Skip to content

Commit e47cf9f

Browse files
committed
Add a new config to set TCP_USER_TIMEOUT
Setting TCP keepalive is not enough to prevent dead TCP connections. See https://blog.cloudflare.com/when-tcp-sockets-refuse-to-die/
1 parent fcb8565 commit e47cf9f

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/client/legacy/connect/http.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ struct Config {
7878
recv_buffer_size: Option<usize>,
7979
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
8080
interface: Option<String>,
81+
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
82+
tcp_user_timeout: Option<Duration>,
8183
}
8284

8385
#[derive(Default, Debug, Clone, Copy)]
@@ -182,6 +184,8 @@ impl<R> HttpConnector<R> {
182184
recv_buffer_size: None,
183185
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
184186
interface: None,
187+
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
188+
tcp_user_timeout: None,
185189
}),
186190
resolver,
187191
}
@@ -324,6 +328,13 @@ impl<R> HttpConnector<R> {
324328
self
325329
}
326330

331+
/// Sets the value of the TCP_USER_TIMEOUT option on the socket.
332+
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
333+
#[inline]
334+
pub fn set_tcp_user_timeout(&mut self, time: Option<Duration>) {
335+
self.config_mut().tcp_user_timeout = time;
336+
}
337+
327338
// private
328339

329340
fn config_mut(&mut self) -> &mut Config {
@@ -728,6 +739,13 @@ fn connect(
728739
.map_err(ConnectError::m("tcp bind interface error"))?;
729740
}
730741

742+
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
743+
if let Some(tcp_user_timeout) = &config.tcp_user_timeout {
744+
if let Err(e) = socket.set_tcp_user_timeout(Some(*tcp_user_timeout)) {
745+
warn!("tcp set_tcp_user_timeout error: {}", e);
746+
}
747+
}
748+
731749
bind_local_address(
732750
&socket,
733751
addr,
@@ -1138,6 +1156,12 @@ mod tests {
11381156
target_os = "linux"
11391157
))]
11401158
interface: None,
1159+
#[cfg(any(
1160+
target_os = "android",
1161+
target_os = "fuchsia",
1162+
target_os = "linux"
1163+
))]
1164+
tcp_user_timeout: None,
11411165
};
11421166
let connecting_tcp = ConnectingTcp::new(dns::SocketAddrs::new(addrs), &cfg);
11431167
let start = Instant::now();

0 commit comments

Comments
 (0)