From 24c231ca463a17f51e53e7a554c7915a95bdbcc7 Mon Sep 17 00:00:00 2001 From: eddi Date: Tue, 18 Jan 2022 22:11:27 +0100 Subject: [PATCH] Add support for the socket option TCP_THIN_LINEAR_TIMEOUTS --- src/sys/unix.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/socket.rs | 5 +++++ 2 files changed, 59 insertions(+) diff --git a/src/sys/unix.rs b/src/sys/unix.rs index 2e084980..44bfefcc 100644 --- a/src/sys/unix.rs +++ b/src/sys/unix.rs @@ -1385,6 +1385,60 @@ impl crate::Socket { } } + /// Get the value of the `TCP_THIN_LINEAR_TIMEOUTS` option on this socket. + /// + /// For more information about this option, see [`set_thin_linear_timeouts`]. + /// + /// [`set_thin_linear_timeouts`]: Socket::set_thin_linear_timeouts + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ))) + )] + pub fn thin_linear_timeouts(&self) -> io::Result { + unsafe { + getsockopt::( + self.as_raw(), + libc::IPPROTO_TCP, + libc::TCP_THIN_LINEAR_TIMEOUTS, + ) + .map(|timeouts| timeouts != 0) + } + } + + /// Set the value of the `TCP_THIN_LINEAR_TIMEOUTS` option on this socket. + /// + /// If set, the kernel will dynamically detect a thin-stream connection if there are less than four packets in flight. + /// With less than four packets in flight the normal TCP fast retransmission will not be effective. + /// The kernel will modify the retransmission to avoid the very high latencies that thin stream suffer because of exponential backoff. + #[cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ))] + #[cfg_attr( + docsrs, + doc(cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") + ))) + )] + pub fn set_thin_linear_timeouts(&self, timeouts: bool) -> io::Result<()> { + unsafe { + setsockopt( + self.as_raw(), + libc::IPPROTO_TCP, + libc::TCP_THIN_LINEAR_TIMEOUTS, + timeouts as c_int, + ) + } + } + /// Gets the value for the `SO_BINDTODEVICE` option on this socket. /// /// This value gets the socket binded device's interface name. diff --git a/tests/socket.rs b/tests/socket.rs index 4d8838c0..728f1681 100644 --- a/tests/socket.rs +++ b/tests/socket.rs @@ -1147,6 +1147,11 @@ test!(cork, set_cork(true)); any(target_os = "android", target_os = "fuchsia", target_os = "linux") ))] test!(quickack, set_quickack(false)); +#[cfg(all( + feature = "all", + any(target_os = "android", target_os = "fuchsia", target_os = "linux") +))] +test!(thin_linear_timeouts, set_thin_linear_timeouts(true)); test!(linger, set_linger(Some(Duration::from_secs(10)))); test!( read_timeout,