Browse Source

Add option '--long-idle' for server

Restore the default behavior handling timeout, make an option to enable
long idle connections.

Previously discussion:

https://github.com/shadowsocks/shadowsocks-libev/pull/2421

https://github.com/shadowsocks/shadowsocks-libev/issues/2427
pull/2463/head
lixingcong 5 years ago
parent
commit
b4cda9dd42
7 changed files with 32 additions and 5 deletions
  1. 2
      README.md
  2. 2
      completions/bash/ss-server
  3. 1
      completions/zsh/_ss-server
  4. 4
      doc/ss-server.asciidoc
  5. 1
      src/common.h
  6. 23
      src/server.c
  7. 4
      src/utils.c

2
README.md

@ -446,6 +446,8 @@ you may refer to the man pages of the applications, respectively.
[--no-delay] Enable TCP_NODELAY. [--no-delay] Enable TCP_NODELAY.
[--long-idle] Enable TCP long idle connections.
[--executable <path>] Path to the executable of ss-server. [--executable <path>] Path to the executable of ss-server.
(only available in manager mode) (only available in manager mode)

2
completions/bash/ss-server

@ -1,7 +1,7 @@
_ss_server() _ss_server()
{ {
local cur prev opts ciphers local cur prev opts ciphers
opts='-s -p -l -k -m -a -f -t -c -n -i -b -u -U -6 -d -v -h --reuse-port --fast-open --acl --manager-address --mtu --mptcp --no-delay --key --plugin --plugin-opts --help'
opts='-s -p -l -k -m -a -f -t -c -n -i -b -u -U -6 -d -v -h --reuse-port --fast-open --acl --manager-address --mtu --mptcp --no-delay --long-idle --key --plugin --plugin-opts --help'
ciphers='rc4-md5 aes-128-gcm aes-192-gcm aes-256-gcm aes-128-cfb aes-192-cfb aes-256-cfb aes-128-ctr aes-192-ctr aes-256-ctr camellia-128-cfb camellia-192-cfb camellia-256-cfb bf-cfb chacha20-ietf-poly1305 salsa20 chacha20 chacha20-ietf' ciphers='rc4-md5 aes-128-gcm aes-192-gcm aes-256-gcm aes-128-cfb aes-192-cfb aes-256-cfb aes-128-ctr aes-192-ctr aes-256-ctr camellia-128-cfb camellia-192-cfb camellia-256-cfb bf-cfb chacha20-ietf-poly1305 salsa20 chacha20 chacha20-ietf'
COMPREPLY=() COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]} cur=${COMP_WORDS[COMP_CWORD]}

1
completions/zsh/_ss-server

@ -28,6 +28,7 @@ _arguments "-h::" \
"--mtu::" \ "--mtu::" \
"--mptcp::" \ "--mptcp::" \
"--no-delay::" \ "--no-delay::" \
"--long-idle::" \
"--key:key in base64:" \ "--key:key in base64:" \
"--plugin:plugin name:" \ "--plugin:plugin name:" \
"--plugin-opts:plugin options:" \ "--plugin-opts:plugin options:" \

4
doc/ss-server.asciidoc

@ -117,6 +117,10 @@ Only available with Linux kernel > 3.9.0.
--no-delay:: --no-delay::
Enable TCP_NODELAY. Enable TCP_NODELAY.
--long-idle::
Enable TCP long idle connections.
If enable, the connected TCP connections would not be destroyed after timeout.
--acl <acl_config>:: --acl <acl_config>::
Enable ACL (Access Control List) and specify config file. Enable ACL (Access Control List) and specify config file.

1
src/common.h

@ -62,6 +62,7 @@ enum {
GETOPT_VAL_REUSE_PORT, GETOPT_VAL_REUSE_PORT,
GETOPT_VAL_FAST_OPEN, GETOPT_VAL_FAST_OPEN,
GETOPT_VAL_NODELAY, GETOPT_VAL_NODELAY,
GETOPT_VAL_LONGIDLE,
GETOPT_VAL_ACL, GETOPT_VAL_ACL,
GETOPT_VAL_MTU, GETOPT_VAL_MTU,
GETOPT_VAL_MPTCP, GETOPT_VAL_MPTCP,

23
src/server.c

@ -120,6 +120,7 @@ static int mode = TCP_ONLY;
static int ipv6first = 0; static int ipv6first = 0;
int fast_open = 0; int fast_open = 0;
static int no_delay = 0; static int no_delay = 0;
static int long_idle = 0;
static int ret_val = 0; static int ret_val = 0;
#ifdef HAVE_SETRLIMIT #ifdef HAVE_SETRLIMIT
@ -704,6 +705,11 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
if (server->stage == STAGE_STREAM) { if (server->stage == STAGE_STREAM) {
remote = server->remote; remote = server->remote;
buf = remote->buf; buf = remote->buf;
if (!long_idle) {
// Only timer the watcher if a valid connection is established
ev_timer_again(EV_A_ & server->recv_ctx->watcher);
}
} }
ssize_t r = recv(server->fd, buf->data, SOCKET_BUF_SIZE, 0); ssize_t r = recv(server->fd, buf->data, SOCKET_BUF_SIZE, 0);
@ -1107,6 +1113,11 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
return; return;
} }
if (long_idle)
ev_timer_stop(EV_A_ & server->recv_ctx->watcher);
else
ev_timer_again(EV_A_ & server->recv_ctx->watcher);
ssize_t r = recv(remote->fd, server->buf->data, SOCKET_BUF_SIZE, 0); ssize_t r = recv(remote->fd, server->buf->data, SOCKET_BUF_SIZE, 0);
if (r == 0) { if (r == 0) {
@ -1229,9 +1240,6 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
int r = getpeername(remote->fd, (struct sockaddr *)&addr, &len); int r = getpeername(remote->fd, (struct sockaddr *)&addr, &len);
if (r == 0) { if (r == 0) {
// connection connected, stop the request timeout timer
ev_timer_stop(EV_A_ & server->recv_ctx->watcher);
remote_send_ctx->connected = 1; remote_send_ctx->connected = 1;
if (remote->buf->len == 0) { if (remote->buf->len == 0) {
@ -1391,10 +1399,12 @@ new_server(int fd, listen_ctx_t *listener)
int request_timeout = min(MAX_REQUEST_TIMEOUT, listener->timeout) int request_timeout = min(MAX_REQUEST_TIMEOUT, listener->timeout)
+ rand() % MAX_REQUEST_TIMEOUT; + rand() % MAX_REQUEST_TIMEOUT;
int repeat_interval = long_idle ? 0 : listener->timeout;
ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ);
ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE);
ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb,
request_timeout, 0);
request_timeout, repeat_interval);
cork_dllist_add(&connections, &server->entries); cork_dllist_add(&connections, &server->entries);
@ -1571,6 +1581,7 @@ main(int argc, char **argv)
{ "fast-open", no_argument, NULL, GETOPT_VAL_FAST_OPEN }, { "fast-open", no_argument, NULL, GETOPT_VAL_FAST_OPEN },
{ "reuse-port", no_argument, NULL, GETOPT_VAL_REUSE_PORT }, { "reuse-port", no_argument, NULL, GETOPT_VAL_REUSE_PORT },
{ "no-delay", no_argument, NULL, GETOPT_VAL_NODELAY }, { "no-delay", no_argument, NULL, GETOPT_VAL_NODELAY },
{ "long-idle", no_argument, NULL, GETOPT_VAL_LONGIDLE },
{ "acl", required_argument, NULL, GETOPT_VAL_ACL }, { "acl", required_argument, NULL, GETOPT_VAL_ACL },
{ "manager-address", required_argument, NULL, { "manager-address", required_argument, NULL,
GETOPT_VAL_MANAGER_ADDRESS }, GETOPT_VAL_MANAGER_ADDRESS },
@ -1600,6 +1611,10 @@ main(int argc, char **argv)
no_delay = 1; no_delay = 1;
LOGI("enable TCP no-delay"); LOGI("enable TCP no-delay");
break; break;
case GETOPT_VAL_LONGIDLE:
long_idle = 1;
LOGI("enable TCP long idle connections");
break;
case GETOPT_VAL_ACL: case GETOPT_VAL_ACL:
LOGI("initializing acl..."); LOGI("initializing acl...");
acl = !init_acl(optarg); acl = !init_acl(optarg);

4
src/utils.c

@ -406,6 +406,10 @@ usage()
#ifndef MODULE_MANAGER #ifndef MODULE_MANAGER
printf( printf(
" [--no-delay] Enable TCP_NODELAY.\n"); " [--no-delay] Enable TCP_NODELAY.\n");
#ifdef MODULE_REMOTE
printf(
" [--long-idle] Enable TCP long idle connections.\n");
#endif
printf( printf(
" [--key <key_in_base64>] Key of your remote server.\n"); " [--key <key_in_base64>] Key of your remote server.\n");
#endif #endif

Loading…
Cancel
Save