blob: d1cc39298c7af07e0be71c46024ce41b4e4e0149 [file]
use std::num::TryFromIntError;
use tokio::net::TcpSocket;
use crate::configs::tcp::TcpSocketConfig;
pub fn build(ipv6: bool, config: TcpSocketConfig) -> TcpSocket {
let socket = if ipv6 {
TcpSocket::new_v6().expect("Unable to create an ipv6 socket")
} else {
TcpSocket::new_v4().expect("Unable to create an ipv4 socket")
};
if config.override_defaults {
config
.recv_buffer_size
.as_bytes_u64()
.try_into()
.map_err(|e: TryFromIntError| std::io::Error::other(e.to_string()))
.and_then(|size: u32| socket.set_recv_buffer_size(size))
.expect("Unable to set SO_RCVBUF on socket");
config
.send_buffer_size
.as_bytes_u64()
.try_into()
.map_err(|e: TryFromIntError| std::io::Error::other(e.to_string()))
.and_then(|size| socket.set_send_buffer_size(size))
.expect("Unable to set SO_SNDBUF on socket");
socket
.set_keepalive(config.keepalive)
.expect("Unable to set SO_KEEPALIVE on socket");
socket
.set_nodelay(config.nodelay)
.expect("Unable to set TCP_NODELAY on socket");
socket
.set_linger(Some(config.linger.get_duration()))
.expect("Unable to set SO_LINGER on socket");
}
socket
}
#[cfg(test)]
mod tests {
use std::time::Duration;
use iggy::utils::{byte_size::IggyByteSize, duration::IggyDuration};
use super::*;
#[test]
fn given_override_defaults_socket_should_be_configured() {
let buffer_size = 425984;
let linger_dur = Duration::new(1, 0);
let config = TcpSocketConfig {
override_defaults: true,
recv_buffer_size: IggyByteSize::from(buffer_size),
send_buffer_size: IggyByteSize::from(buffer_size),
keepalive: true,
nodelay: true,
linger: IggyDuration::new(linger_dur),
};
let socket = build(false, config);
assert!(socket.recv_buffer_size().unwrap() >= buffer_size as u32);
assert!(socket.send_buffer_size().unwrap() >= buffer_size as u32);
assert!(socket.keepalive().unwrap());
assert!(socket.nodelay().unwrap());
assert_eq!(socket.linger().unwrap(), Some(linger_dur));
}
}