From b0732a37894fba934b2688686b4d6b22c38d5cc4 Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 28 Jul 2021 01:24:05 +0300 Subject: [PATCH] Fix TCP keepalive handling on Haiku and OpenBSD On Haiku and OpenBSD don't call `setsockopt(fd, IPPROTO_TCP, SO_KEEPALIVE, secs)`, it is incorrect because `SO_KEEPALIVE` belongs to `SOL_SOCKET` layer, because it accepts a boolean instead of the number of seconds, and because there is no way to set keepalive idle time per socket on these operating systems. On Haiku and OpenBSD it is only possible to enable and disable keepalives, and it is already done with `setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, 1)` in a portable way in `Socket.set_keepalive()` defined in `src/socket.rs`. --- src/lib.rs | 9 +++++---- src/sys/unix.rs | 5 ++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8ff72d4a..6ea3cc22 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -340,10 +340,11 @@ impl TcpKeepalive { /// Set the amount of time after which TCP keepalive probes will be sent on /// idle connections. /// - /// This will set the value of `SO_KEEPALIVE` on OpenBSD and Haiku, - /// `TCP_KEEPALIVE` on macOS and iOS, and `TCP_KEEPIDLE` on all other Unix - /// operating systems. On Windows, this sets the value of the - /// `tcp_keepalive` struct's `keepalivetime` field. + /// This will set `TCP_KEEPALIVE` on macOS and iOS, and + /// `TCP_KEEPIDLE` on all other Unix operating systems, except + /// OpenBSD and Haiku which don't support any way to set this + /// option. On Windows, this sets the value of the `tcp_keepalive` + /// struct's `keepalivetime` field. /// /// Some platforms specify this value in seconds, so sub-second /// specifications may be omitted. diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 4e997848..fa34066c 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -135,11 +135,9 @@ pub(crate) use libc::{TCP_KEEPCNT, TCP_KEEPINTVL}; // See this type in the Windows file. pub(crate) type Bool = c_int; -#[cfg(any(target_os = "openbsd", target_os = "haiku"))] -use libc::SO_KEEPALIVE as KEEPALIVE_TIME; #[cfg(target_vendor = "apple")] use libc::TCP_KEEPALIVE as KEEPALIVE_TIME; -#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_vendor = "apple")))] +#[cfg(not(any(target_vendor = "apple")))] use libc::TCP_KEEPIDLE as KEEPALIVE_TIME; /// Helper macro to execute a system call that returns an `io::Result`. @@ -876,6 +874,7 @@ pub(crate) fn keepalive_time(fd: Socket) -> io::Result { } pub(crate) fn set_tcp_keepalive(fd: Socket, keepalive: &TcpKeepalive) -> io::Result<()> { + #[cfg(not(any(target_os = "haiku", target_os = "openbsd")))] if let Some(time) = keepalive.time { let secs = into_secs(time); unsafe { setsockopt(fd, libc::IPPROTO_TCP, KEEPALIVE_TIME, secs)? }