diff --git a/src/udprelay.c b/src/udprelay.c index c4e7bd26..40a536db 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -473,6 +473,11 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) goto CLEAN_UP; } +#ifdef UDPRELAY_TUNNEL + // Construct packet + buf_len -= addr_header_len; + memmove(buf, buf + addr_header_len, buf_len); +#else // Construct packet char *tmpbuf = malloc(buf_len + 3); memset(tmpbuf, 0, 3); @@ -481,6 +486,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) buf = tmpbuf; buf_len += 3; #endif +#endif #ifdef UDPRELAY_REMOTE // Construct packet @@ -590,12 +596,20 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) int host_len = strlen(host); uint16_t port_num = (uint16_t)atoi(port); uint16_t port_net_num = htons(port_num); - int addr_header_len = 1 + host_len + 2; + int addr_header_len = 2 + host_len + 2; // initialize the addr header addr_header[0] = 3; - memcpy(addr_header + 1, host, host_len); - memcpy(addr_header + 1 + host_len, &port_net_num, 2); + addr_header[1] = host_len; + memcpy(addr_header + 2, host, host_len); + memcpy(addr_header + 2 + host_len, &port_net_num, 2); + + // reconstruct the buffer + char *tmp = malloc(buf_len + addr_header_len); + memcpy(tmp, addr_header, addr_header_len); + memcpy(tmp + addr_header_len, buf, buf_len); + free(buf); + buf = tmp; #else char host[256] = {0}; @@ -696,8 +710,11 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) freeaddrinfo(result); } - buf_len -= offset; - memmove(buf, buf + offset, buf_len); + if (offset > 0) + { + buf_len -= offset; + memmove(buf, buf + offset, buf_len); + } buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); diff --git a/src/utils.c b/src/utils.c index 7a18c90c..98612c87 100644 --- a/src/utils.c +++ b/src/utils.c @@ -82,9 +82,10 @@ void usage() { printf("\n"); printf("shadowsocks-libev %s\n\n", VERSION); - printf(" maintained by Max Lv \n\n"); + printf(" maintained by Max Lv \n"); + printf(" and Linus Yang \n\n"); printf(" usage:\n\n"); - printf(" ss-[local|redir|server]\n"); + printf(" ss-[local|redir|server|tunnel]\n"); printf(" -s host name or ip address of your remote server\n"); printf(" -p port number of your remote server\n"); printf(" -l port number of your local server\n"); @@ -100,11 +101,13 @@ void usage() printf(" [-c ] json format config file\n"); printf("\n"); printf(" [-i ] specific network interface to bind,\n"); - printf(" only available in local and server modes\n"); + printf(" not available in redir mode\n"); printf(" [-b ] specific local address to bind,\n"); - printf(" only available in local and redir modes\n"); + printf(" not available in server mode\n"); printf(" [-u] udprelay mode to supprot udp traffic\n"); - printf(" only available in local and server modes\n"); + printf(" not available in redir mode\n"); + printf(" [-L :] setup a local port forwarding tunnel\n"); + printf(" only available in tunnel mode\n"); printf(" [-v] verbose mode, debug output in console\n"); printf("\n"); }