mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-20 21:43:41 +00:00
add UDP relay only mode
This commit is contained in:
@@ -43,6 +43,10 @@
|
||||
#define SOL_TCP IPPROTO_TCP
|
||||
#endif
|
||||
|
||||
#define TCP_ONLY 0
|
||||
#define TCP_AND_UDP 1
|
||||
#define UDP_ONLY 3
|
||||
|
||||
int init_udprelay(const char *server_host, const char *server_port,
|
||||
#ifdef UDPRELAY_LOCAL
|
||||
const struct sockaddr *remote_addr, const int remote_addr_len,
|
||||
|
||||
+87
-62
@@ -79,9 +79,11 @@
|
||||
#define BUF_SIZE 2048
|
||||
#endif
|
||||
|
||||
int acl = 0;
|
||||
int verbose = 0;
|
||||
int udprelay = 0;
|
||||
|
||||
static int acl = 0;
|
||||
static int mode = TCP_ONLY;
|
||||
|
||||
static int fast_open = 0;
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
#ifndef LIB_ONLY
|
||||
@@ -342,7 +344,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
|
||||
int udp_assc = 0;
|
||||
|
||||
if (udprelay && request->cmd == 3) {
|
||||
if (mode != TCP_ONLY && request->cmd == 3) {
|
||||
udp_assc = 1;
|
||||
socklen_t addr_len = sizeof(sock_addr);
|
||||
getsockname(server->fd, (struct sockaddr *)&sock_addr,
|
||||
@@ -429,7 +431,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
LOGI("connect to %s:%s", host, port);
|
||||
}
|
||||
|
||||
if ((acl && (request->atyp == 1 || request->atyp == 3) && acl_contains_ip(host))) {
|
||||
if ((acl && (request->atyp == 1 || request->atyp == 4) && acl_contains_ip(host))) {
|
||||
if (verbose) {
|
||||
LOGI("bypass %s:%s", host, port);
|
||||
}
|
||||
@@ -901,7 +903,7 @@ int main(int argc, char **argv)
|
||||
|
||||
USE_TTY();
|
||||
|
||||
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:uv",
|
||||
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:uUv",
|
||||
long_options, &option_index)) != -1) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
@@ -950,7 +952,10 @@ int main(int argc, char **argv)
|
||||
user = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
udprelay = 1;
|
||||
mode = TCP_AND_UDP;
|
||||
break;
|
||||
case 'U':
|
||||
mode = UDP_ONLY;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
@@ -1060,18 +1065,6 @@ int main(int argc, char **argv)
|
||||
LOGI("initialize ciphers... %s", method);
|
||||
int m = enc_init(password, method);
|
||||
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error");
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1) {
|
||||
FATAL("listen() error");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
LOGI("listening at %s:%s", local_addr, local_port);
|
||||
|
||||
// Setup proxy context
|
||||
struct listen_ctx listen_ctx;
|
||||
listen_ctx.remote_num = remote_num;
|
||||
@@ -1079,7 +1072,7 @@ int main(int argc, char **argv)
|
||||
for (i = 0; i < remote_num; i++) {
|
||||
char *host = remote_addr[i].host;
|
||||
char *port = remote_addr[i].port == NULL ? remote_port :
|
||||
remote_addr[i].port;
|
||||
remote_addr[i].port;
|
||||
struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage));
|
||||
memset(storage, 0, sizeof(struct sockaddr_storage));
|
||||
if (get_sockaddr(host, port, storage, 1) == -1) {
|
||||
@@ -1088,21 +1081,38 @@ int main(int argc, char **argv)
|
||||
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;
|
||||
}
|
||||
listen_ctx.timeout = atoi(timeout);
|
||||
listen_ctx.fd = listenfd;
|
||||
listen_ctx.iface = iface;
|
||||
listen_ctx.method = m;
|
||||
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx.io);
|
||||
|
||||
if (mode != UDP_ONLY) {
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error");
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1) {
|
||||
FATAL("listen() error");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
|
||||
listen_ctx.fd = listenfd;
|
||||
|
||||
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx.io);
|
||||
}
|
||||
|
||||
// Setup UDP
|
||||
if (udprelay) {
|
||||
if (mode != TCP_ONLY) {
|
||||
LOGI("udprelay enabled");
|
||||
init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0],
|
||||
get_sockaddr_len(listen_ctx.remote_addr[0]), m, listen_ctx.timeout, iface);
|
||||
}
|
||||
|
||||
LOGI("listening at %s:%s", local_addr, local_port);
|
||||
|
||||
// setuid
|
||||
if (user != NULL) {
|
||||
run_as(user);
|
||||
@@ -1119,10 +1129,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
// Clean up
|
||||
free_connections(loop);
|
||||
free_udprelay();
|
||||
if (mode != UDP_ONLY) {
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
free_connections(loop);
|
||||
}
|
||||
|
||||
if (mode != TCP_ONLY) {
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
for (i = 0; i < remote_num; i++) {
|
||||
free(listen_ctx.remote_addr[i]);
|
||||
}
|
||||
@@ -1153,7 +1168,7 @@ int start_ss_local_server(profile_t profile)
|
||||
int local_port = profile.local_port;
|
||||
int timeout = profile.timeout;
|
||||
|
||||
udprelay = profile.udp_relay;
|
||||
mode = profile.mode;
|
||||
fast_open = profile.fast_open;
|
||||
verbose = profile.verbose;
|
||||
|
||||
@@ -1191,50 +1206,57 @@ int start_ss_local_server(profile_t profile)
|
||||
LOGI("initialize ciphers... %s", method);
|
||||
int m = enc_init(password, method);
|
||||
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port_str);
|
||||
if (listenfd < 0) {
|
||||
ERROR("bind()");
|
||||
return -1;
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1) {
|
||||
ERROR("listen()");
|
||||
return -1;
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
LOGI("listening at %s:%s", local_addr, local_port_str);
|
||||
|
||||
// Setup proxy context
|
||||
struct listen_ctx listen_ctx;
|
||||
|
||||
listen_ctx.remote_num = 1;
|
||||
listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *));
|
||||
struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage));
|
||||
memset(storage, 0, sizeof(struct sockaddr_storage));
|
||||
if (get_sockaddr(remote_host, remote_port_str, storage, 1) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Setup proxy context
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
struct listen_ctx listen_ctx;
|
||||
|
||||
listen_ctx.remote_num = 1;
|
||||
listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *));
|
||||
listen_ctx.remote_addr[0] = (struct sockaddr *)storage;
|
||||
listen_ctx.timeout = timeout;
|
||||
listen_ctx.fd = listenfd;
|
||||
listen_ctx.method = m;
|
||||
listen_ctx.iface = NULL;
|
||||
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx.io);
|
||||
if (mode != UDP_ONLY) {
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port_str);
|
||||
if (listenfd < 0) {
|
||||
ERROR("bind()");
|
||||
return -1;
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1) {
|
||||
ERROR("listen()");
|
||||
return -1;
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
|
||||
// Setup UDP
|
||||
if (udprelay) {
|
||||
LOGI("udprelay enabled");
|
||||
init_udprelay(local_addr, local_port_str, listen_ctx.remote_addr[0],
|
||||
get_sockaddr_len(listen_ctx.remote_addr[0]), m,
|
||||
listen_ctx.timeout, NULL);
|
||||
listen_ctx.fd = listenfd;
|
||||
|
||||
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx.io);
|
||||
}
|
||||
|
||||
// Init connections
|
||||
cork_dllist_init(&connections);
|
||||
// Setup UDP
|
||||
if (mode != TCP_ONLY) {
|
||||
LOGI("udprelay enabled");
|
||||
struct sockaddr *addr = (struct sockaddr *)storage;
|
||||
init_udprelay(local_addr, local_port_str, addr,
|
||||
get_sockaddr_len(addr), m, timeout, NULL);
|
||||
}
|
||||
|
||||
LOGI("listening at %s:%s", local_addr, local_port_str);
|
||||
|
||||
if (mode != UDP_ONLY) {
|
||||
// Init connections
|
||||
cork_dllist_init(&connections);
|
||||
}
|
||||
|
||||
// Enter the loop
|
||||
ev_run(loop, 0);
|
||||
@@ -1244,14 +1266,17 @@ int start_ss_local_server(profile_t profile)
|
||||
}
|
||||
|
||||
// Clean up
|
||||
free_connections(loop);
|
||||
if (udprelay) {
|
||||
if (mode != TCP_ONLY) {
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
if (mode != UDP_ONLY) {
|
||||
ev_io_stop(loop, &listen_ctx.io);
|
||||
free_connections(loop);
|
||||
close(listen_ctx.fd);
|
||||
}
|
||||
|
||||
free(listen_ctx.remote_addr);
|
||||
close(listen_ctx.fd);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_cleanup();
|
||||
|
||||
+28
-19
@@ -81,7 +81,8 @@ static void free_server(struct server *server);
|
||||
static void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
int verbose = 0;
|
||||
int udprelay = 0;
|
||||
|
||||
static int mode = TCP_ONLY;
|
||||
|
||||
int getdestaddr(int fd, struct sockaddr_storage *destaddr)
|
||||
{
|
||||
@@ -613,7 +614,7 @@ int main(int argc, char **argv)
|
||||
|
||||
opterr = 0;
|
||||
|
||||
while ((c = getopt(argc, argv, "f:s:p:l:k:t:m:c:b:a:vu")) != -1) {
|
||||
while ((c = getopt(argc, argv, "f:s:p:l:k:t:m:c:b:a:uUv")) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
if (remote_num < MAX_REMOTE_NUM) {
|
||||
@@ -650,7 +651,10 @@ int main(int argc, char **argv)
|
||||
user = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
udprelay = 1;
|
||||
mode = TCP_AND_UDP;
|
||||
break;
|
||||
case 'U':
|
||||
mode = UDP_ONLY;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
@@ -724,18 +728,6 @@ int main(int argc, char **argv)
|
||||
LOGI("initialize ciphers... %s", method);
|
||||
int m = enc_init(password, method);
|
||||
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error");
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1) {
|
||||
FATAL("listen() error");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
LOGI("listening at %s:%s", local_addr, local_port);
|
||||
|
||||
// Setup proxy context
|
||||
struct listen_ctx listen_ctx;
|
||||
listen_ctx.remote_num = remote_num;
|
||||
@@ -752,20 +744,37 @@ int main(int argc, char **argv)
|
||||
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;
|
||||
}
|
||||
listen_ctx.timeout = atoi(timeout);
|
||||
listen_ctx.fd = listenfd;
|
||||
listen_ctx.method = m;
|
||||
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx.io);
|
||||
|
||||
if (mode != UDP_ONLY) {
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error");
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1) {
|
||||
FATAL("listen() error");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
|
||||
listen_ctx.fd = listenfd;
|
||||
|
||||
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx.io);
|
||||
}
|
||||
|
||||
// Setup UDP
|
||||
if (udprelay) {
|
||||
if (mode != TCP_ONLY) {
|
||||
LOGI("udprelay enabled");
|
||||
init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0],
|
||||
get_sockaddr_len(listen_ctx.remote_addr[0]), m, listen_ctx.timeout, NULL);
|
||||
}
|
||||
|
||||
LOGI("listening at %s:%s", local_addr, local_port);
|
||||
|
||||
// setuid
|
||||
if (user != NULL) {
|
||||
run_as(user);
|
||||
|
||||
+43
-32
@@ -99,9 +99,11 @@ static void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
static void server_resolve_cb(struct sockaddr *addr, void *data);
|
||||
|
||||
int acl = 0;
|
||||
int verbose = 0;
|
||||
int udprelay = 0;
|
||||
|
||||
static int acl = 0;
|
||||
static int mode = TCP_ONLY;
|
||||
|
||||
static int fast_open = 0;
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
static int nofile = 0;
|
||||
@@ -1100,7 +1102,7 @@ int main(int argc, char **argv)
|
||||
|
||||
USE_TTY();
|
||||
|
||||
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:i:d:a:uv",
|
||||
while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:c:i:d:a:uUv",
|
||||
long_options, &option_index)) != -1) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
@@ -1147,7 +1149,10 @@ int main(int argc, char **argv)
|
||||
user = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
udprelay = 1;
|
||||
mode = TCP_AND_UDP;
|
||||
break;
|
||||
case 'U':
|
||||
mode = UDP_ONLY;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
@@ -1288,39 +1293,41 @@ int main(int argc, char **argv)
|
||||
int index = --server_num;
|
||||
const char * host = server_host[index];
|
||||
|
||||
// Bind to port
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(host, server_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error");
|
||||
if (mode != UDP_ONLY) {
|
||||
// Bind to port
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(host, server_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error");
|
||||
}
|
||||
if (listen(listenfd, SSMAXCONN) == -1) {
|
||||
FATAL("listen() error");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
struct listen_ctx *listen_ctx = &listen_ctx_list[index];
|
||||
|
||||
// Setup proxy context
|
||||
listen_ctx->timeout = atoi(timeout);
|
||||
listen_ctx->fd = listenfd;
|
||||
listen_ctx->method = m;
|
||||
listen_ctx->iface = iface;
|
||||
listen_ctx->loop = loop;
|
||||
|
||||
ev_io_init(&listen_ctx->io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx->io);
|
||||
}
|
||||
if (listen(listenfd, SSMAXCONN) == -1) {
|
||||
FATAL("listen() error");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
LOGI("listening at %s:%s", host ? host : "*", server_port);
|
||||
|
||||
struct listen_ctx *listen_ctx = &listen_ctx_list[index];
|
||||
|
||||
// Setup proxy context
|
||||
listen_ctx->timeout = atoi(timeout);
|
||||
listen_ctx->fd = listenfd;
|
||||
listen_ctx->method = m;
|
||||
listen_ctx->iface = iface;
|
||||
listen_ctx->loop = loop;
|
||||
|
||||
ev_io_init(&listen_ctx->io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx->io);
|
||||
|
||||
// Setup UDP
|
||||
if (udprelay) {
|
||||
if (mode != TCP_ONLY) {
|
||||
init_udprelay(server_host[index], server_port, m, atoi(timeout),
|
||||
iface);
|
||||
}
|
||||
|
||||
LOGI("listening at %s:%s", host ? host : "*", server_port);
|
||||
|
||||
}
|
||||
|
||||
if (udprelay) {
|
||||
if (mode != TCP_ONLY) {
|
||||
LOGI("udprelay enabled");
|
||||
}
|
||||
|
||||
@@ -1342,13 +1349,17 @@ int main(int argc, char **argv)
|
||||
// Clean up
|
||||
for (int i = 0; i <= server_num; i++) {
|
||||
struct listen_ctx *listen_ctx = &listen_ctx_list[i];
|
||||
ev_io_stop(loop, &listen_ctx->io);
|
||||
close(listen_ctx->fd);
|
||||
if (mode != UDP_ONLY) {
|
||||
ev_io_stop(loop, &listen_ctx->io);
|
||||
close(listen_ctx->fd);
|
||||
}
|
||||
}
|
||||
|
||||
free_connections(loop);
|
||||
if (mode != UDP_ONLY) {
|
||||
free_connections(loop);
|
||||
}
|
||||
|
||||
if (udprelay) {
|
||||
if (mode != TCP_ONLY) {
|
||||
free_udprelay();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ typedef struct {
|
||||
char *acl; // file path to acl
|
||||
char *log; // file path to log
|
||||
int fast_open; // enable tcp fast open
|
||||
int udp_relay; // enable udp relay
|
||||
int mode; // enable udp relay
|
||||
int verbose; // verbose mode
|
||||
} profile_t;
|
||||
|
||||
@@ -53,7 +53,7 @@ typedef struct {
|
||||
.acl = NULL,
|
||||
.log = NULL,
|
||||
.fast_open = 0,
|
||||
.udp_relay = 0,
|
||||
.mode = 0,
|
||||
.verbose = 0
|
||||
};
|
||||
*/
|
||||
|
||||
+27
-19
@@ -86,7 +86,7 @@ static void free_server(struct server *server);
|
||||
static void close_and_free_server(EV_P_ struct server *server);
|
||||
|
||||
int verbose = 0;
|
||||
int udprelay = 0;
|
||||
static int mode = TCP_ONLY;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
static int setnonblocking(int fd)
|
||||
@@ -654,7 +654,7 @@ int main(int argc, char **argv)
|
||||
|
||||
USE_TTY();
|
||||
|
||||
while ((c = getopt(argc, argv, "f:s:p:l:k:t:m:i:c:b:L:a:uv")) != -1) {
|
||||
while ((c = getopt(argc, argv, "f:s:p:l:k:t:m:i:c:b:L:a:uUv")) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
if (remote_num < MAX_REMOTE_NUM) {
|
||||
@@ -691,7 +691,10 @@ int main(int argc, char **argv)
|
||||
local_addr = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
udprelay = 1;
|
||||
mode = TCP_AND_UDP;
|
||||
break;
|
||||
case 'U':
|
||||
mode = UDP_ONLY;
|
||||
break;
|
||||
case 'L':
|
||||
tunnel_addr_str = optarg;
|
||||
@@ -782,18 +785,6 @@ int main(int argc, char **argv)
|
||||
LOGI("initialize ciphers... %s", method);
|
||||
int m = enc_init(password, method);
|
||||
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error:");
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1) {
|
||||
FATAL("listen() error:");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
LOGI("listening at %s:%s", local_addr, local_port);
|
||||
|
||||
// Setup proxy context
|
||||
struct listen_ctx listen_ctx;
|
||||
listen_ctx.tunnel_addr = tunnel_addr;
|
||||
@@ -811,22 +802,39 @@ int main(int argc, char **argv)
|
||||
listen_ctx.remote_addr[i] = (struct sockaddr *)storage;
|
||||
}
|
||||
listen_ctx.timeout = atoi(timeout);
|
||||
listen_ctx.fd = listenfd;
|
||||
listen_ctx.iface = iface;
|
||||
listen_ctx.method = m;
|
||||
|
||||
struct ev_loop *loop = EV_DEFAULT;
|
||||
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx.io);
|
||||
|
||||
if (mode != UDP_ONLY) {
|
||||
// Setup socket
|
||||
int listenfd;
|
||||
listenfd = create_and_bind(local_addr, local_port);
|
||||
if (listenfd < 0) {
|
||||
FATAL("bind() error:");
|
||||
}
|
||||
if (listen(listenfd, SOMAXCONN) == -1) {
|
||||
FATAL("listen() error:");
|
||||
}
|
||||
setnonblocking(listenfd);
|
||||
|
||||
listen_ctx.fd = listenfd;
|
||||
|
||||
ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ);
|
||||
ev_io_start(loop, &listen_ctx.io);
|
||||
}
|
||||
|
||||
// Setup UDP
|
||||
if (udprelay) {
|
||||
if (mode != TCP_ONLY) {
|
||||
LOGI("udprelay enabled");
|
||||
init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0],
|
||||
get_sockaddr_len(listen_ctx.remote_addr[0]),
|
||||
tunnel_addr, m, listen_ctx.timeout, iface);
|
||||
}
|
||||
|
||||
LOGI("listening at %s:%s", local_addr, local_port);
|
||||
|
||||
// setuid
|
||||
if (user != NULL) {
|
||||
run_as(user);
|
||||
|
||||
+6
-1
@@ -238,7 +238,12 @@ void usage()
|
||||
" not available in server mode\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
" [-u] enable udprelay mode,\n");
|
||||
" [-u] enable UDP relay,\n");
|
||||
printf(
|
||||
" TPROXY is required in redir mode\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
" [-U] enable UDP relay and disable TCP relay,\n");
|
||||
printf(
|
||||
" TPROXY is required in redir mode\n");
|
||||
printf("\n");
|
||||
|
||||
Reference in New Issue
Block a user