Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ enum {
GETOPT_VAL_MANAGER_ADDRESS,
GETOPT_VAL_EXECUTABLE,
GETOPT_VAL_WORKDIR,
GETOPT_VAL_TCP_INCOMING_SNDBUF,
GETOPT_VAL_TCP_INCOMING_RCVBUF,
GETOPT_VAL_TCP_OUTGOING_SNDBUF,
GETOPT_VAL_TCP_OUTGOING_RCVBUF
};

#endif // _COMMON_H
16 changes: 16 additions & 0 deletions src/jconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,22 @@ read_jconf(const char *file)
check_json_value_type(value, json_boolean,
"invalid config file: option 'reuse_port' must be a boolean");
conf.reuse_port = value->u.boolean;
} else if (strcmp(name, "tcp_incoming_sndbuf") == 0) {
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) {
Expand Down
4 changes: 4 additions & 0 deletions src/jconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ typedef struct {
char *plugin_opts;
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;
Expand Down
80 changes: 80 additions & 0 deletions src/local.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@

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;
Expand Down Expand Up @@ -1300,6 +1304,14 @@ create_remote(listen_ctx_t *listener,
}
}

if (tcp_outgoing_sndbuf > 0) {
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
Expand Down Expand Up @@ -1390,6 +1402,14 @@ accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif

if (tcp_incoming_sndbuf > 0) {
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;

Expand Down Expand Up @@ -1430,6 +1450,10 @@ 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 },
Expand Down Expand Up @@ -1486,6 +1510,18 @@ main(int argc, char **argv)
case GETOPT_VAL_REUSE_PORT:
reuse_port = 1;
break;
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++]);
Expand Down Expand Up @@ -1613,6 +1649,18 @@ main(int argc, char **argv)
if (reuse_port == 0) {
reuse_port = conf->reuse_port;
}
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;
}
Expand Down Expand Up @@ -1665,6 +1713,38 @@ main(int argc, char **argv)
winsock_init();
#endif

if (tcp_incoming_sndbuf != 0 && tcp_incoming_sndbuf < SOCKET_BUF_SIZE) {
tcp_incoming_sndbuf = 0;
}

if (tcp_incoming_sndbuf != 0) {
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;
}

if (tcp_outgoing_sndbuf != 0) {
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_rcvbuf);
}

if (plugin != NULL) {
uint16_t port = get_local_port();
if (port == 0) {
Expand Down
80 changes: 80 additions & 0 deletions src/redir.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ 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;

Expand Down Expand Up @@ -755,6 +759,14 @@ accept_cb(EV_P_ ev_io *w, int revents)
setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif

if (tcp_incoming_sndbuf > 0) {
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];

Expand Down Expand Up @@ -814,6 +826,14 @@ accept_cb(EV_P_ ev_io *w, int revents)
}
}

if (tcp_outgoing_sndbuf > 0) {
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;
Expand Down Expand Up @@ -903,6 +923,10 @@ main(int argc, char **argv)
{ "plugin", required_argument, NULL, GETOPT_VAL_PLUGIN },
{ "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 },
Expand Down Expand Up @@ -944,6 +968,18 @@ main(int argc, char **argv)
case GETOPT_VAL_REUSE_PORT:
reuse_port = 1;
break;
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++]);
Expand Down Expand Up @@ -1079,6 +1115,18 @@ main(int argc, char **argv)
if (reuse_port == 0) {
reuse_port = conf->reuse_port;
}
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;
}
Expand Down Expand Up @@ -1167,6 +1215,38 @@ main(int argc, char **argv)
LOGI("resolving hostname to IPv6 address first");
}

if (tcp_incoming_sndbuf != 0 && tcp_incoming_sndbuf < SOCKET_BUF_SIZE) {
tcp_incoming_sndbuf = 0;
}

if (tcp_incoming_sndbuf != 0) {
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;
}

if (tcp_outgoing_sndbuf != 0) {
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_rcvbuf);
}

if (plugin != NULL) {
int len = 0;
size_t buf_size = 256 * remote_num;
Expand Down
Loading