diff --git a/src/local.c b/src/local.c index 34436cf6..1722775c 100644 --- a/src/local.c +++ b/src/local.c @@ -105,6 +105,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { if (r == 0) { // connection closed remote->buf_len = 0; + remote->buf_idx = 0; close_and_free_server(EV_A_ server); if (remote != NULL) { ev_io_start(EV_A_ &remote->send_ctx->io); @@ -142,7 +143,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { } } else if(s < r) { remote->buf_len = r - s; - bufcpy(remote->buf, remote->buf + s, remote->buf_len); + remote->buf_idx = s; ev_io_stop(EV_A_ &server_recv_ctx->io); ev_io_start(EV_A_ &remote->send_ctx->io); return; @@ -180,14 +181,14 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { if (request->atyp == 1) { // IP V4 size_t in_addr_len = sizeof(struct in_addr); - bufcpy(addr_to_send + addr_len, remote->buf + 4, in_addr_len + 2); + memcpy(addr_to_send + addr_len, remote->buf + 4, in_addr_len + 2); addr_len += in_addr_len + 2; } else if (request->atyp == 3) { // Domain name uint8_t name_len = *(uint8_t *)(remote->buf + 4); addr_to_send[addr_len++] = name_len; - bufcpy(addr_to_send + addr_len, remote->buf + 4 + 1, name_len); + memcpy(addr_to_send + addr_len, remote->buf + 4 + 1, name_len); addr_len += name_len; // get port @@ -197,7 +198,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { } else if (request->atyp == 4) { // IP V6 size_t in6_addr_len = sizeof(struct in6_addr); - bufcpy(addr_to_send + addr_len, remote->buf + 4, in6_addr_len + 2); + memcpy(addr_to_send + addr_len, remote->buf + 4, in6_addr_len + 2); addr_len += in6_addr_len + 2; } else { @@ -226,7 +227,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { struct in_addr sin_addr; inet_aton("0.0.0.0", &sin_addr); - bufcpy(server->buf, &response, sizeof(struct socks5_response)); + memcpy(server->buf, &response, sizeof(struct socks5_response)); memset(server->buf + sizeof(struct socks5_response), 0, sizeof(struct in_addr) + sizeof(uint16_t)); int reply_size = sizeof(struct socks5_response) + sizeof(struct in_addr) + sizeof(uint16_t); @@ -254,7 +255,7 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { return; } else { // has data to send - ssize_t s = send(server->fd, server->buf, + ssize_t s = send(server->fd, server->buf + server->buf_idx, server->buf_len, 0); if (s < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -266,10 +267,12 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { } else if (s < server->buf_len) { // partly sent, move memory, wait for the next time to send server->buf_len -= s; - bufcpy(server->buf, server->buf + s, server->buf_len); + server->buf_idx += s; return; } else { // all sent out, wait for reading + server->buf_len = 0; + server->buf_idx = 0; ev_io_stop(EV_A_ &server_send_ctx->io); if (remote != NULL) { ev_io_start(EV_A_ &remote->recv_ctx->io); @@ -315,6 +318,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { if (r == 0) { // connection closed server->buf_len = 0; + server->buf_idx = 0; close_and_free_remote(EV_A_ remote); if (server != NULL) { ev_io_start(EV_A_ &server->send_ctx->io); @@ -351,7 +355,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { } } else if (s < r) { server->buf_len = r - s; - bufcpy(server->buf, server->buf + s, server->buf_len); + server->buf_idx = s; ev_io_stop(EV_A_ &remote_recv_ctx->io); ev_io_start(EV_A_ &server->send_ctx->io); return; @@ -389,7 +393,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { return; } else { // has data to send - ssize_t s = send(remote->fd, remote->buf, + ssize_t s = send(remote->fd, remote->buf + remote->buf_idx, remote->buf_len, 0); if (s < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -402,10 +406,12 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { } else if (s < remote->buf_len) { // partly sent, move memory, wait for the next time to send remote->buf_len -= s; - bufcpy(remote->buf, remote->buf + s, remote->buf_len); + remote->buf_idx += s; return; } else { // all sent out, wait for reading + remote->buf_len = 0; + remote->buf_idx = 0; ev_io_stop(EV_A_ &remote_send_ctx->io); if (server != NULL) { ev_io_start(EV_A_ &server->recv_ctx->io); @@ -434,6 +440,7 @@ struct remote* new_remote(int fd, int timeout) { remote->send_ctx->remote = remote; remote->send_ctx->connected = 0; remote->buf_len = 0; + remote->buf_idx = 0; return remote; } @@ -481,6 +488,7 @@ struct server* new_server(int fd) { server->d_ctx = NULL; } server->buf_len = 0; + server->buf_idx = 0; return server; } diff --git a/src/local.h b/src/local.h index 1d445013..2579a416 100644 --- a/src/local.h +++ b/src/local.h @@ -6,47 +6,49 @@ #include "jconf.h" struct listen_ctx { - ev_io io; + ev_io io; char **remote_host; int remote_num; char *remote_port; int timeout; - int fd; - struct sockaddr sock; + int fd; + struct sockaddr sock; }; struct server_ctx { - ev_io io; - int connected; - struct server *server; + ev_io io; + int connected; + struct server *server; }; struct server { - int fd; - char buf[BUF_SIZE]; // server send from, remote recv into + int fd; + char buf[BUF_SIZE]; // server send from, remote recv into char stage; - int buf_len; + int buf_len; + int buf_idx; struct rc4_state *e_ctx; struct rc4_state *d_ctx; - struct server_ctx *recv_ctx; - struct server_ctx *send_ctx; - struct remote *remote; + struct server_ctx *recv_ctx; + struct server_ctx *send_ctx; + struct remote *remote; }; struct remote_ctx { - ev_io io; + ev_io io; ev_timer watcher; - int connected; - struct remote *remote; + int connected; + struct remote *remote; }; struct remote { - int fd; - char buf[BUF_SIZE]; // remote send from, server recv into - int buf_len; - struct remote_ctx *recv_ctx; - struct remote_ctx *send_ctx; - struct server *server; + int fd; + char buf[BUF_SIZE]; // remote send from, server recv into + int buf_len; + int buf_idx; + struct remote_ctx *recv_ctx; + struct remote_ctx *send_ctx; + struct server *server; }; diff --git a/src/redir.c b/src/redir.c index 0d89d6db..30eaa221 100644 --- a/src/redir.c +++ b/src/redir.c @@ -116,6 +116,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { if (r == 0) { // connection closed remote->buf_len = 0; + remote->buf_idx = 0; close_and_free_server(EV_A_ server); if (remote != NULL) { ev_io_start(EV_A_ &remote->send_ctx->io); @@ -152,7 +153,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { } } else if(s < r) { remote->buf_len = r - s; - bufcpy(remote->buf, remote->buf + s, remote->buf_len); + remote->buf_idx = s; ev_io_stop(EV_A_ &server_recv_ctx->io); ev_io_start(EV_A_ &remote->send_ctx->io); return; @@ -171,7 +172,7 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { return; } else { // has data to send - ssize_t s = send(server->fd, server->buf, + ssize_t s = send(server->fd, server->buf + server->buf_idx, server->buf_len, 0); if (s < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -183,10 +184,12 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { } else if (s < server->buf_len) { // partly sent, move memory, wait for the next time to send server->buf_len -= s; - bufcpy(server->buf, server->buf + s, server->buf_len); + server->buf_idx += s; return; } else { // all sent out, wait for reading + server->buf_len = 0; + server->buf_idx = 0; ev_io_stop(EV_A_ &server_send_ctx->io); if (remote != NULL) { ev_io_start(EV_A_ &remote->recv_ctx->io); @@ -232,6 +235,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { if (r == 0) { // connection closed server->buf_len = 0; + server->buf_idx = 0; close_and_free_remote(EV_A_ remote); if (server != NULL) { ev_io_start(EV_A_ &server->send_ctx->io); @@ -268,7 +272,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { } } else if (s < r) { server->buf_len = r - s; - bufcpy(server->buf, server->buf + s, server->buf_len); + server->buf_idx = s; ev_io_stop(EV_A_ &remote_recv_ctx->io); ev_io_start(EV_A_ &server->send_ctx->io); return; @@ -297,9 +301,9 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { // handle IP V4 only size_t in_addr_len = sizeof(struct in_addr); - bufcpy(addr_to_send + addr_len, &server->destaddr.sin_addr, in_addr_len); + memcpy(addr_to_send + addr_len, &server->destaddr.sin_addr, in_addr_len); addr_len += in_addr_len; - bufcpy(addr_to_send + addr_len, &server->destaddr.sin_port, 2); + memcpy(addr_to_send + addr_len, &server->destaddr.sin_port, 2); addr_len += 2; encrypt_ctx(addr_to_send, addr_len, server->e_ctx); @@ -329,7 +333,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { return; } else { // has data to send - ssize_t s = send(remote->fd, remote->buf, + ssize_t s = send(remote->fd, remote->buf + remote->buf_idx, remote->buf_len, 0); if (s < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -342,10 +346,12 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { } else if (s < remote->buf_len) { // partly sent, move memory, wait for the next time to send remote->buf_len -= s; - bufcpy(remote->buf, remote->buf + s, remote->buf_len); + remote->buf_idx += s; return; } else { // all sent out, wait for reading + remote->buf_len = 0; + remote->buf_idx = 0; ev_io_stop(EV_A_ &remote_send_ctx->io); if (server != NULL) { ev_io_start(EV_A_ &server->recv_ctx->io); @@ -374,6 +380,7 @@ struct remote* new_remote(int fd, int timeout) { remote->send_ctx->remote = remote; remote->send_ctx->connected = 0; remote->buf_len = 0; + remote->buf_idx = 0; return remote; } @@ -420,6 +427,7 @@ struct server* new_server(int fd) { server->d_ctx = NULL; } server->buf_len = 0; + server->buf_idx = 0; return server; } diff --git a/src/redir.h b/src/redir.h index 6013fd2e..df953d73 100644 --- a/src/redir.h +++ b/src/redir.h @@ -6,47 +6,49 @@ #include "jconf.h" struct listen_ctx { - ev_io io; + ev_io io; char **remote_host; int remote_num; char *remote_port; int timeout; - int fd; - struct sockaddr sock; + int fd; + struct sockaddr sock; }; struct server_ctx { - ev_io io; - int connected; - struct server *server; + ev_io io; + int connected; + struct server *server; }; struct server { - int fd; - char buf[BUF_SIZE]; // server send from, remote recv into - int buf_len; + int fd; + char buf[BUF_SIZE]; // server send from, remote recv into + int buf_len; + int buf_idx; struct sockaddr_in destaddr; struct rc4_state *e_ctx; struct rc4_state *d_ctx; - struct server_ctx *recv_ctx; - struct server_ctx *send_ctx; - struct remote *remote; + struct server_ctx *recv_ctx; + struct server_ctx *send_ctx; + struct remote *remote; }; struct remote_ctx { - ev_io io; + ev_io io; ev_timer watcher; - int connected; - struct remote *remote; + int connected; + struct remote *remote; }; struct remote { - int fd; - char buf[BUF_SIZE]; // remote send from, server recv into - int buf_len; - struct remote_ctx *recv_ctx; - struct remote_ctx *send_ctx; - struct server *server; + int fd; + char buf[BUF_SIZE]; // remote send from, server recv into + int buf_len; + int buf_idx; + struct remote_ctx *recv_ctx; + struct remote_ctx *send_ctx; + struct server *server; }; diff --git a/src/server.c b/src/server.c index c22bf961..c5e17f0c 100644 --- a/src/server.c +++ b/src/server.c @@ -172,7 +172,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { } } else if (s < r) { remote->buf_len = r - s; - bufcpy(remote->buf, remote->buf + s, remote->buf_len); + remote->buf_idx = r; ev_io_stop(EV_A_ &server_recv_ctx->io); ev_io_start(EV_A_ &remote->send_ctx->io); } @@ -202,14 +202,18 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { size_t in_addr_len = sizeof(struct in_addr); if (r > in_addr_len) { char *a = inet_ntoa(*(struct in_addr*)(server->buf + offset)); - bufcpy(host, a, strlen(a)); + memcpy(host, a, strlen(a)); offset += in_addr_len; } } else if (atyp == 3) { // Domain name uint8_t name_len = *(uint8_t *)(server->buf + offset); - bufcpy(host, server->buf + offset + 1, name_len); + if (name_len >= 255) { + close_and_free_server(EV_A_ server); + return; + } + memcpy(host, server->buf + offset + 1, name_len); offset += name_len + 1; } else if (atyp == 4) { @@ -219,7 +223,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { char a[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, (const void*)(server->buf + offset), a, sizeof(a)); - bufcpy(host, a, strlen(a)); + memcpy(host, a, strlen(a)); offset += in6_addr_len; } @@ -257,7 +261,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { // XXX: should handel buffer carefully if (r > offset) { server->buf_len = r - offset; - bufcpy(server->buf, server->buf + offset, server->buf_len); + server->buf_idx = offset; } server->stage = 4; @@ -293,7 +297,7 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { return; } else { // has data to send - ssize_t s = send(server->fd, server->buf, + ssize_t s = send(server->fd, server->buf + server->buf_idx, server->buf_len, 0); if (s < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -305,11 +309,12 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { } else if (s < server->buf_len) { // partly sent, move memory, wait for the next time to send server->buf_len -= s; - bufcpy(server->buf, server->buf + s, server->buf_len); + server->buf_idx += s; return; } else { // all sent out, wait for reading server->buf_len = 0; + server->buf_idx = 0; ev_io_stop(EV_A_ &server_send_ctx->io); if (remote != NULL) { ev_io_start(EV_A_ &remote->recv_ctx->io); @@ -395,8 +400,10 @@ static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) { // XXX: should handel buffer carefully if (server->buf_len > 0) { - bufcpy(remote->buf, server->buf, server->buf_len); + memcpy(remote->buf, server->buf, server->buf_len); remote->buf_len = server->buf_len; + remote->buf_idx = 0; + server->buf_idx = 0; server->buf_len = 0; } @@ -472,7 +479,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { return; } else if (s < r) { server->buf_len = r - s; - bufcpy(server->buf, server->buf + s, server->buf_len); + server->buf_idx = r; ev_io_stop(EV_A_ &remote_recv_ctx->io); ev_io_start(EV_A_ &server->send_ctx->io); return; @@ -529,7 +536,7 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { return; } else { // has data to send - ssize_t s = send(remote->fd, remote->buf, + ssize_t s = send(remote->fd, remote->buf + remote->buf_idx, remote->buf_len, 0); if (s == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -542,11 +549,12 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { } else if (s < remote->buf_len) { // partly sent, move memory, wait for the next time to send remote->buf_len -= s; - bufcpy(remote->buf, remote->buf + s, remote->buf_len); + remote->buf_idx += s; return; } else { // all sent out, wait for reading remote->buf_len = 0; + remote->buf_idx = 0; ev_io_stop(EV_A_ &remote_send_ctx->io); if (server != NULL) { ev_io_start(EV_A_ &server->recv_ctx->io); @@ -579,6 +587,7 @@ struct remote* new_remote(int fd, int timeout) { remote->send_ctx->remote = remote; remote->send_ctx->connected = 0; remote->buf_len = 0; + remote->buf_idx = 0; remote->server = NULL; return remote; } @@ -635,6 +644,7 @@ struct server* new_server(int fd, struct listen_ctx *listener) { server->d_ctx = NULL; } server->buf_len = 0; + server->buf_idx = 0; server->remote = NULL; return server; } diff --git a/src/server.h b/src/server.h index 76a8814b..296c7b30 100644 --- a/src/server.h +++ b/src/server.h @@ -9,48 +9,50 @@ #include "asyncns.h" struct listen_ctx { - ev_io io; - int fd; + ev_io io; + int fd; int timeout; asyncns_t *asyncns; - struct sockaddr sock; + struct sockaddr sock; }; struct server_ctx { - ev_io io; + ev_io io; ev_timer watcher; - int connected; - struct server *server; + int connected; + struct server *server; }; struct server { - int fd; - char buf[BUF_SIZE]; // server send from, remote recv into + int fd; + char buf[BUF_SIZE]; // server send from, remote recv into char stage; - int buf_len; + int buf_len; + int buf_idx; struct rc4_state *e_ctx; struct rc4_state *d_ctx; - struct server_ctx *recv_ctx; - struct server_ctx *send_ctx; + struct server_ctx *recv_ctx; + struct server_ctx *send_ctx; struct listen_ctx *listen_ctx; asyncns_query_t *query; - struct remote *remote; + struct remote *remote; }; struct remote_ctx { - ev_io io; + ev_io io; ev_timer watcher; - int connected; - struct remote *remote; + int connected; + struct remote *remote; }; struct remote { - int fd; - char buf[BUF_SIZE]; // remote send from, server recv into - int buf_len; - struct remote_ctx *recv_ctx; - struct remote_ctx *send_ctx; - struct server *server; + int fd; + char buf[BUF_SIZE]; // remote send from, server recv into + int buf_len; + int buf_idx; + struct remote_ctx *recv_ctx; + struct remote_ctx *send_ctx; + struct server *server; }; diff --git a/src/utils.c b/src/utils.c index 918e1be6..1fd5a92e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -22,13 +22,6 @@ void ERROR(const char *s) { } -void bufcpy(char *dest, const char *src, size_t n) { - int i; - for (i = 0; i < n; i++) { - *dest++ = *src++; - } -} - char *itoa(int i) { /* Room for INT_DIGITS digits, - and '\0' */ static char buf[INT_DIGITS + 2]; diff --git a/src/utils.h b/src/utils.h index c5af5247..e8020bac 100644 --- a/src/utils.h +++ b/src/utils.h @@ -24,6 +24,5 @@ void ERROR(const char *s); void usage(void); void demonize(const char* path); char *itoa(int i); -void bufcpy(char *dest, const char *src, size_t n); #endif // _UTILS_H