Skip to content

Commit

Permalink
feat(mptcp): MPTCP on Linux try to set keepalive time & interval
Browse files Browse the repository at this point in the history
- TCP_KEEPIDLE, TCP_KEEPINTV may be supported in the future kernel
- multipath-tcp/mptcp_net-next#383
- ref #1156
  • Loading branch information
zonyitoo committed Apr 15, 2023
1 parent 8be8047 commit c1f505f
Showing 1 changed file with 28 additions and 26 deletions.
54 changes: 28 additions & 26 deletions crates/shadowsocks/src/net/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,36 +61,38 @@ pub async fn create_inbound_udp_socket(addr: &SocketAddr, ipv6_only: bool) -> io

#[inline]
fn set_tcp_keepalive(socket: &Socket, tcp: &TcpSocketOpts) -> io::Result<()> {
cfg_if! {
if #[cfg(any(target_os = "linux", target_os = "android"))] {
// FIXME: Linux Kernel doesn't support setting TCP Keep Alive.
// SO_KEEPALIVE works fine. But TCP_KEEPIDLE, TCP_KEEPINTV are not supported.
let support_tcp_keepalive_intv = !tcp.mptcp;
} else {
let support_tcp_keepalive_intv = true;
}
}

if let Some(intv) = tcp.keepalive {
#[allow(unused_mut)]
let mut keepalive = TcpKeepalive::new();

if support_tcp_keepalive_intv {
keepalive = keepalive.with_time(intv);

#[cfg(any(
target_os = "freebsd",
target_os = "fuchsia",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
{
keepalive = keepalive.with_interval(intv);
}
let mut keepalive = TcpKeepalive::new().with_time(intv);

#[cfg(any(
target_os = "freebsd",
target_os = "fuchsia",
target_os = "linux",
target_os = "netbsd",
target_vendor = "apple",
))]
{
keepalive = keepalive.with_interval(intv);
}

socket.set_tcp_keepalive(&keepalive)?;
cfg_if! {
if #[cfg(any(target_os = "linux", target_os = "android"))] {
// FIXME: Linux Kernel doesn't support setting TCP Keep Alive. (MPTCP)
// SO_KEEPALIVE works fine. But TCP_KEEPIDLE, TCP_KEEPINTV are not supported.
// https://github.com/multipath-tcp/mptcp_net-next/issues/383
// https://github.com/multipath-tcp/mptcp_net-next/issues/353
if let Err(err) = socket.set_tcp_keepalive(&keepalive) {
log::debug!("set TCP keep-alive with time & interval failed with error: {:?}", err);

// Try again without time & interval
let keepalive = TcpKeepalive::new();
socket.set_tcp_keepalive(&keepalive)?;
}
} else {
socket.set_tcp_keepalive(&keepalive)?;
}
}
}

Ok(())
Expand Down

0 comments on commit c1f505f

Please sign in to comment.