Browse Source

Add --tcp-incoming-rcvbuf and --tcp-outgoing-rcvbuf which allow precise control over TCP receive buffers.

pull/2788/head
Not Sure 3 years ago
committed by Max Lv
parent
commit
36d9993bbf
8 changed files with 177 additions and 1 deletions
  1. 4
      src/common.h
  2. 8
      src/jconf.c
  3. 2
      src/jconf.h
  4. 40
      src/local.c
  5. 40
      src/redir.c
  6. 40
      src/server.c
  7. 40
      src/tunnel.c
  8. 4
      src/utils.c

4
src/common.h

@ -72,7 +72,9 @@ enum {
GETOPT_VAL_EXECUTABLE,
GETOPT_VAL_WORKDIR,
GETOPT_VAL_TCP_INCOMING_SNDBUF,
GETOPT_VAL_TCP_OUTGOING_SNDBUF
GETOPT_VAL_TCP_INCOMING_RCVBUF,
GETOPT_VAL_TCP_OUTGOING_SNDBUF,
GETOPT_VAL_TCP_OUTGOING_RCVBUF
};
#endif // _COMMON_H

8
src/jconf.c

@ -278,10 +278,18 @@ read_jconf(const char *file)
check_json_value_type(value, json_integer,
"invalid config file: option 'tcp_incoming_sndbuf' must be an integer");
conf.tcp_incoming_sndbuf = value->u.integer;
} else if (strcmp(name, "tcp_incoming_rcvbuf") == 0) {
check_json_value_type(value, json_integer,
"invalid config file: option 'tcp_incoming_rcvbuf' must be an integer");
conf.tcp_incoming_rcvbuf = value->u.integer;
} else if (strcmp(name, "tcp_outgoing_sndbuf") == 0) {
check_json_value_type(value, json_integer,
"invalid config file: option 'tcp_outgoing_sndbuf' must be an integer");
conf.tcp_outgoing_sndbuf = value->u.integer;
} else if (strcmp(name, "tcp_outgoing_rcvbuf") == 0) {
check_json_value_type(value, json_integer,
"invalid config file: option 'tcp_outgoing_rcvbuf' must be an integer");
conf.tcp_outgoing_rcvbuf = value->u.integer;
} else if (strcmp(name, "auth") == 0) {
FATAL("One time auth has been deprecated. Try AEAD ciphers instead.");
} else if (strcmp(name, "nofile") == 0) {

2
src/jconf.h

@ -73,7 +73,9 @@ typedef struct {
int fast_open;
int reuse_port;
int tcp_incoming_sndbuf;
int tcp_incoming_rcvbuf;
int tcp_outgoing_sndbuf;
int tcp_outgoing_rcvbuf;
int nofile;
char *nameserver;
int dscp_num;

40
src/local.c

@ -80,7 +80,9 @@
int verbose = 0;
int reuse_port = 0;
int tcp_incoming_sndbuf = 0;
int tcp_incoming_rcvbuf = 0;
int tcp_outgoing_sndbuf = 0;
int tcp_outgoing_rcvbuf = 0;
#ifdef __ANDROID__
int vpn = 0;
@ -1306,6 +1308,10 @@ create_remote(listen_ctx_t *listener,
setsockopt(remotefd, SOL_SOCKET, SO_SNDBUF, &tcp_outgoing_sndbuf, sizeof(int));
}
if (tcp_outgoing_rcvbuf > 0) {
setsockopt(remotefd, SOL_SOCKET, SO_RCVBUF, &tcp_outgoing_rcvbuf, sizeof(int));
}
// Setup
setnonblocking(remotefd);
#ifdef SET_INTERFACE
@ -1400,6 +1406,10 @@ accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int));
}
if (tcp_incoming_rcvbuf > 0) {
setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int));
}
server_t *server = new_server(serverfd);
server->listener = listener;
@ -1441,7 +1451,9 @@ main(int argc, char **argv)
static struct option long_options[] = {
{ "reuse-port", no_argument, NULL, GETOPT_VAL_REUSE_PORT },
{ "tcp-incoming-sndbuf", required_argument, NULL, GETOPT_VAL_TCP_INCOMING_SNDBUF },
{ "tcp-incoming-rcvbuf", required_argument, NULL, GETOPT_VAL_TCP_INCOMING_RCVBUF },
{ "tcp-outgoing-sndbuf", required_argument, NULL, GETOPT_VAL_TCP_OUTGOING_SNDBUF },
{ "tcp-outgoing-rcvbuf", required_argument, NULL, GETOPT_VAL_TCP_OUTGOING_RCVBUF },
{ "fast-open", no_argument, NULL, GETOPT_VAL_FAST_OPEN },
{ "no-delay", no_argument, NULL, GETOPT_VAL_NODELAY },
{ "acl", required_argument, NULL, GETOPT_VAL_ACL },
@ -1501,9 +1513,15 @@ main(int argc, char **argv)
case GETOPT_VAL_TCP_INCOMING_SNDBUF:
tcp_incoming_sndbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_INCOMING_RCVBUF:
tcp_incoming_rcvbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_OUTGOING_SNDBUF:
tcp_outgoing_sndbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_OUTGOING_RCVBUF:
tcp_outgoing_rcvbuf = atoi(optarg);
break;
case 's':
if (remote_num < MAX_REMOTE_NUM) {
parse_addr(optarg, &remote_addr[remote_num++]);
@ -1634,9 +1652,15 @@ main(int argc, char **argv)
if (tcp_incoming_sndbuf == 0) {
tcp_incoming_sndbuf = conf->tcp_incoming_sndbuf;
}
if (tcp_incoming_rcvbuf == 0) {
tcp_incoming_rcvbuf = conf->tcp_incoming_rcvbuf;
}
if (tcp_outgoing_sndbuf == 0) {
tcp_outgoing_sndbuf = conf->tcp_outgoing_sndbuf;
}
if (tcp_outgoing_rcvbuf == 0) {
tcp_outgoing_rcvbuf = conf->tcp_outgoing_rcvbuf;
}
if (fast_open == 0) {
fast_open = conf->fast_open;
}
@ -1697,6 +1721,14 @@ main(int argc, char **argv)
LOGI("set TCP incoming connection send buffer size to %d", tcp_incoming_sndbuf);
}
if (tcp_incoming_rcvbuf != 0 && tcp_incoming_rcvbuf < SOCKET_BUF_SIZE) {
tcp_incoming_rcvbuf = 0;
}
if (tcp_incoming_rcvbuf != 0) {
LOGI("set TCP incoming connection receive buffer size to %d", tcp_incoming_rcvbuf);
}
if (tcp_outgoing_sndbuf != 0 && tcp_outgoing_sndbuf < SOCKET_BUF_SIZE) {
tcp_outgoing_sndbuf = 0;
}
@ -1705,6 +1737,14 @@ main(int argc, char **argv)
LOGI("set TCP outgoing connection send buffer size to %d", tcp_outgoing_sndbuf);
}
if (tcp_outgoing_rcvbuf != 0 && tcp_outgoing_rcvbuf < SOCKET_BUF_SIZE) {
tcp_outgoing_rcvbuf = 0;
}
if (tcp_outgoing_rcvbuf != 0) {
LOGI("set TCP outgoing connection receive buffer size to %d", tcp_outgoing_recvbuf);
}
if (plugin != NULL) {
uint16_t port = get_local_port();
if (port == 0) {

40
src/redir.c

@ -90,7 +90,9 @@ static void close_and_free_server(EV_P_ server_t *server);
int verbose = 0;
int reuse_port = 0;
int tcp_incoming_sndbuf = 0;
int tcp_incoming_rcvbuf = 0;
int tcp_outgoing_sndbuf = 0;
int tcp_outgoing_rcvbuf = 0;
static crypto_t *crypto;
@ -761,6 +763,10 @@ accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int));
}
if (tcp_incoming_rcvbuf > 0) {
setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int));
}
int index = rand() % listener->remote_num;
struct sockaddr *remote_addr = listener->remote_addr[index];
@ -824,6 +830,10 @@ accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(remotefd, SOL_SOCKET, SO_SNDBUF, &tcp_outgoing_sndbuf, sizeof(int));
}
if (tcp_outgoing_rcvbuf > 0) {
setsockopt(remotefd, SOL_SOCKET, SO_RCVBUF, &tcp_outgoing_rcvbuf, sizeof(int));
}
server_t *server = new_server(serverfd);
remote_t *remote = new_remote(remotefd, listener->timeout);
server->remote = remote;
@ -914,7 +924,9 @@ main(int argc, char **argv)
{ "plugin-opts", required_argument, NULL, GETOPT_VAL_PLUGIN_OPTS },
{ "reuse-port", no_argument, NULL, GETOPT_VAL_REUSE_PORT },
{ "tcp-incoming-sndbuf", required_argument, NULL, GETOPT_VAL_TCP_INCOMING_SNDBUF },
{ "tcp-incoming-rcvbuf", required_argument, NULL, GETOPT_VAL_TCP_INCOMING_RCVBUF },
{ "tcp-outgoing-sndbuf", required_argument, NULL, GETOPT_VAL_TCP_OUTGOING_SNDBUF },
{ "tcp-outgoing-rcvbuf", required_argument, NULL, GETOPT_VAL_TCP_OUTGOING_RCVBUF },
{ "no-delay", no_argument, NULL, GETOPT_VAL_NODELAY },
{ "password", required_argument, NULL, GETOPT_VAL_PASSWORD },
{ "key", required_argument, NULL, GETOPT_VAL_KEY },
@ -959,9 +971,15 @@ main(int argc, char **argv)
case GETOPT_VAL_TCP_INCOMING_SNDBUF:
tcp_incoming_sndbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_INCOMING_RCVBUF:
tcp_incoming_rcvbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_OUTGOING_SNDBUF:
tcp_outgoing_sndbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_OUTGOING_RCVBUF:
tcp_outgoing_rcvbuf = atoi(optarg);
break;
case 's':
if (remote_num < MAX_REMOTE_NUM) {
parse_addr(optarg, &remote_addr[remote_num++]);
@ -1100,9 +1118,15 @@ main(int argc, char **argv)
if (tcp_incoming_sndbuf == 0) {
tcp_incoming_sndbuf = conf->tcp_incoming_sndbuf;
}
if (tcp_incoming_rcvbuf == 0) {
tcp_incoming_rcvbuf = conf->tcp_incoming_rcvbuf;
}
if (tcp_outgoing_sndbuf == 0) {
tcp_outgoing_sndbuf = conf->tcp_outgoing_sndbuf;
}
if (tcp_outgoing_rcvbuf == 0) {
tcp_outgoing_rcvbuf = conf->tcp_outgoing_rcvbuf;
}
if (fast_open == 0) {
fast_open = conf->fast_open;
}
@ -1199,6 +1223,14 @@ main(int argc, char **argv)
LOGI("set TCP incoming connection send buffer size to %d", tcp_incoming_sndbuf);
}
if (tcp_incoming_rcvbuf != 0 && tcp_incoming_rcvbuf < SOCKET_BUF_SIZE) {
tcp_incoming_rcvbuf = 0;
}
if (tcp_incoming_rcvbuf != 0) {
LOGI("set TCP incoming connection receive buffer size to %d", tcp_incoming_rcvbuf);
}
if (tcp_outgoing_sndbuf != 0 && tcp_outgoing_sndbuf < SOCKET_BUF_SIZE) {
tcp_outgoing_sndbuf = 0;
}
@ -1207,6 +1239,14 @@ main(int argc, char **argv)
LOGI("set TCP outgoing connection send buffer size to %d", tcp_outgoing_sndbuf);
}
if (tcp_outgoing_rcvbuf != 0 && tcp_outgoing_rcvbuf < SOCKET_BUF_SIZE) {
tcp_outgoing_rcvbuf = 0;
}
if (tcp_outgoing_rcvbuf != 0) {
LOGI("set TCP outgoing connection receive buffer size to %d", tcp_outgoing_recvbuf);
}
if (plugin != NULL) {
int len = 0;
size_t buf_size = 256 * remote_num;

40
src/server.c

@ -110,7 +110,9 @@ static void resolv_free_cb(void *data);
int verbose = 0;
int reuse_port = 0;
int tcp_incoming_sndbuf = 0;
int tcp_incoming_rcvbuf = 0;
int tcp_outgoing_sndbuf = 0;
int tcp_outgoing_rcvbuf = 0;
int is_bind_local_addr = 0;
struct sockaddr_storage local_addr_v4;
@ -477,6 +479,10 @@ connect_to_remote(EV_P_ struct addrinfo *res,
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &tcp_outgoing_sndbuf, sizeof(int));
}
if (tcp_outgoing_rcvbuf > 0) {
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &tcp_outgoing_rcvbuf, sizeof(int));
}
// setup remote socks
if (setnonblocking(sockfd) == -1)
@ -1549,6 +1555,10 @@ accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int));
}
if (tcp_incoming_rcvbuf > 0) {
setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int));
}
setnonblocking(serverfd);
server_t *server = new_server(serverfd, listener);
@ -1589,7 +1599,9 @@ main(int argc, char **argv)
{ "fast-open", no_argument, NULL, GETOPT_VAL_FAST_OPEN },
{ "reuse-port", no_argument, NULL, GETOPT_VAL_REUSE_PORT },
{ "tcp-incoming-sndbuf", required_argument, NULL, GETOPT_VAL_TCP_INCOMING_SNDBUF },
{ "tcp-incoming-rcvbuf", required_argument, NULL, GETOPT_VAL_TCP_INCOMING_RCVBUF },
{ "tcp-outgoing-sndbuf", required_argument, NULL, GETOPT_VAL_TCP_OUTGOING_SNDBUF },
{ "tcp-outgoing-rcvbuf", required_argument, NULL, GETOPT_VAL_TCP_OUTGOING_RCVBUF },
{ "no-delay", no_argument, NULL, GETOPT_VAL_NODELAY },
{ "acl", required_argument, NULL, GETOPT_VAL_ACL },
{ "manager-address", required_argument, NULL,
@ -1650,9 +1662,15 @@ main(int argc, char **argv)
case GETOPT_VAL_TCP_INCOMING_SNDBUF:
tcp_incoming_sndbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_INCOMING_RCVBUF:
tcp_incoming_rcvbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_OUTGOING_SNDBUF:
tcp_outgoing_sndbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_OUTGOING_RCVBUF:
tcp_outgoing_rcvbuf = atoi(optarg);
break;
case 's':
if (server_num < MAX_REMOTE_NUM) {
parse_addr(optarg, &server_addr[server_num++]);
@ -1782,9 +1800,15 @@ main(int argc, char **argv)
if (tcp_incoming_sndbuf == 0) {
tcp_incoming_sndbuf = conf->tcp_incoming_sndbuf;
}
if (tcp_incoming_rcvbuf == 0) {
tcp_incoming_rcvbuf = conf->tcp_incoming_rcvbuf;
}
if (tcp_outgoing_sndbuf == 0) {
tcp_outgoing_sndbuf = conf->tcp_outgoing_sndbuf;
}
if (tcp_outgoing_rcvbuf == 0) {
tcp_outgoing_rcvbuf = conf->tcp_outgoing_rcvbuf;
}
if (fast_open == 0) {
fast_open = conf->fast_open;
}
@ -1820,6 +1844,14 @@ main(int argc, char **argv)
LOGI("set TCP incoming connection send buffer size to %d", tcp_incoming_sndbuf);
}
if (tcp_incoming_rcvbuf != 0 && tcp_incoming_rcvbuf < SOCKET_BUF_SIZE) {
tcp_incoming_rcvbuf = 0;
}
if (tcp_incoming_rcvbuf != 0) {
LOGI("set TCP incoming connection receive buffer size to %d", tcp_incoming_rcvbuf);
}
if (tcp_outgoing_sndbuf != 0 && tcp_outgoing_sndbuf < SOCKET_BUF_SIZE) {
tcp_outgoing_sndbuf = 0;
}
@ -1828,6 +1860,14 @@ main(int argc, char **argv)
LOGI("set TCP outgoing connection send buffer size to %d", tcp_outgoing_sndbuf);
}
if (tcp_outgoing_rcvbuf != 0 && tcp_outgoing_rcvbuf < SOCKET_BUF_SIZE) {
tcp_outgoing_rcvbuf = 0;
}
if (tcp_outgoing_rcvbuf != 0) {
LOGI("set TCP outgoing connection receive buffer size to %d", tcp_outgoing_recvbuf);
}
if (server_num == 0) {
server_addr[server_num++].host = "0.0.0.0";
}

40
src/tunnel.c

@ -83,7 +83,9 @@ int vpn = 0;
int verbose = 0;
int reuse_port = 0;
int tcp_incoming_sndbuf = 0;
int tcp_incoming_rcvbuf = 0;
int tcp_outgoing_sndbuf = 0;
int tcp_outgoing_rcvbuf = 0;
static crypto_t *crypto;
@ -727,6 +729,10 @@ accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(serverfd, SOL_SOCKET, SO_SNDBUF, &tcp_incoming_sndbuf, sizeof(int));
}
if (tcp_incoming_rcvbuf > 0) {
setsockopt(serverfd, SOL_SOCKET, SO_RCVBUF, &tcp_incoming_rcvbuf, sizeof(int));
}
int index = rand() % listener->remote_num;
struct sockaddr *remote_addr = listener->remote_addr[index];
@ -784,6 +790,10 @@ accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(remotefd, SOL_SOCKET, SO_SNDBUF, &tcp_outgoing_sndbuf, sizeof(int));
}
if (tcp_outgoing_rcvbuf > 0) {
setsockopt(remotefd, SOL_SOCKET, SO_RCVBUF, &tcp_outgoing_rcvbuf, sizeof(int));
}
// Setup
setnonblocking(remotefd);
#ifdef SET_INTERFACE
@ -909,7 +919,9 @@ main(int argc, char **argv)
{ "plugin-opts", required_argument, NULL, GETOPT_VAL_PLUGIN_OPTS },
{ "reuse-port", no_argument, NULL, GETOPT_VAL_REUSE_PORT },
{ "tcp-incoming-sndbuf", required_argument, NULL, GETOPT_VAL_TCP_INCOMING_SNDBUF },
{ "tcp-incoming-rcvbuf", required_argument, NULL, GETOPT_VAL_TCP_INCOMING_RCVBUF },
{ "tcp-outgoing-sndbuf", required_argument, NULL, GETOPT_VAL_TCP_OUTGOING_SNDBUF },
{ "tcp-outgoing-rcvbuf", required_argument, NULL, GETOPT_VAL_TCP_OUTGOING_RCVBUF },
{ "password", required_argument, NULL, GETOPT_VAL_PASSWORD },
{ "key", required_argument, NULL, GETOPT_VAL_KEY },
{ "help", no_argument, NULL, GETOPT_VAL_HELP },
@ -958,9 +970,15 @@ main(int argc, char **argv)
case GETOPT_VAL_TCP_INCOMING_SNDBUF:
tcp_incoming_sndbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_INCOMING_RCVBUF:
tcp_incoming_rcvbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_OUTGOING_SNDBUF:
tcp_outgoing_sndbuf = atoi(optarg);
break;
case GETOPT_VAL_TCP_OUTGOING_RCVBUF:
tcp_outgoing_rcvbuf = atoi(optarg);
break;
case 's':
if (remote_num < MAX_REMOTE_NUM) {
parse_addr(optarg, &remote_addr[remote_num++]);
@ -1107,9 +1125,15 @@ main(int argc, char **argv)
if (tcp_incoming_sndbuf == 0) {
tcp_incoming_sndbuf = conf->tcp_incoming_sndbuf;
}
if (tcp_incoming_rcvbuf == 0) {
tcp_incoming_rcvbuf = conf->tcp_incoming_rcvbuf;
}
if (tcp_outgoing_sndbuf == 0) {
tcp_outgoing_sndbuf = conf->tcp_outgoing_sndbuf;
}
if (tcp_outgoing_rcvbuf == 0) {
tcp_outgoing_rcvbuf = conf->tcp_outgoing_rcvbuf;
}
if (fast_open == 0) {
fast_open = conf->fast_open;
}
@ -1138,6 +1162,14 @@ main(int argc, char **argv)
LOGI("set TCP incoming connection send buffer size to %d", tcp_incoming_sndbuf);
}
if (tcp_incoming_rcvbuf != 0 && tcp_incoming_rcvbuf < SOCKET_BUF_SIZE) {
tcp_incoming_rcvbuf = 0;
}
if (tcp_incoming_rcvbuf != 0) {
LOGI("set TCP incoming connection receive buffer size to %d", tcp_incoming_rcvbuf);
}
if (tcp_outgoing_sndbuf != 0 && tcp_outgoing_sndbuf < SOCKET_BUF_SIZE) {
tcp_outgoing_sndbuf = 0;
}
@ -1146,6 +1178,14 @@ main(int argc, char **argv)
LOGI("set TCP outgoing connection send buffer size to %d", tcp_outgoing_sndbuf);
}
if (tcp_outgoing_rcvbuf != 0 && tcp_outgoing_rcvbuf < SOCKET_BUF_SIZE) {
tcp_outgoing_rcvbuf = 0;
}
if (tcp_outgoing_rcvbuf != 0) {
LOGI("set TCP outgoing connection receive buffer size to %d", tcp_outgoing_recvbuf);
}
if (plugin != NULL) {
uint16_t port = get_local_port();
if (port == 0) {

4
src/utils.c

@ -389,8 +389,12 @@ usage()
#endif
printf(
" [--tcp-incoming-sndbuf] Size of the incoming connection TCP send buffer.\n");
printf(
" [--tcp-incoming-rcvbuf] Size of the incoming connection TCP receive buffer.\n");
printf(
" [--tcp-outgoing-sndbuf] Size of the outgoing connection TCP send buffer.\n");
printf(
" [--tcp-outgoing-rcvbuf] Size of the outgoing connection TCP receive buffer.\n");
#if defined(MODULE_REMOTE) || defined(MODULE_LOCAL)
printf(
" [--acl <acl_file>] Path to ACL (Access Control List).\n");

Loading…
Cancel
Save