Browse Source

Enlarge the socket buffer size to 16KB.

After five years, memory footprint is not a problem for most of
low-end boxes and high-end routers now.

It should also improve the speed on loopback and high-speed LAN
networks.
pull/2365/head
Max Lv 6 years ago
parent
commit
a7291ea725
5 changed files with 42 additions and 52 deletions
  1. 26
      src/local.c
  2. 2
      src/netutils.h
  3. 24
      src/redir.c
  4. 24
      src/server.c
  5. 18
      src/tunnel.c

26
src/local.c

@ -79,10 +79,6 @@
#define EWOULDBLOCK EAGAIN
#endif
#ifndef BUF_SIZE
#define BUF_SIZE 2048
#endif
int verbose = 0;
int reuse_port = 0;
@ -302,7 +298,7 @@ server_handshake_reply(EV_P_ ev_io *w, int udp_assc, struct socks5_response *res
buffer_t resp_to_send;
buffer_t *resp_buf = &resp_to_send;
balloc(resp_buf, BUF_SIZE);
balloc(resp_buf, SOCKET_BUF_SIZE);
memcpy(resp_buf->data, response, sizeof(struct socks5_response));
memcpy(resp_buf->data + sizeof(struct socks5_response),
@ -450,7 +446,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf)
else if (dst_port == tls_protocol->default_port)
hostname_len = tls_protocol->parse_packet(buf->data + 3 + abuf->len,
buf->len - 3 - abuf->len, &hostname);
if (hostname_len == -1 && buf->len < BUF_SIZE && server->stage != STAGE_SNI) {
if (hostname_len == -1 && buf->len < SOCKET_BUF_SIZE && server->stage != STAGE_SNI) {
if (server_handshake_reply(EV_A_ w, 0, &response) < 0)
return -1;
server->stage = STAGE_SNI;
@ -602,7 +598,7 @@ not_bypass:
}
if (!remote->direct) {
int err = crypto->encrypt(abuf, server->e_ctx, BUF_SIZE);
int err = crypto->encrypt(abuf, server->e_ctx, SOCKET_BUF_SIZE);
if (err) {
LOGE("invalid password or cipher");
close_and_free_remote(EV_A_ remote);
@ -646,7 +642,7 @@ server_stream(EV_P_ ev_io *w, buffer_t *buf)
#ifdef __ANDROID__
tx += remote->buf->len;
#endif
int err = crypto->encrypt(remote->buf, server->e_ctx, BUF_SIZE);
int err = crypto->encrypt(remote->buf, server->e_ctx, SOCKET_BUF_SIZE);
if (err) {
LOGE("invalid password or cipher");
@ -656,7 +652,7 @@ server_stream(EV_P_ ev_io *w, buffer_t *buf)
}
if (server->abuf) {
bprepend(remote->buf, server->abuf, BUF_SIZE);
bprepend(remote->buf, server->abuf, SOCKET_BUF_SIZE);
bfree(server->abuf);
ss_free(server->abuf);
server->abuf = NULL;
@ -849,7 +845,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
}
if (revents != EV_TIMER) {
r = recv(server->fd, buf->data + buf->len, BUF_SIZE - buf->len, 0);
r = recv(server->fd, buf->data + buf->len, SOCKET_BUF_SIZE - buf->len, 0);
if (r == 0) {
// connection closed
@ -1006,7 +1002,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
remote_t *remote = remote_recv_ctx->remote;
server_t *server = remote->server;
ssize_t r = recv(remote->fd, server->buf->data, BUF_SIZE, 0);
ssize_t r = recv(remote->fd, server->buf->data, SOCKET_BUF_SIZE, 0);
if (r == 0) {
// connection closed
@ -1033,7 +1029,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
rx += server->buf->len;
stat_update_cb();
#endif
int err = crypto->decrypt(server->buf, server->d_ctx, BUF_SIZE);
int err = crypto->decrypt(server->buf, server->d_ctx, SOCKET_BUF_SIZE);
if (err == CRYPTO_ERROR) {
LOGE("invalid password or cipher");
close_and_free_remote(EV_A_ remote);
@ -1179,7 +1175,7 @@ new_remote(int fd, int timeout)
remote->buf = ss_malloc(sizeof(buffer_t));
remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t));
remote->send_ctx = ss_malloc(sizeof(remote_ctx_t));
balloc(remote->buf, BUF_SIZE);
balloc(remote->buf, SOCKET_BUF_SIZE);
memset(remote->recv_ctx, 0, sizeof(remote_ctx_t));
memset(remote->send_ctx, 0, sizeof(remote_ctx_t));
remote->recv_ctx->connected = 0;
@ -1235,8 +1231,8 @@ new_server(int fd)
server->send_ctx = ss_malloc(sizeof(server_ctx_t));
server->buf = ss_malloc(sizeof(buffer_t));
server->abuf = ss_malloc(sizeof(buffer_t));
balloc(server->buf, BUF_SIZE);
balloc(server->abuf, BUF_SIZE);
balloc(server->buf, SOCKET_BUF_SIZE);
balloc(server->abuf, SOCKET_BUF_SIZE);
memset(server->recv_ctx, 0, sizeof(server_ctx_t));
memset(server->send_ctx, 0, sizeof(server_ctx_t));
server->stage = STAGE_INIT;

2
src/netutils.h

@ -55,6 +55,8 @@
#define MAX_HOSTNAME_LEN 256 // FQCN <= 255 characters
#define MAX_PORT_STR_LEN 6 // PORT < 65536
#define SOCKET_BUF_SIZE (16 * 1024) // 16KB
typedef struct {
char *host;
char *port;

24
src/redir.c

@ -61,8 +61,8 @@
#define EWOULDBLOCK EAGAIN
#endif
#ifndef BUF_SIZE
#define BUF_SIZE 2048
#ifndef SOCKET_BUF_SIZE
#define SOCKET_BUF_SIZE 2048
#endif
#ifndef IP6T_SO_ORIGINAL_DST
@ -196,7 +196,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
ev_timer_stop(EV_A_ & server->delayed_connect_watcher);
ssize_t r = recv(server->fd, remote->buf->data + remote->buf->len,
BUF_SIZE - remote->buf->len, 0);
SOCKET_BUF_SIZE - remote->buf->len, 0);
if (r == 0) {
// connection closed
@ -242,7 +242,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
return;
}
int err = crypto->encrypt(remote->buf, server->e_ctx, BUF_SIZE);
int err = crypto->encrypt(remote->buf, server->e_ctx, SOCKET_BUF_SIZE);
if (err) {
LOGE("invalid password or cipher");
@ -361,7 +361,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
remote_t *remote = remote_recv_ctx->remote;
server_t *server = remote->server;
ssize_t r = recv(remote->fd, server->buf->data, BUF_SIZE, 0);
ssize_t r = recv(remote->fd, server->buf->data, SOCKET_BUF_SIZE, 0);
if (r == 0) {
// connection closed
@ -383,7 +383,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
server->buf->len = r;
int err = crypto->decrypt(server->buf, server->d_ctx, BUF_SIZE);
int err = crypto->decrypt(server->buf, server->d_ctx, SOCKET_BUF_SIZE);
if (err == CRYPTO_ERROR) {
LOGE("invalid password or cipher");
close_and_free_remote(EV_A_ remote);
@ -450,7 +450,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
// send destaddr
buffer_t ss_addr_to_send;
buffer_t *abuf = &ss_addr_to_send;
balloc(abuf, BUF_SIZE);
balloc(abuf, SOCKET_BUF_SIZE);
if (AF_INET6 == server->destaddr.ss_family) { // IPv6
abuf->data[abuf->len++] = 4; // Type 4 is IPv6 address
@ -476,7 +476,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
abuf->len += 2;
int err = crypto->encrypt(abuf, server->e_ctx, BUF_SIZE);
int err = crypto->encrypt(abuf, server->e_ctx, SOCKET_BUF_SIZE);
if (err) {
LOGE("invalid password or cipher");
bfree(abuf);
@ -485,7 +485,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
return;
}
err = crypto->encrypt(remote->buf, server->e_ctx, BUF_SIZE);
err = crypto->encrypt(remote->buf, server->e_ctx, SOCKET_BUF_SIZE);
if (err) {
LOGE("invalid password or cipher");
bfree(abuf);
@ -494,7 +494,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
return;
}
bprepend(remote->buf, abuf, BUF_SIZE);
bprepend(remote->buf, abuf, SOCKET_BUF_SIZE);
bfree(abuf);
} else {
ERROR("getpeername");
@ -588,7 +588,7 @@ new_remote(int fd, int timeout)
remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t));
remote->send_ctx = ss_malloc(sizeof(remote_ctx_t));
remote->buf = ss_malloc(sizeof(buffer_t));
balloc(remote->buf, BUF_SIZE);
balloc(remote->buf, SOCKET_BUF_SIZE);
memset(remote->recv_ctx, 0, sizeof(remote_ctx_t));
memset(remote->send_ctx, 0, sizeof(remote_ctx_t));
remote->fd = fd;
@ -641,7 +641,7 @@ new_server(int fd)
server->recv_ctx = ss_malloc(sizeof(server_ctx_t));
server->send_ctx = ss_malloc(sizeof(server_ctx_t));
server->buf = ss_malloc(sizeof(buffer_t));
balloc(server->buf, BUF_SIZE);
balloc(server->buf, SOCKET_BUF_SIZE);
memset(server->recv_ctx, 0, sizeof(server_ctx_t));
memset(server->send_ctx, 0, sizeof(server_ctx_t));
server->fd = fd;

24
src/server.c

@ -66,10 +66,6 @@
#define EWOULDBLOCK EAGAIN
#endif
#ifndef BUF_SIZE
#define BUF_SIZE 2048
#endif
#ifndef SSMAXCONN
#define SSMAXCONN 1024
#endif
@ -163,13 +159,13 @@ stat_update_cb(EV_P_ ev_timer *watcher, int revents)
struct sockaddr_un svaddr, claddr;
int sfd = -1;
size_t msgLen;
char resp[BUF_SIZE];
char resp[SOCKET_BUF_SIZE];
if (verbose) {
LOGI("update traffic stat: tx: %" PRIu64 " rx: %" PRIu64 "", tx, rx);
}
snprintf(resp, BUF_SIZE, "stat: {\"%s\":%" PRIu64 "}", remote_port, tx + rx);
snprintf(resp, SOCKET_BUF_SIZE, "stat: {\"%s\":%" PRIu64 "}", remote_port, tx + rx);
msgLen = strlen(resp) + 1;
ss_addr_t ip_addr = { .host = NULL, .port = NULL };
@ -728,7 +724,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
ev_timer_again(EV_A_ & server->recv_ctx->watcher);
}
ssize_t r = recv(server->fd, buf->data, BUF_SIZE, 0);
ssize_t r = recv(server->fd, buf->data, SOCKET_BUF_SIZE, 0);
if (r == 0) {
// connection closed
@ -754,7 +750,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
tx += r;
buf->len = r;
int err = crypto->decrypt(buf, server->d_ctx, BUF_SIZE);
int err = crypto->decrypt(buf, server->d_ctx, SOCKET_BUF_SIZE);
if (err == CRYPTO_ERROR) {
report_addr(server->fd, MALICIOUS, "authentication error");
@ -946,7 +942,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
// XXX: should handle buffer carefully
if (server->buf->len > 0) {
brealloc(remote->buf, server->buf->len, BUF_SIZE);
brealloc(remote->buf, server->buf->len, SOCKET_BUF_SIZE);
memcpy(remote->buf->data, server->buf->data + server->buf->idx,
server->buf->len);
remote->buf->len = server->buf->len;
@ -1110,7 +1106,7 @@ resolv_cb(struct sockaddr *addr, void *data)
// XXX: should handle buffer carefully
if (server->buf->len > 0) {
brealloc(remote->buf, server->buf->len, BUF_SIZE);
brealloc(remote->buf, server->buf->len, SOCKET_BUF_SIZE);
memcpy(remote->buf->data, server->buf->data + server->buf->idx,
server->buf->len);
remote->buf->len = server->buf->len;
@ -1140,7 +1136,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
ev_timer_again(EV_A_ & server->recv_ctx->watcher);
ssize_t r = recv(remote->fd, server->buf->data, BUF_SIZE, 0);
ssize_t r = recv(remote->fd, server->buf->data, SOCKET_BUF_SIZE, 0);
if (r == 0) {
// connection closed
@ -1166,7 +1162,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
rx += r;
server->buf->len = r;
int err = crypto->encrypt(server->buf, server->e_ctx, BUF_SIZE);
int err = crypto->encrypt(server->buf, server->e_ctx, SOCKET_BUF_SIZE);
if (err) {
LOGE("invalid password or cipher");
@ -1341,7 +1337,7 @@ new_remote(int fd)
remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t));
remote->send_ctx = ss_malloc(sizeof(remote_ctx_t));
remote->buf = ss_malloc(sizeof(buffer_t));
balloc(remote->buf, BUF_SIZE);
balloc(remote->buf, SOCKET_BUF_SIZE);
memset(remote->recv_ctx, 0, sizeof(remote_ctx_t));
memset(remote->send_ctx, 0, sizeof(remote_ctx_t));
remote->fd = fd;
@ -1404,7 +1400,7 @@ new_server(int fd, listen_ctx_t *listener)
server->buf = ss_malloc(sizeof(buffer_t));
memset(server->recv_ctx, 0, sizeof(server_ctx_t));
memset(server->send_ctx, 0, sizeof(server_ctx_t));
balloc(server->buf, BUF_SIZE);
balloc(server->buf, SOCKET_BUF_SIZE);
server->fd = fd;
server->recv_ctx->server = server;
server->recv_ctx->connected = 0;

18
src/tunnel.c

@ -62,10 +62,6 @@
#define EWOULDBLOCK EAGAIN
#endif
#ifndef BUF_SIZE
#define BUF_SIZE 2048
#endif
static void accept_cb(EV_P_ ev_io *w, int revents);
static void server_recv_cb(EV_P_ ev_io *w, int revents);
static void server_send_cb(EV_P_ ev_io *w, int revents);
@ -195,7 +191,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
return;
}
ssize_t r = recv(server->fd, remote->buf->data, BUF_SIZE, 0);
ssize_t r = recv(server->fd, remote->buf->data, SOCKET_BUF_SIZE, 0);
if (r == 0) {
// connection closed
@ -217,7 +213,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
remote->buf->len = r;
int err = crypto->encrypt(remote->buf, server->e_ctx, BUF_SIZE);
int err = crypto->encrypt(remote->buf, server->e_ctx, SOCKET_BUF_SIZE);
if (err) {
LOGE("invalid password or cipher");
@ -319,7 +315,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
remote_t *remote = remote_recv_ctx->remote;
server_t *server = remote->server;
ssize_t r = recv(remote->fd, server->buf->data, BUF_SIZE, 0);
ssize_t r = recv(remote->fd, server->buf->data, SOCKET_BUF_SIZE, 0);
if (r == 0) {
// connection closed
@ -341,7 +337,7 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
server->buf->len = r;
int err = crypto->decrypt(server->buf, server->d_ctx, BUF_SIZE);
int err = crypto->decrypt(server->buf, server->d_ctx, SOCKET_BUF_SIZE);
if (err == CRYPTO_ERROR) {
LOGE("invalid password or cipher");
close_and_free_remote(EV_A_ remote);
@ -449,7 +445,7 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
memcpy(abuf->data + abuf->len, &port, 2);
abuf->len += 2;
int err = crypto->encrypt(abuf, server->e_ctx, BUF_SIZE);
int err = crypto->encrypt(abuf, server->e_ctx, SOCKET_BUF_SIZE);
if (err) {
LOGE("invalid password or cipher");
@ -602,7 +598,7 @@ new_remote(int fd, int timeout)
remote->recv_ctx = ss_malloc(sizeof(remote_ctx_t));
remote->send_ctx = ss_malloc(sizeof(remote_ctx_t));
remote->buf = ss_malloc(sizeof(buffer_t));
balloc(remote->buf, BUF_SIZE);
balloc(remote->buf, SOCKET_BUF_SIZE);
memset(remote->recv_ctx, 0, sizeof(remote_ctx_t));
memset(remote->send_ctx, 0, sizeof(remote_ctx_t));
remote->fd = fd;
@ -655,7 +651,7 @@ new_server(int fd)
server->recv_ctx = ss_malloc(sizeof(server_ctx_t));
server->send_ctx = ss_malloc(sizeof(server_ctx_t));
server->buf = ss_malloc(sizeof(buffer_t));
balloc(server->buf, BUF_SIZE);
balloc(server->buf, SOCKET_BUF_SIZE);
memset(server->recv_ctx, 0, sizeof(server_ctx_t));
memset(server->send_ctx, 0, sizeof(server_ctx_t));
server->fd = fd;

Loading…
Cancel
Save