Open ustulation opened 5 years ago
libc
crate. I've done some prototyping:
/// Set TCP keep alive options for a given socket, if configured.
pub fn set_keep_alive(stream: &TcpStream, conf: &SocketConfig) -> io::Result<()> {
if let Some((idle, interval, count)) = conf.keep_alive {
stream.set_keepalive(Some(Duration::from_secs(u64::from(idle))))?;
let fd = stream.as_raw_fd();
set_ip_opt(fd, libc::TCP_KEEPINTVL, interval)?;
set_ip_opt(fd, libc::TCP_KEEPCNT, count)?;
}
Ok(())
}
/// Sets IP level option for a given socketlevel option for a given socket fn set_ip_opt(sock_fd: RawFd, opt: libc::c_int, val: u32) -> io::Result<()> { unsafe { let optval: libc::c_int = val as libc::c_int; let ret = libc::setsockopt( sock_fd, libc::IPPROTOTCP, opt, &optval as *const as *const libc::c_void, mem::size_of_val(&optval) as libc::socklen_t, ); if ret != 0 { Err(io::Error::last_os_error()) } else { Ok(()) } } }
That could also be done with the `nix` crate which provides a higher level API once https://github.com/nix-rust/nix/pull/889 gets merged.
Windows does not support the TCP_KEEPINTVL
and TCP_KEEPCNT
options. But there's an alternative API:
SO_KEEPALIVE
for socket: https://docs.microsoft.com/en-us/windows/desktop/WinSock/so-keepaliveSee example: http://read.pudn.com/downloads79/ebook/301417/Chapter09/SIO_KEEPALIVE_VALS/alive.c__.htm
It's weird, on Mac OS seems like TCP_KEEPINTVL
and CNT
are documented: https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/man/man4/tcp.4#L190, but when trying to use from code, it says the symbols are not found. Or maybe that's just libc wrappers... Should also see what the constants are and try to use them directly.
We won't be using TCP keepalive functionality any time soon. Now, it's obvious that it's configuration differs on each platform and it only works with TCP, but socket-collection also supports UDP based protocols. So are postponing this research to the future.
Ideally we would want to not have app level
heartbeat
if protocol levelkeepalives
are sufficient. However the API for it is not very flexible at this time inmio
and allows to set the duration after which the 1stkeepalive
should be sent when the socket is idling, but not how much interval needs to elapse before we decide to sever the connection or how manykeepalives
we send after the firstkeepalive
. Depending on the duration ofkeepalive-interval
(the 1stkeepalive
that is sent) other parameters seem to be fixed to reasonable defaults as noted here.