Skip to content

Commit 6d92bd0

Browse files
committed
allow customizing keep-alive seconds on TCP sockets
- ref #490
1 parent f1d312f commit 6d92bd0

File tree

16 files changed

+105
-133
lines changed

16 files changed

+105
-133
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,9 @@ Example configuration:
458458
// TCP_NODELAY
459459
"no_delay": false,
460460

461+
// Enables `SO_KEEPALIVE` and set `TCP_KEEPIDLE`, `TCP_KEEPINTVL` to the specified seconds
462+
"keep_alive": 15,
463+
461464
// Soft and Hard limit of file descriptors on *NIX systems
462465
"nofile": 10240,
463466

crates/shadowsocks-service/src/config.rs

+16
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ struct SSConfig {
123123
mode: Option<String>,
124124
#[serde(skip_serializing_if = "Option::is_none")]
125125
no_delay: Option<bool>,
126+
#[serde(skip_serializing_if = "Option::is_none")]
127+
keep_alive: Option<u64>,
126128
#[cfg(all(unix, not(target_os = "android")))]
127129
#[serde(skip_serializing_if = "Option::is_none")]
128130
nofile: Option<u64>,
@@ -769,6 +771,9 @@ pub struct Config {
769771
pub no_delay: bool,
770772
/// Set `TCP_FASTOPEN` socket option
771773
pub fast_open: bool,
774+
/// Set TCP Keep-Alive duration, will set both `TCP_KEEPIDLE` and `TCP_KEEPINTVL`
775+
pub keep_alive: Option<Duration>,
776+
772777
/// `RLIMIT_NOFILE` option for *nix systems
773778
#[cfg(all(unix, not(target_os = "android")))]
774779
pub nofile: Option<u64>,
@@ -883,6 +888,8 @@ impl Config {
883888

884889
no_delay: false,
885890
fast_open: false,
891+
keep_alive: None,
892+
886893
#[cfg(all(unix, not(target_os = "android")))]
887894
nofile: None,
888895

@@ -1374,6 +1381,11 @@ impl Config {
13741381
nconfig.fast_open = b;
13751382
}
13761383

1384+
// TCP Keep-Alive
1385+
if let Some(d) = config.keep_alive {
1386+
nconfig.keep_alive = Some(Duration::from_secs(d));
1387+
}
1388+
13771389
// UDP
13781390
nconfig.udp_timeout = config.udp_timeout.map(Duration::from_secs);
13791391

@@ -1864,6 +1876,10 @@ impl fmt::Display for Config {
18641876
jconf.fast_open = Some(self.fast_open);
18651877
}
18661878

1879+
if let Some(keepalive) = self.keep_alive {
1880+
jconf.keep_alive = Some(keepalive.as_secs());
1881+
}
1882+
18671883
match self.dns {
18681884
DnsConfig::System => {}
18691885
#[cfg(feature = "trust-dns")]

crates/shadowsocks-service/src/local/mod.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,17 @@ pub async fn run(mut config: Config) -> io::Result<()> {
8282
};
8383
connect_opts.tcp.send_buffer_size = config.outbound_send_buffer_size;
8484
connect_opts.tcp.recv_buffer_size = config.outbound_recv_buffer_size;
85+
connect_opts.tcp.nodelay = config.no_delay;
8586
connect_opts.tcp.fastopen = config.fast_open;
87+
connect_opts.tcp.keepalive = config.keep_alive;
8688
context.set_connect_opts(connect_opts);
8789

8890
let mut accept_opts = AcceptOpts::default();
8991
accept_opts.tcp.send_buffer_size = config.inbound_send_buffer_size;
9092
accept_opts.tcp.recv_buffer_size = config.inbound_recv_buffer_size;
9193
accept_opts.tcp.nodelay = config.no_delay;
9294
accept_opts.tcp.fastopen = config.fast_open;
95+
accept_opts.tcp.keepalive = config.keep_alive;
9396

9497
if let Some(resolver) = build_dns_resolver(config.dns, config.ipv6_first, context.connect_opts_ref()).await {
9598
context.set_dns_resolver(Arc::new(resolver));
@@ -215,9 +218,6 @@ pub async fn run(mut config: Config) -> io::Result<()> {
215218
if let Some(b) = local_config.udp_addr {
216219
server.set_udp_bind_addr(b.clone());
217220
}
218-
if config.no_delay {
219-
server.set_nodelay(true);
220-
}
221221

222222
vfut.push(async move { server.run(&client_addr, balancer).await }.boxed());
223223
}
@@ -236,9 +236,6 @@ pub async fn run(mut config: Config) -> io::Result<()> {
236236
server.set_udp_expiry_duration(d);
237237
}
238238
server.set_mode(local_config.mode);
239-
if config.no_delay {
240-
server.set_nodelay(true);
241-
}
242239

243240
let udp_addr = local_config.udp_addr.unwrap_or_else(|| client_addr.clone());
244241
vfut.push(async move { server.run(&client_addr, &udp_addr, balancer).await }.boxed());
@@ -262,9 +259,6 @@ pub async fn run(mut config: Config) -> io::Result<()> {
262259
server.set_udp_expiry_duration(d);
263260
}
264261
server.set_mode(local_config.mode);
265-
if config.no_delay {
266-
server.set_nodelay(true);
267-
}
268262
server.set_tcp_redir(local_config.tcp_redir);
269263
server.set_udp_redir(local_config.udp_redir);
270264

crates/shadowsocks-service/src/local/redir/server.rs

+1-15
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ pub struct Redir {
1818
mode: Mode,
1919
udp_expiry_duration: Option<Duration>,
2020
udp_capacity: Option<usize>,
21-
nodelay: bool,
2221
tcp_redir: RedirType,
2322
udp_redir: RedirType,
2423
}
@@ -43,7 +42,6 @@ impl Redir {
4342
mode: Mode::TcpOnly,
4443
udp_expiry_duration: None,
4544
udp_capacity: None,
46-
nodelay: false,
4745
tcp_redir: RedirType::tcp_default(),
4846
udp_redir: RedirType::udp_default(),
4947
}
@@ -64,11 +62,6 @@ impl Redir {
6462
self.mode = mode;
6563
}
6664

67-
/// Set `TCP_NODELAY`
68-
pub fn set_nodelay(&mut self, nodelay: bool) {
69-
self.nodelay = nodelay;
70-
}
71-
7265
/// Set transparent proxy type of TCP relay, which is platform dependent
7366
pub fn set_tcp_redir(&mut self, ty: RedirType) {
7467
self.tcp_redir = ty;
@@ -96,14 +89,7 @@ impl Redir {
9689
}
9790

9891
async fn run_tcp_tunnel(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
99-
run_tcp_redir(
100-
self.context.clone(),
101-
client_config,
102-
balancer,
103-
self.tcp_redir,
104-
self.nodelay,
105-
)
106-
.await
92+
run_tcp_redir(self.context.clone(), client_config, balancer, self.tcp_redir).await
10793
}
10894

10995
async fn run_udp_tunnel(&self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {

crates/shadowsocks-service/src/local/redir/tcprelay/mod.rs

+2-21
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,12 @@ async fn establish_client_tcp_redir<'a>(
3939
mut stream: TcpStream,
4040
peer_addr: SocketAddr,
4141
addr: &Address,
42-
nodelay: bool,
4342
) -> io::Result<()> {
4443
let server = balancer.best_tcp_server();
4544
let svr_cfg = server.server_config();
4645

4746
let mut remote = AutoProxyClientStream::connect(context, &server, addr).await?;
4847

49-
if nodelay {
50-
remote.set_nodelay(true)?;
51-
}
52-
5348
establish_tcp_tunnel(svr_cfg, &mut stream, &mut remote, peer_addr, addr).await
5449
}
5550

@@ -59,20 +54,7 @@ async fn handle_redir_client(
5954
s: TcpStream,
6055
peer_addr: SocketAddr,
6156
mut daddr: SocketAddr,
62-
nodelay: bool,
6357
) -> io::Result<()> {
64-
// let svr_cfg = server.server_config();
65-
//
66-
// if let Err(err) = s.set_keepalive(svr_cfg.timeout()) {
67-
// error!("failed to set keep alive: {:?}", err);
68-
// }
69-
70-
if nodelay {
71-
if let Err(err) = s.set_nodelay(true) {
72-
error!("failed to set TCP_NODELAY on accepted socket, error: {:?}", err);
73-
}
74-
}
75-
7658
// Get forward address from socket
7759
//
7860
// Try to convert IPv4 mapped IPv6 address for dual-stack mode.
@@ -82,15 +64,14 @@ async fn handle_redir_client(
8264
}
8365
}
8466
let target_addr = Address::from(daddr);
85-
establish_client_tcp_redir(context, balancer, s, peer_addr, &target_addr, nodelay).await
67+
establish_client_tcp_redir(context, balancer, s, peer_addr, &target_addr).await
8668
}
8769

8870
pub async fn run_tcp_redir(
8971
context: Arc<ServiceContext>,
9072
client_config: &ServerAddr,
9173
balancer: PingBalancer,
9274
redir_ty: RedirType,
93-
nodelay: bool,
9475
) -> io::Result<()> {
9576
let listener = match *client_config {
9677
ServerAddr::SocketAddr(ref saddr) => TcpListener::bind_redir(redir_ty, *saddr).await?,
@@ -137,7 +118,7 @@ pub async fn run_tcp_redir(
137118
}
138119
};
139120

140-
if let Err(err) = handle_redir_client(context, balancer, socket, peer_addr, dst_addr, nodelay).await {
121+
if let Err(err) = handle_redir_client(context, balancer, socket, peer_addr, dst_addr).await {
141122
debug!("TCP redirect client, error: {:?}", err);
142123
}
143124
});

crates/shadowsocks-service/src/local/socks/server/mod.rs

+3-18
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ pub struct Socks {
2424
udp_expiry_duration: Option<Duration>,
2525
udp_capacity: Option<usize>,
2626
udp_bind_addr: Option<ServerAddr>,
27-
nodelay: bool,
2827
}
2928

3029
impl Default for Socks {
@@ -48,7 +47,6 @@ impl Socks {
4847
udp_expiry_duration: None,
4948
udp_capacity: None,
5049
udp_bind_addr: None,
51-
nodelay: false,
5250
}
5351
}
5452

@@ -75,11 +73,6 @@ impl Socks {
7573
self.udp_bind_addr = Some(a);
7674
}
7775

78-
/// Set `TCP_NODELAY`
79-
pub fn set_nodelay(&mut self, nodelay: bool) {
80-
self.nodelay = nodelay;
81-
}
82-
8376
/// Start serving
8477
pub async fn run(self, client_config: &ServerAddr, balancer: PingBalancer) -> io::Result<()> {
8578
let mut vfut = Vec::new();
@@ -133,13 +126,8 @@ impl Socks {
133126
}
134127
};
135128

136-
if self.nodelay {
137-
let _ = stream.set_nodelay(true);
138-
}
139-
140129
let balancer = balancer.clone();
141130
let context = self.context.clone();
142-
let nodelay = self.nodelay;
143131
let udp_bind_addr = udp_bind_addr.clone();
144132
let mode = self.mode;
145133

@@ -150,7 +138,6 @@ impl Socks {
150138
balancer,
151139
peer_addr,
152140
mode,
153-
nodelay,
154141
));
155142
}
156143
}
@@ -163,7 +150,6 @@ impl Socks {
163150
balancer: PingBalancer,
164151
peer_addr: SocketAddr,
165152
mode: Mode,
166-
nodelay: bool,
167153
) -> io::Result<()> {
168154
use std::io::ErrorKind;
169155

@@ -175,12 +161,12 @@ impl Socks {
175161

176162
match version_buffer[0] {
177163
0x04 => {
178-
let handler = Socks4TcpHandler::new(context, nodelay, balancer, mode);
164+
let handler = Socks4TcpHandler::new(context, balancer, mode);
179165
handler.handle_socks4_client(stream, peer_addr).await
180166
}
181167

182168
0x05 => {
183-
let handler = Socks5TcpHandler::new(context, udp_bind_addr, nodelay, balancer, mode);
169+
let handler = Socks5TcpHandler::new(context, udp_bind_addr, balancer, mode);
184170
handler.handle_socks5_client(stream, peer_addr).await
185171
}
186172

@@ -200,9 +186,8 @@ impl Socks {
200186
balancer: PingBalancer,
201187
peer_addr: SocketAddr,
202188
mode: Mode,
203-
nodelay: bool,
204189
) -> io::Result<()> {
205-
let handler = Socks5TcpHandler::new(context, udp_bind_addr, nodelay, balancer, mode);
190+
let handler = Socks5TcpHandler::new(context, udp_bind_addr, balancer, mode);
206191
handler.handle_socks5_client(stream, peer_addr).await
207192
}
208193

crates/shadowsocks-service/src/local/socks/server/socks4/tcprelay.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,14 @@ use crate::local::socks::socks4::{Address, Command, HandshakeRequest, HandshakeR
2424

2525
pub struct Socks4TcpHandler {
2626
context: Arc<ServiceContext>,
27-
nodelay: bool,
2827
balancer: PingBalancer,
2928
mode: Mode,
3029
}
3130

3231
impl Socks4TcpHandler {
33-
pub fn new(context: Arc<ServiceContext>, nodelay: bool, balancer: PingBalancer, mode: Mode) -> Socks4TcpHandler {
32+
pub fn new(context: Arc<ServiceContext>, balancer: PingBalancer, mode: Mode) -> Socks4TcpHandler {
3433
Socks4TcpHandler {
3534
context,
36-
nodelay,
3735
balancer,
3836
mode,
3937
}
@@ -108,10 +106,6 @@ impl Socks4TcpHandler {
108106
}
109107
};
110108

111-
if self.nodelay {
112-
remote.set_nodelay(true)?;
113-
}
114-
115109
// NOTE: Transfer all buffered data before unwrap, or these data will be lost
116110
let buffer = stream.buffer();
117111
if !buffer.is_empty() {

crates/shadowsocks-service/src/local/socks/server/socks5/tcprelay.rs

-7
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ use crate::{
3636
pub struct Socks5TcpHandler {
3737
context: Arc<ServiceContext>,
3838
udp_bind_addr: Option<Arc<ServerAddr>>,
39-
nodelay: bool,
4039
balancer: PingBalancer,
4140
mode: Mode,
4241
}
@@ -45,14 +44,12 @@ impl Socks5TcpHandler {
4544
pub fn new(
4645
context: Arc<ServiceContext>,
4746
udp_bind_addr: Option<Arc<ServerAddr>>,
48-
nodelay: bool,
4947
balancer: PingBalancer,
5048
mode: Mode,
5149
) -> Socks5TcpHandler {
5250
Socks5TcpHandler {
5351
context,
5452
udp_bind_addr,
55-
nodelay,
5653
balancer,
5754
mode,
5855
}
@@ -163,10 +160,6 @@ impl Socks5TcpHandler {
163160
}
164161
};
165162

166-
if self.nodelay {
167-
remote.set_nodelay(true)?;
168-
}
169-
170163
establish_tcp_tunnel(svr_cfg, &mut stream, &mut remote, peer_addr, &target_addr).await
171164
}
172165

0 commit comments

Comments
 (0)