Enable TCP keep alive on RTR sockets if configured.
@@ -134,9 +134,12 @@ impl RtrStream {
fn new(
sock: TcpStream,
tls: Option<&TlsAcceptor>,
- _keepalive: Option<Duration>,
+ keepalive: Option<Duration>,
server_metrics: SharedRtrServerMetrics,
) -> Result<Self, io::Error> {
+ if let Some(duration) = keepalive {
+ Self::set_keepalive(&sock, duration)?
+ }
let metrics = Arc::new(RtrClientMetrics::new(sock.local_addr()?.ip()));
let client_metrics = metrics.clone();
tokio::spawn(async move {
@@ -147,6 +150,32 @@ impl RtrStream {
metrics
})
}
+
+ #[cfg(unix)]
+ fn set_keepalive(
+ sock: &TcpStream, duration: Duration
+ ) -> Result<(), io::Error>{
+ use std::convert::TryFrom;
+ use std::os::unix::io::AsRawFd;
+ use nix::sys::socket::{setsockopt, sockopt};
+
+ (|fd, duration: Duration| {
+ setsockopt(
+ fd, sockopt::TcpKeepInterval,
+ &u32::try_from(duration.as_secs()).unwrap_or(u32::MAX)
+ )?;
+ setsockopt(fd, sockopt::KeepAlive, &true)
+ })(sock.as_raw_fd(), duration).map_err(|err| {
+ io::Error::new(io::ErrorKind::Other, err)
+ })
+ }
+
+ #[cfg(not(unix))]
+ fn set_keepalive(
+ _sock: &TcpStream, _duration: Duration
+ ) -> Result<(), io::Error>{
+ Ok(())
+ }
}
impl Socket for RtrStream {
