diff --git a/src/client/legacy/connect/http.rs b/src/client/legacy/connect/http.rs index bcad03f..05a19f4 100644 --- a/src/client/legacy/connect/http.rs +++ b/src/client/legacy/connect/http.rs @@ -78,6 +78,8 @@ struct Config { recv_buffer_size: Option, #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] interface: Option, + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + tcp_user_timeout: Option, } #[derive(Default, Debug, Clone, Copy)] @@ -182,6 +184,8 @@ impl HttpConnector { recv_buffer_size: None, #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] interface: None, + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + tcp_user_timeout: None, }), resolver, } @@ -324,6 +328,13 @@ impl HttpConnector { self } + /// Sets the value of the TCP_USER_TIMEOUT option on the socket. + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + #[inline] + pub fn set_tcp_user_timeout(&mut self, time: Option) { + self.config_mut().tcp_user_timeout = time; + } + // private fn config_mut(&mut self) -> &mut Config { @@ -728,6 +739,13 @@ fn connect( .map_err(ConnectError::m("tcp bind interface error"))?; } + #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))] + if let Some(tcp_user_timeout) = &config.tcp_user_timeout { + if let Err(e) = socket.set_tcp_user_timeout(Some(*tcp_user_timeout)) { + warn!("tcp set_tcp_user_timeout error: {}", e); + } + } + bind_local_address( &socket, addr, @@ -1138,6 +1156,12 @@ mod tests { target_os = "linux" ))] interface: None, + #[cfg(any( + target_os = "android", + target_os = "fuchsia", + target_os = "linux" + ))] + tcp_user_timeout: None, }; let connecting_tcp = ConnectingTcp::new(dns::SocketAddrs::new(addrs), &cfg); let start = Instant::now();