From 9590ffe6f5fd62e38ad441f2059606934ca87ad2 Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Sun, 6 Jun 2021 01:42:41 +0800 Subject: [PATCH] all tcp sockets will set with default Keep Alive timeout 15s - fixes #546 - ref #490 --- crates/shadowsocks-service/src/config.rs | 4 ++++ crates/shadowsocks-service/src/local/mod.rs | 9 +++++++-- crates/shadowsocks-service/src/manager/mod.rs | 5 +++-- crates/shadowsocks-service/src/server/mod.rs | 11 ++++++++--- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/crates/shadowsocks-service/src/config.rs b/crates/shadowsocks-service/src/config.rs index 6af9b966c39b..62552ca84677 100644 --- a/crates/shadowsocks-service/src/config.rs +++ b/crates/shadowsocks-service/src/config.rs @@ -772,6 +772,10 @@ pub struct Config { /// Set `TCP_FASTOPEN` socket option pub fast_open: bool, /// Set TCP Keep-Alive duration, will set both `TCP_KEEPIDLE` and `TCP_KEEPINTVL` + /// + /// https://github.com/shadowsocks/shadowsocks-rust/issues/546 + /// + /// If this is not set, sockets will be set with a default timeout pub keep_alive: Option, /// `RLIMIT_NOFILE` option for *nix systems diff --git a/crates/shadowsocks-service/src/local/mod.rs b/crates/shadowsocks-service/src/local/mod.rs index 901de7a8c63b..f622481dbaf0 100644 --- a/crates/shadowsocks-service/src/local/mod.rs +++ b/crates/shadowsocks-service/src/local/mod.rs @@ -42,6 +42,11 @@ pub mod socks; pub mod tunnel; pub mod utils; +/// Default TCP Keep Alive timeout +/// +/// This is borrowed from Go's `net` library's default setting +pub(crate) const LOCAL_DEFAULT_KEEPALIVE_TIMEOUT: Duration = Duration::from_secs(15); + /// Starts a shadowsocks local server pub async fn run(mut config: Config) -> io::Result<()> { assert!(config.config_type == ConfigType::Local && !config.local.is_empty()); @@ -84,7 +89,7 @@ pub async fn run(mut config: Config) -> io::Result<()> { connect_opts.tcp.recv_buffer_size = config.outbound_recv_buffer_size; connect_opts.tcp.nodelay = config.no_delay; connect_opts.tcp.fastopen = config.fast_open; - connect_opts.tcp.keepalive = config.keep_alive; + connect_opts.tcp.keepalive = config.keep_alive.or(Some(LOCAL_DEFAULT_KEEPALIVE_TIMEOUT)); context.set_connect_opts(connect_opts); let mut accept_opts = AcceptOpts::default(); @@ -92,7 +97,7 @@ pub async fn run(mut config: Config) -> io::Result<()> { accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size; accept_opts.tcp.nodelay = config.no_delay; accept_opts.tcp.fastopen = config.fast_open; - accept_opts.tcp.keepalive = config.keep_alive; + accept_opts.tcp.keepalive = config.keep_alive.or(Some(LOCAL_DEFAULT_KEEPALIVE_TIMEOUT)); if let Some(resolver) = build_dns_resolver(config.dns, config.ipv6_first, context.connect_opts_ref()).await { context.set_dns_resolver(Arc::new(resolver)); diff --git a/crates/shadowsocks-service/src/manager/mod.rs b/crates/shadowsocks-service/src/manager/mod.rs index faddc32f632c..566f3afb85c9 100644 --- a/crates/shadowsocks-service/src/manager/mod.rs +++ b/crates/shadowsocks-service/src/manager/mod.rs @@ -10,6 +10,7 @@ use shadowsocks::net::{AcceptOpts, ConnectOpts}; use crate::{ config::{Config, ConfigType}, dns::build_dns_resolver, + server::SERVER_DEFAULT_KEEPALIVE_TIMEOUT, }; pub use self::server::Manager; @@ -51,14 +52,14 @@ pub async fn run(config: Config) -> io::Result<()> { connect_opts.tcp.recv_buffer_size = config.outbound_recv_buffer_size; connect_opts.tcp.nodelay = config.no_delay; connect_opts.tcp.fastopen = config.fast_open; - connect_opts.tcp.keepalive = config.keep_alive; + connect_opts.tcp.keepalive = config.keep_alive.or(Some(SERVER_DEFAULT_KEEPALIVE_TIMEOUT)); let mut accept_opts = AcceptOpts::default(); accept_opts.tcp.send_buffer_size = config.inbound_send_buffer_size; accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size; accept_opts.tcp.nodelay = config.no_delay; accept_opts.tcp.fastopen = config.fast_open; - accept_opts.tcp.keepalive = config.keep_alive; + accept_opts.tcp.keepalive = config.keep_alive.or(Some(SERVER_DEFAULT_KEEPALIVE_TIMEOUT)); if let Some(resolver) = build_dns_resolver(config.dns, config.ipv6_first, &connect_opts).await { manager.set_dns_resolver(Arc::new(resolver)); diff --git a/crates/shadowsocks-service/src/server/mod.rs b/crates/shadowsocks-service/src/server/mod.rs index 9f93921db777..a2ba22a32bfb 100644 --- a/crates/shadowsocks-service/src/server/mod.rs +++ b/crates/shadowsocks-service/src/server/mod.rs @@ -1,6 +1,6 @@ //! Shadowsocks server -use std::{io, sync::Arc}; +use std::{io, sync::Arc, time::Duration}; use futures::{future, FutureExt}; use log::trace; @@ -19,6 +19,11 @@ pub mod server; mod tcprelay; mod udprelay; +/// Default TCP Keep Alive timeout +/// +/// This is borrowed from Go's `net` library's default setting +pub(crate) const SERVER_DEFAULT_KEEPALIVE_TIMEOUT: Duration = Duration::from_secs(15); + /// Starts a shadowsocks server pub async fn run(config: Config) -> io::Result<()> { assert_eq!(config.config_type, ConfigType::Server); @@ -64,14 +69,14 @@ pub async fn run(config: Config) -> io::Result<()> { connect_opts.tcp.recv_buffer_size = config.outbound_recv_buffer_size; connect_opts.tcp.nodelay = config.no_delay; connect_opts.tcp.fastopen = config.fast_open; - connect_opts.tcp.keepalive = config.keep_alive; + connect_opts.tcp.keepalive = config.keep_alive.or(Some(SERVER_DEFAULT_KEEPALIVE_TIMEOUT)); let mut accept_opts = AcceptOpts::default(); accept_opts.tcp.send_buffer_size = config.inbound_send_buffer_size; accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size; accept_opts.tcp.nodelay = config.no_delay; accept_opts.tcp.fastopen = config.fast_open; - accept_opts.tcp.keepalive = config.keep_alive; + accept_opts.tcp.keepalive = config.keep_alive.or(Some(SERVER_DEFAULT_KEEPALIVE_TIMEOUT)); let resolver = build_dns_resolver(config.dns, config.ipv6_first, &connect_opts) .await