diff --git a/src/udprelay.c b/src/udprelay.c index 458c5abd..ddfc17f4 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -61,11 +61,11 @@ int setinterface(int socket_fd, const char* interface_name) int create_and_bind(const char *host, const char *port) { struct addrinfo hints; struct addrinfo *result, *rp; - int s, listen_sock; + int s, server_sock; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ - hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ + hints.ai_socktype = SOCK_DGRAM; /* We want a UDP socket */ s = getaddrinfo(host, port, &hints, &result); if (s != 0) { @@ -74,18 +74,17 @@ int create_and_bind(const char *host, const char *port) { } for (rp = result; rp != NULL; rp = rp->ai_next) { - listen_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (listen_sock == -1) + server_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (server_sock == -1) continue; int opt = 1; - setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); + setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); #ifdef SO_NOSIGPIPE - setsockopt(listen_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); + setsockopt(server_sock, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); #endif - s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); + s = bind(server_sock, rp->ai_addr, rp->ai_addrlen); if (s == 0) { /* We managed to bind successfully! */ break; @@ -93,7 +92,7 @@ int create_and_bind(const char *host, const char *port) { ERROR("bind"); } - close(listen_sock); + close(server_sock); } if (rp == NULL) { @@ -103,7 +102,7 @@ int create_and_bind(const char *host, const char *port) { freeaddrinfo(result); - return listen_sock; + return server_sock; } struct client *connect_to_client(struct addrinfo *res, const char *iface) { @@ -288,7 +287,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - query = asyncns_getaddrinfo(server->shadowsocks_ctx->asyncns, + query = asyncns_getaddrinfo(server->server_ctx->asyncns, host, port, &hints); if (query == NULL) { @@ -385,10 +384,8 @@ static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents) { static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) { int err; struct addrinfo *result, *rp; - struct server_ctx *server_ctx = (struct server_ctx *) (((void*)watcher) - - sizeof(ev_io)); - struct server *server = server_ctx->server; - asyncns_t *asyncns = server->shadowsocks_ctx->asyncns; + struct server *server = (struct server *) ((void*)watcher); + asyncns_t *asyncns = server->asyncns; asyncns_query_t *query = server->query; if (asyncns == NULL || query == NULL) { @@ -428,7 +425,7 @@ static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) { rp = result; } - struct client *client = connect_to_client(rp, server->shadowsocks_ctx->iface); + struct client *client = connect_to_client(rp, server->server_ctx->iface); if (client == NULL) { LOGE("connect error."); @@ -656,26 +653,16 @@ void close_and_free_client(EV_P_ struct client *client) { } } -struct server* new_server(int fd, struct shadowsocks_ctx *listener) { +struct server* new_server(int fd, struct server_ctx *ctx) { server_conn++; struct server *server; server = malloc(sizeof(struct server)); server->buf = malloc(BUF_SIZE); - server->recv_ctx = malloc(sizeof(struct server_ctx)); - server->send_ctx = malloc(sizeof(struct server_ctx)); - server->fd = fd; - ev_io_init(&server->recv_ctx->io, server_recv_cb, fd, EV_READ); - ev_io_init(&server->send_ctx->io, server_send_cb, fd, EV_WRITE); ev_timer_init(&server->send_ctx->watcher, server_resolve_cb, 0.2, 0.5); - ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, listener->timeout, listener->timeout * 5); - server->recv_ctx->server = server; - server->recv_ctx->connected = 0; - server->send_ctx->server = server; - server->send_ctx->connected = 0; - server->stage = 0; + ev_timer_init(&server->recv_ctx->watcher, server_timeout_cb, ctx->timeout, ctx->timeout * 5); server->query = NULL; - server->shadowsocks_ctx = listener; - if (listener->method) { + server->server_ctx = ctx; + if (ctx->method) { server->e_ctx = malloc(sizeof(struct enc_ctx)); server->d_ctx = malloc(sizeof(struct enc_ctx)); enc_ctx_init(listener->method, server->e_ctx, 1); @@ -727,8 +714,8 @@ void close_and_free_server(EV_P_ struct server *server) { } } -static void accept_cb (EV_P_ ev_io *w, int revents) { - struct shadowsocks_ctx *listener = (struct shadowsocks_ctx *)w; +static void server_cb (EV_P_ ev_io *w, int revents) { + struct server_ctx *listener = (struct server_ctx *)w; int serverfd = accept(listener->fd, NULL, NULL); if (serverfd == -1) { ERROR("accept"); @@ -737,7 +724,6 @@ static void accept_cb (EV_P_ ev_io *w, int revents) { setnonblocking(serverfd); int opt = 1; - setsockopt(serverfd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); #ifdef SO_NOSIGPIPE setsockopt(serverfd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt)); #endif @@ -751,10 +737,8 @@ static void accept_cb (EV_P_ ev_io *w, int revents) { ev_timer_start(EV_A_ &server->recv_ctx->watcher); } -int udprelay(char *server_host, int server_num, char *server_port, - int method, int timeout, char *iface) { - - int i, c; +int udprelay(const char *server_host, int server_num, const char *server_port, + int method, int timeout, const char *iface) { // inilitialize ev loop struct ev_loop *loop = EV_DEFAULT; @@ -766,24 +750,21 @@ int udprelay(char *server_host, int server_num, char *server_port, // Bind to port int serverfd = create_and_bind(host, server_port); - if (listenfd < 0) { - FATAL("bind() error.."); + if (serverfd < 0) { + FATAL("udprelay bind() error.."); } setnonblocking(serverfd); - LOGD("server listening at port %s.", server_port); // Setup proxy context - struct shadowsocks_ctx shadowsocks_ctx; - shadowsocks_ctx.timeout = timeout; - shadowsocks_ctx.method = method; - shadowsocks_ctx.iface = iface; - - struct server_ctx server_ctx; - server_ctx.asyncns = asyncns; - server_ctx.shadowsocks_ctx = - - ev_io_init (&shadowsocks_ctx.io, accept_cb, listenfd, EV_READ); - ev_io_start (loop, &shadowsocks_ctx.io); + struct server_ctx *server_ctx = malloc(sizeof(struct server_ctx)); + server_ctx->fd = serverfd; + server_ctx->timeout = timeout; + server_ctx->method = method; + server_ctx->iface = iface; + server_ctx->asyncns = asyncns; + + ev_io_init (&server_ctx.io, server_recv_cb, serverfd, EV_READ); + ev_io_start (loop, &server_ctx.io); } // start ev loop diff --git a/src/udprelay.h b/src/udprelay.h index ccbb4c2f..b6e2f154 100644 --- a/src/udprelay.h +++ b/src/udprelay.h @@ -8,24 +8,26 @@ #include "jconf.h" #include "asyncns.h" +#define MAX_UDP_PACKET_SIZE (64 * 1024) + struct server_ctx { ev_io io; - ev_timer watcher; - int connected; - struct server *server; + asyncns_t *asyncns; + int fd; + int method; + int timeout; + char *iface; }; struct server { - int fd; + ev_timer watcher; + asyncns_query_t *query; int buf_len; int buf_idx; - int timeout; - int method; - char *iface; char *buf; // server send from, client recv into - struct server_ctx *recv_ctx; - struct server_ctx *send_ctx; - asyncns_query_t *query; + struct enc_ctx *e_ctx; + struct enc_ctx *d_ctx; + struct server_ctx *server_ctx; struct client *client; }; @@ -39,8 +41,6 @@ struct client { int buf_len; int buf_idx; char *buf; // client send from, server recv into - struct enc_ctx *e_ctx; - struct enc_ctx *d_ctx; struct client_ctx *recv_ctx; struct client_ctx *send_ctx; struct server *server;