diff --git a/Makefile.am b/Makefile.am index 5bbaa3c8..57a50de6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,2 @@ -bin_PROGRAMS = local server -local_SOURCES = encrypt.c encrypt.h local.c local.h -server_SOURCES = encrypt.c encrypt.h server.c server.h socks5.h - +bin_PROGRAMS = local +local_SOURCES = encrypt.c encrypt.h local.c local.h socks5.h diff --git a/Makefile.in b/Makefile.in index 836a0cd2..560e4bb1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -32,7 +32,7 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -bin_PROGRAMS = local$(EXEEXT) server$(EXEEXT) +bin_PROGRAMS = local$(EXEEXT) subdir = . DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ @@ -52,9 +52,6 @@ PROGRAMS = $(bin_PROGRAMS) am_local_OBJECTS = encrypt.$(OBJEXT) local.$(OBJEXT) local_OBJECTS = $(am_local_OBJECTS) local_LDADD = $(LDADD) -am_server_OBJECTS = encrypt.$(OBJEXT) server.$(OBJEXT) -server_OBJECTS = $(am_server_OBJECTS) -server_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -63,8 +60,8 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(local_SOURCES) $(server_SOURCES) -DIST_SOURCES = $(local_SOURCES) $(server_SOURCES) +SOURCES = $(local_SOURCES) +DIST_SOURCES = $(local_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -168,8 +165,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -local_SOURCES = encrypt.c encrypt.h local.c local.h -server_SOURCES = encrypt.c encrypt.h server.c server.h socks5.h +local_SOURCES = encrypt.c encrypt.h local.c local.h socks5.h all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am @@ -264,9 +260,6 @@ clean-binPROGRAMS: local$(EXEEXT): $(local_OBJECTS) $(local_DEPENDENCIES) $(EXTRA_local_DEPENDENCIES) @rm -f local$(EXEEXT) $(LINK) $(local_OBJECTS) $(local_LDADD) $(LIBS) -server$(EXEEXT): $(server_OBJECTS) $(server_DEPENDENCIES) $(EXTRA_server_DEPENDENCIES) - @rm -f server$(EXEEXT) - $(LINK) $(server_OBJECTS) $(server_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -276,7 +269,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encrypt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/local.c b/local.c index e6cbd4b6..73443551 100644 --- a/local.c +++ b/local.c @@ -17,14 +17,16 @@ #include #include #include +#include #include "local.h" +#include "socks5.h" #include "encrypt.h" #define SERVER "127.0.0.1" -#define REMOTE_PORT "8499" +#define REMOTE_PORT "8388" #define PORT "1080" -#define KEY "foobar!" +#define KEY "barfoo!" #define REPLY "HTTP/1.1 200 OK\n\nhello" @@ -58,7 +60,6 @@ int create_and_bind(char *port) { 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_flags = AI_PASSIVE; /* All interfaces */ s = getaddrinfo("0.0.0.0", port, &hints, &result); if (s != 0) { @@ -98,58 +99,167 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { struct server_ctx *server_recv_ctx = (struct server_ctx *)w; struct server *server = server_recv_ctx->server; struct remote *remote = server->remote; - if (remote == NULL) { - close_and_free_server(EV_A_ server); - return; - } + + if (remote == NULL) { + close_and_free_server(EV_A_ server); + return; + } + + char *buf = remote->buf; + int *buf_len = &remote->buf_len; + if (server->stage != 5) { + buf = server->buf; + buf_len = server->buf_len; + } + while (1) { - ssize_t r = recv(server->fd, remote->buf, BUF_SIZE, 0); + ssize_t r = recv(server->fd, buf, BUF_SIZE, 0); + if (r == 0) { // connection closed - remote->buf_len = 0; + *buf_len = 0; close_and_free_server(EV_A_ server); if (remote != NULL) { ev_io_start(EV_A_ &remote->send_ctx->io); } return; } else if(r < 0) { - perror("recv"); if (errno == EAGAIN) { // no data // continue to wait for recv break; } else { + perror("server recv"); close_and_free_server(EV_A_ server); close_and_free_remote(EV_A_ remote); return; } } - encrypt(remote->buf, r); - int w = send(remote->fd, remote->buf, r, MSG_NOSIGNAL); - if(w == -1) { - perror("send"); - if (errno == EAGAIN) { - // no data, wait for send + + // local socks5 server + if (server->stage == 5) { + encrypt(remote->buf, r); + int w = send(remote->fd, remote->buf, r, 0); + if(w == -1) { + if (errno == EAGAIN) { + // no data, wait for send + ev_io_stop(EV_A_ &server_recv_ctx->io); + ev_io_start(EV_A_ &remote->send_ctx->io); + break; + } else { + perror("send"); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + } else if(w < r) { + char *pt = remote->buf; + char *et = pt + min(w, BUF_SIZE); + while (pt < et) { + *pt = *(pt + w); + pt++; + } + remote->buf_len = r - w; ev_io_stop(EV_A_ &server_recv_ctx->io); ev_io_start(EV_A_ &remote->send_ctx->io); break; + } + } else if (server->stage == 0) { + struct method_select_response response; + response.ver = VERSION; + response.method = 0; + char *send_buf = (char *)&response; + send(server->fd, send_buf, sizeof(response), MSG_NOSIGNAL); + server->stage = 1; + return; + } else if (server->stage == 1) { + struct socks5_request *request = (struct socks5_request *)server->buf; + + if (request->cmd != 1) { + fprintf(stderr, "unsupported cmd: %d\n", request->cmd); + struct socks5_response response; + response.ver = VERSION; + response.rep = CMD_NOT_SUPPORTED; + response.rsv = 0; + response.atyp = 1; + char *send_buf = (char *)&response; + send(server->fd, send_buf, 4, MSG_NOSIGNAL); + close_and_free_server(EV_A_ server); + close_and_free_remote(EV_A_ remote); + return; + } + + char addr_to_send[256]; + unsigned char addr_len = 0; + addr_to_send[addr_len++] = request->atyp; + + // get remote addr and port + if (request->atyp == 1) { + + // IP V4 + struct in_addr *in_addr; + in_addr = (struct in_addr *)(server->buf + 4); + char* addr_buf = inet_ntoa(*in_addr); + unsigned char name_len = strlen(addr_buf); + memcpy(addr_to_send + addr_len, addr_buf, name_len); + addr_len += name_len; + + // get port + addr_to_send[addr_len++] = *(unsigned char *)(server->buf + 4 + 4); + addr_to_send[addr_len++] = *(unsigned char *)(server->buf + 4 + 4 + 1); + addr_to_send[addr_len] = 0; + + } else if (request->atyp == 3) { + // Domain name + unsigned char name_len = *(unsigned char *)(server->buf + 4); + addr_to_send[addr_len++] = name_len; + memcpy(addr_to_send + addr_len, server->buf + 4 + 1, name_len); + addr_len += name_len; + + // get port + addr_to_send[addr_len++] = *(unsigned char *)(server->buf + 4 + 1 + name_len); + addr_to_send[addr_len++] = *(unsigned char *)(server->buf + 4 + 1 + name_len + 1); + addr_to_send[addr_len] = 0; } else { + fprintf(stderr, "unsupported addrtype: %d\n", request->atyp); close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); + close_and_free_remote(EV_A_ remote); return; } - } else if(w < r) { - char *pt; - for (pt = remote->buf; pt < pt + min(w, BUF_SIZE); pt++) { - *pt = *(pt + w); + + assert(addr_len < 256); + + send_encrypt(remote->fd, addr_to_send, addr_len, 0); + + // Fake reply + struct socks5_response response; + response.ver = VERSION; + response.rep = 0; + response.rsv = 0; + response.atyp = 1; + + struct in_addr sin_addr; + inet_aton("0.0.0.0", &sin_addr); + + memcpy(server->buf, &response, 4); + memcpy(server->buf + 4, &sin_addr, sizeof(struct in_addr)); + *((unsigned short *)(server->buf + 4 + sizeof(struct in_addr))) = (unsigned short) htons(atoi(PORT)); + + int reply_size = 4 + sizeof(struct in_addr) + sizeof(unsigned short); + int r = send(server->fd, server->buf, reply_size, MSG_NOSIGNAL); + if (r < reply_size) { + fprintf(stderr, "header not complete sent\n"); + close_and_free_remote(EV_A_ remote); + close_and_free_server(EV_A_ server); + return; } - remote->buf_len = r - w; - ev_io_stop(EV_A_ &server_recv_ctx->io); - ev_io_start(EV_A_ &remote->send_ctx->io); - break; - } + + server->stage = 5; + + } } } + static void server_send_cb (EV_P_ ev_io *w, int revents) { struct server_ctx *server_send_ctx = (struct server_ctx *)w; struct server *server = server_send_ctx->server; @@ -164,8 +274,8 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { ssize_t r = send(server->fd, server->buf, server->buf_len, 0); if (r < 0) { - perror("send"); if (errno != EAGAIN) { + perror("send"); close_and_free_server(EV_A_ server); close_and_free_remote(EV_A_ remote); return; @@ -176,9 +286,11 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { // printf("r=%d\n", r); // printf("server->buf_len=%d\n", server->buf_len); // partly sent, move memory, wait for the next time to send - char *pt; - for (pt = server->buf; pt < pt + min(r, BUF_SIZE); pt++) { + char *pt = server->buf; + char *et = pt + min(r, BUF_SIZE); + while (pt < et) { *pt = *(pt + r); + pt++; } server->buf_len -= r; return; @@ -196,6 +308,7 @@ static void server_send_cb (EV_P_ ev_io *w, int revents) { } } + static void remote_recv_cb (EV_P_ ev_io *w, int revents) { struct remote_ctx *remote_recv_ctx = (struct remote_ctx *)w; struct remote *remote = remote_recv_ctx->remote; @@ -206,7 +319,8 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { } while (1) { ssize_t r = recv(remote->fd, server->buf, BUF_SIZE, 0); - // printf("after recv: r=%d\n", r); + /*printf("after recv: r=%d\n", r);*/ + if (r == 0) { // connection closed server->buf_len = 0; @@ -216,12 +330,12 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { } return; } else if(r < 0) { - perror("recv"); if (errno == EAGAIN) { // no data // continue to wait for recv break; } else { + perror("remote recv"); close_and_free_server(EV_A_ server); close_and_free_remote(EV_A_ remote); return; @@ -231,21 +345,23 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { int w = send(server->fd, server->buf, r, MSG_NOSIGNAL); // printf("after send: w=%d\n", w); if(w == -1) { - perror("send"); if (errno == EAGAIN) { // no data, wait for send ev_io_stop(EV_A_ &remote_recv_ctx->io); ev_io_start(EV_A_ &server->send_ctx->io); break; } else { + perror("send"); close_and_free_server(EV_A_ server); close_and_free_remote(EV_A_ remote); return; } } else if(w < r) { - char *pt; - for (pt = server->buf; pt < pt + min(w, BUF_SIZE); pt++) { + char *pt = server->buf; + char *et = pt + min(w, BUF_SIZE); + while (pt < et) { *pt = *(pt + w); + pt++; } server->buf_len = r - w; ev_io_stop(EV_A_ &remote_recv_ctx->io); @@ -254,11 +370,14 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { } } } + static void remote_send_cb (EV_P_ ev_io *w, int revents) { struct remote_ctx *remote_send_ctx = (struct remote_ctx *)w; struct remote *remote = remote_send_ctx->remote; struct server *server = remote->server; + if (!remote_send_ctx->connected) { + socklen_t len; struct sockaddr_storage addr; char ipstr[INET6_ADDRSTRLEN]; @@ -288,8 +407,8 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { ssize_t r = send(remote->fd, remote->buf, remote->buf_len, 0); if (r < 0) { - perror("send"); if (errno != EAGAIN) { + perror("send"); // close and free close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); @@ -299,10 +418,12 @@ static void remote_send_cb (EV_P_ ev_io *w, int revents) { } if (r < remote->buf_len) { // partly sent, move memory, wait for the next time to send - char *pt; - for (pt = remote->buf; pt < pt + min(r, BUF_SIZE); pt++) { - *pt = *(pt + r); - } + char *pt = remote->buf; + char *et = pt + min(r, BUF_SIZE); + while (pt < et) { + *pt = *(pt + r); + pt++; + } remote->buf_len -= r; return; } else { @@ -333,7 +454,6 @@ struct remote* new_remote(int fd) { remote->recv_ctx->connected = 0; remote->send_ctx->remote = remote; remote->send_ctx->connected = 0; - fprintf(stderr, "new remote\n"); return remote; } void free_remote(struct remote *remote) { @@ -344,7 +464,6 @@ void free_remote(struct remote *remote) { free(remote->recv_ctx); free(remote->send_ctx); free(remote); - fprintf(stderr, "free remote\n"); } } void close_and_free_remote(EV_P_ struct remote *remote) { @@ -367,7 +486,7 @@ struct server* new_server(int fd) { server->recv_ctx->connected = 0; server->send_ctx->server = server; server->send_ctx->connected = 0; - fprintf(stderr, "new server\n"); + server->stage = 0; return server; } void free_server(struct server *server) { @@ -378,7 +497,6 @@ void free_server(struct server *server) { free(server->recv_ctx); free(server->send_ctx); free(server); - fprintf(stderr, "free server\n"); } } void close_and_free_server(EV_P_ struct server *server) { diff --git a/local.h b/local.h index bae4a19a..f6b96007 100644 --- a/local.h +++ b/local.h @@ -2,7 +2,7 @@ #include -#define BUF_SIZE 1500 +#define BUF_SIZE 1024 struct listen_ctx { ev_io io; @@ -14,6 +14,7 @@ struct server { int fd; char buf[BUF_SIZE]; // server send from, remote recv into int buf_len; + char stage; struct server_ctx *recv_ctx; struct server_ctx *send_ctx; struct remote *remote; diff --git a/server.c b/server.c deleted file mode 100644 index 774a75c2..00000000 --- a/server.c +++ /dev/null @@ -1,593 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "encrypt.h" -#include "socks5.h" -#include "server.h" - -#define SERVER "127.0.0.1" -#define REMOTE_PORT "8499" -#define PORT "1080" -#define KEY "foobar!" - -#define REPLY "HTTP/1.1 200 OK\n\nhello" - -#define min(a,b) \ - ({ typeof (a) _a = (a); \ - typeof (b) _b = (b); \ - _a < _b ? _a : _b; }) - -#define FD_NULL 0 - -// every watcher type has its own typedef'd struct -// with the name ev_TYPE -ev_io stdin_watcher; - - -struct client_ctx { - ev_io io; - int fd; -}; - -int setnonblocking(int fd) { - int flags; - if (-1 ==(flags = fcntl(fd, F_GETFL, 0))) - flags = 0; - return fcntl(fd, F_SETFL, flags | O_NONBLOCK); -} - -int create_and_bind(char *port) { - struct addrinfo hints; - struct addrinfo *result, *rp; - int s, listen_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_flags = AI_PASSIVE; /* All interfaces */ - - s = getaddrinfo("0.0.0.0", port, &hints, &result); - if (s != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); - return -1; - } - - for (rp = result; rp != NULL; rp = rp->ai_next) { - listen_sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - int opt = 1; - setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - if (listen_sock == -1) - continue; - - s = bind(listen_sock, rp->ai_addr, rp->ai_addrlen); - if (s == 0) { - /* We managed to bind successfully! */ - break; - } else { - perror("bind"); - } - - close(listen_sock); - } - - if (rp == NULL) { - fprintf(stderr, "Could not bind\n"); - return -1; - } - - freeaddrinfo(result); - - return listen_sock; -} - -static void server_recv_cb (EV_P_ ev_io *w, int revents) { - struct server_ctx *server_recv_ctx = (struct server_ctx *)w; - struct server *server = server_recv_ctx->server; - struct remote *remote = server->remote; - if (server->stage == 5 && remote == NULL) { - close_and_free_server(EV_A_ server); - return; - } - // if remote is not created, use server->buf for both read & write - char *buf = server->buf; - int *buf_len = &server->buf_len; - if (remote != NULL) { - buf = remote->buf; - buf_len = &remote->buf_len; - } - while (1) { - ssize_t r = recv(server->fd, buf, BUF_SIZE, 0); - if (r == 0) { - // connection closed - *buf_len = 0; - close_and_free_server(EV_A_ server); - if (remote != NULL) { - ev_io_start(EV_A_ &remote->send_ctx->io); - } - return; - } else if(r < 0) { - perror("recv"); - if (errno == EAGAIN) { - // no data - // continue to wait for recv - break; - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } - decrypt(buf, r); - if (server->stage == 5) { - int w = send(remote->fd, remote->buf, r, MSG_NOSIGNAL); - if(w == -1) { - perror("send"); - if (errno == EAGAIN) { - // no data, wait for send - ev_io_stop(EV_A_ &server_recv_ctx->io); - ev_io_start(EV_A_ &remote->send_ctx->io); - break; - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } else if(w < r) { - char *pt; - for (pt = remote->buf; pt < pt + min(w, BUF_SIZE); pt++) { - *pt = *(pt + w); - } - remote->buf_len = r - w; - ev_io_stop(EV_A_ &server_recv_ctx->io); - ev_io_start(EV_A_ &remote->send_ctx->io); - break; - } - } else if (server->stage == 0) { - struct method_select_response response; - response.ver = VERSION; - response.method = 0; - char *send_buf = (char *)&response; - send_encrypt(server->fd, send_buf, sizeof(response), MSG_NOSIGNAL); - server->stage = 1; - return; - } else if (server->stage == 1) { - struct socks5_request *request = (struct socks5_request *)server->buf; - if (request->cmd != 1) { - fprintf(stderr, "unsupported cmd: %d\n", request->cmd); - struct socks5_response response; - response.ver = VERSION; - response.rep = CMD_NOT_SUPPORTED; - response.rsv = 0; - response.atyp = 1; - char *send_buf = (char *)&response; - send_encrypt(server->fd, send_buf, 4, MSG_NOSIGNAL); - close_and_free_server(EV_A_ server); - return; - } - - struct addrinfo remote_addrinfo; - struct sockaddr remote_sockaddr; - int rv; - - // get remote addr and port - if (request->atyp == 1) { - // IP V4 - struct sockaddr_in *addrp = (struct sockaddr_in *)&remote_sockaddr; - struct in_addr *in_addr; - in_addr = (struct in_addr *)(server->buf + 4); - addrp->sin_addr = *in_addr; - // get port - addrp->sin_port = *(unsigned short *)(server->buf + 4 + 4); - } else if (request->atyp == 3) { - struct addrinfo hints, *res; - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - char name_buf[256]; - unsigned char name_len = *(unsigned char *)(server->buf + 4); - memcpy(name_buf, server->buf + 4 + 1, name_len); - name_buf[name_len] = 0; // append NUL - fprintf(stderr, "connecting: %s\n", name_buf); - if ((rv = getaddrinfo(name_buf, "80", &hints, &res)) != 0) { - perror("getaddrinfo"); - // TODO send reply - close_and_free_server(EV_A_ server); - return; - } - remote_addrinfo = *res; - remote_sockaddr = *(res->ai_addr); - remote_addrinfo.ai_addr = &remote_sockaddr; - - // get port - struct sockaddr_in *addrp = (struct sockaddr_in *)&remote_sockaddr; - addrp->sin_port = *(unsigned short *)(server->buf + 4 + 1 + name_len); - freeaddrinfo(res); - } else { - fprintf(stderr, "unsupported addrtype: %d\n", request->atyp); - // TODO send reply - close_and_free_server(EV_A_ server); - return; - } - - - int sockfd; - sockfd = socket(remote_addrinfo.ai_family, remote_addrinfo.ai_socktype, - remote_addrinfo.ai_protocol); - if (sockfd < 0) { - perror("socket"); - close(sockfd); - // TODO send reply - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - setnonblocking(sockfd); - remote = new_remote(sockfd); - server->remote = remote; - remote->server = server; - connect(sockfd, remote_addrinfo.ai_addr, remote_addrinfo.ai_addrlen); - ev_io_stop(EV_A_ &server->recv_ctx->io); - ev_io_start(EV_A_ &remote->send_ctx->io); - server->stage = 4; - return; - } - } -} -static void server_send_cb (EV_P_ ev_io *w, int revents) { - struct server_ctx *server_send_ctx = (struct server_ctx *)w; - struct server *server = server_send_ctx->server; - struct remote *remote = server->remote; - if (server->buf_len == 0) { - // close and free - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } else { - // has data to send - ssize_t r = send(server->fd, server->buf, - server->buf_len, 0); - if (r < 0) { - perror("send"); - if (errno != EAGAIN) { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - return; - } - if (r < server->buf_len) { - // printf("r=%d\n", r); - // printf("server->buf_len=%d\n", server->buf_len); - // partly sent, move memory, wait for the next time to send - char *pt; - for (pt = server->buf; pt < pt + min(r, BUF_SIZE); pt++) { - *pt = *(pt + r); - } - server->buf_len -= r; - return; - } else { - // all sent out, wait for reading - ev_io_stop(EV_A_ &server_send_ctx->io); - if (remote != NULL) { - ev_io_start(EV_A_ &remote->recv_ctx->io); - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } - } - -} -static void remote_recv_cb (EV_P_ ev_io *w, int revents) { - struct remote_ctx *remote_recv_ctx = (struct remote_ctx *)w; - struct remote *remote = remote_recv_ctx->remote; - struct server *server = remote->server; - if (server == NULL) { - close_and_free_remote(EV_A_ remote); - return; - } - while (1) { - ssize_t r = recv(remote->fd, server->buf, BUF_SIZE, 0); - // printf("after recv: r=%d\n", r); - if (r == 0) { - // connection closed - server->buf_len = 0; - close_and_free_remote(EV_A_ remote); - if (server != NULL) { - ev_io_start(EV_A_ &server->send_ctx->io); - } - return; - } else if(r < 0) { - perror("recv"); - if (errno == EAGAIN) { - // no data - // continue to wait for recv - break; - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } - encrypt(server->buf, r); - int w = send(server->fd, server->buf, r, MSG_NOSIGNAL); - // printf("after send: w=%d\n", w); - if(w == -1) { - perror("send"); - if (errno == EAGAIN) { - // no data, wait for send - ev_io_stop(EV_A_ &remote_recv_ctx->io); - ev_io_start(EV_A_ &server->send_ctx->io); - break; - } else { - close_and_free_server(EV_A_ server); - close_and_free_remote(EV_A_ remote); - return; - } - } else if(w < r) { - char *pt; - for (pt = server->buf; pt < pt + min(w, BUF_SIZE); pt++) { - *pt = *(pt + w); - } - server->buf_len = r - w; - ev_io_stop(EV_A_ &remote_recv_ctx->io); - ev_io_start(EV_A_ &server->send_ctx->io); - break; - } - } -} -static void remote_send_cb (EV_P_ ev_io *w, int revents) { - struct remote_ctx *remote_send_ctx = (struct remote_ctx *)w; - struct remote *remote = remote_send_ctx->remote; - struct server *server = remote->server; - printf("remote_send_cb\n"); - if (!remote_send_ctx->connected) { - - printf("not connected\n"); - socklen_t len; - struct sockaddr_storage addr; - char ipstr[INET6_ADDRSTRLEN]; - int port; - len = sizeof addr; - int r = getpeername(remote->fd, (struct sockaddr*)&addr, &len); - if (r == 0) { - remote_send_ctx->connected = 1; - - printf("send reply\n"); - // send reply - struct sockaddr_in sockaddr; - socklen_t sockaddrlen = sizeof(sockaddr); - int rv = getsockname(remote->fd, (struct sockaddr *)&sockaddr, &sockaddrlen); - if (rv == -1) { - perror("getsockname"); - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } - struct socks5_response response; - response.ver = VERSION; - response.rep = 0; - response.rsv = 0; - response.atyp = 1; - - memcpy(server->buf, &response, 4); - memcpy(server->buf + 4, &sockaddr.sin_addr, sizeof(struct in_addr)); - memcpy(server->buf + 4 + sizeof(struct in_addr), &sockaddr.sin_port, - sizeof(struct in_addr)); - - fprintf(stderr, "send reply\n"); - int r = send_encrypt(server->fd, server->buf, 4 + sizeof(struct in_addr) + - sizeof(unsigned short), 0); - if (r < 4 + sizeof(struct in_addr) + sizeof(unsigned short)) { - fprintf(stderr, "header not complete sent\n"); - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - } - server->stage = 5; - - ev_io_stop(EV_A_ &remote_send_ctx->io); - ev_io_start(EV_A_ &server->recv_ctx->io); - ev_io_start(EV_A_ &remote->recv_ctx->io); - } else { - perror("getpeername"); - // not connected - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } - } else { - printf("is connected\n"); - if (remote->buf_len == 0) { - // close and free - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } else { - // has data to send - ssize_t r = send(remote->fd, remote->buf, - remote->buf_len, 0); - if (r < 0) { - perror("send"); - if (errno != EAGAIN) { - // close and free - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } - return; - } - if (r < remote->buf_len) { - // partly sent, move memory, wait for the next time to send - char *pt; - for (pt = remote->buf; pt < pt + min(r, BUF_SIZE); pt++) { - *pt = *(pt + r); - } - remote->buf_len -= r; - return; - } else { - // all sent out, wait for reading - ev_io_stop(EV_A_ &remote_send_ctx->io); - if (server != NULL) { - ev_io_start(EV_A_ &server->recv_ctx->io); - } else { - close_and_free_remote(EV_A_ remote); - close_and_free_server(EV_A_ server); - return; - } - } - } - - } -} - -struct remote* new_remote(int fd) { - struct remote *remote; - remote = malloc(sizeof(struct remote)); - remote->fd = fd; - remote->recv_ctx = malloc(sizeof(struct remote_ctx)); - remote->send_ctx = malloc(sizeof(struct remote_ctx)); - ev_io_init(&remote->recv_ctx->io, remote_recv_cb, fd, EV_READ); - ev_io_init(&remote->send_ctx->io, remote_send_cb, fd, EV_WRITE); - remote->recv_ctx->remote = remote; - remote->recv_ctx->connected = 0; - remote->send_ctx->remote = remote; - remote->send_ctx->connected = 0; - fprintf(stderr, "new remote\n"); - return remote; -} -void free_remote(struct remote *remote) { - if (remote != NULL) { - if (remote->server != NULL) { - remote->server->remote = NULL; - } - free(remote->recv_ctx); - free(remote->send_ctx); - free(remote); - fprintf(stderr, "free remote\n"); - } -} -void close_and_free_remote(EV_P_ struct remote *remote) { - if (remote != NULL) { - ev_io_stop(EV_A_ &remote->send_ctx->io); - ev_io_stop(EV_A_ &remote->recv_ctx->io); - if (remote->fd != FD_NULL) { - close(remote->fd); - } - free_remote(remote); - } -} -struct server* new_server(int fd) { - struct server *server; - server = malloc(sizeof(struct server)); - server->fd = fd; - server->recv_ctx = malloc(sizeof(struct server_ctx)); - server->send_ctx = malloc(sizeof(struct server_ctx)); - 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); - server->recv_ctx->server = server; - server->recv_ctx->connected = 0; - server->send_ctx->server = server; - server->send_ctx->connected = 0; - server->stage = 0; - fprintf(stderr, "new server\n"); - return server; -} -void free_server(struct server *server) { - if (server != NULL) { - if (server->remote != NULL) { - server->remote->server = NULL; - } - free(server->recv_ctx); - free(server->send_ctx); - free(server); - fprintf(stderr, "free server\n"); - } -} -void close_and_free_server(EV_P_ struct server *server) { - if (server != NULL) { - ev_io_stop(EV_A_ &server->send_ctx->io); - ev_io_stop(EV_A_ &server->recv_ctx->io); - if (server->fd != FD_NULL) { - close(server->fd); - } - free_server(server); - } -} -static void accept_cb (EV_P_ ev_io *w, int revents) -{ - struct listen_ctx *listener = (struct listen_ctx *)w; - int serverfd; - while (1) { - serverfd = accept(listener->fd, NULL, NULL); - if (serverfd == -1) { - perror("accept"); - break; - } - setnonblocking(serverfd); - struct server *server = new_server(serverfd); -// struct addrinfo hints, *res; -// int sockfd; -// memset(&hints, 0, sizeof hints); -// hints.ai_family = AF_UNSPEC; -// hints.ai_socktype = SOCK_STREAM; -// getaddrinfo(SERVER, REMOTE_PORT, &hints, &res); -// sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); -// if (sockfd < 0) { -// perror("socket"); -// close(sockfd); -// free_server(server); -// continue; -// } -// setnonblocking(sockfd); - server->remote = NULL; -// connect(sockfd, res->ai_addr, res->ai_addrlen); -// // listen to remote connected event -// ev_io_start(EV_A_ &remote->send_ctx->io); - ev_io_start(EV_A_ &server->recv_ctx->io); - break; - } -} - -int main (void) -{ - fprintf(stderr, "calculating ciphers\n"); - get_table(KEY); - - int listenfd; - listenfd = create_and_bind(REMOTE_PORT); - if (listenfd < 0) { - return 1; - } - if (listen(listenfd, SOMAXCONN) == -1) { - perror("listen() error."); - return 1; - } - fprintf(stderr, "server listening at port %s\n", REMOTE_PORT); - setnonblocking(listenfd); - struct listen_ctx listen_ctx; - listen_ctx.fd = listenfd; - struct ev_loop *loop = EV_DEFAULT; - ev_io_init (&listen_ctx.io, accept_cb, listenfd, EV_READ); - ev_io_start (loop, &listen_ctx.io); - ev_run (loop, 0); - return 0; -} - diff --git a/server.h b/server.h deleted file mode 100644 index aeda7cd4..00000000 --- a/server.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include - -#define BUF_SIZE 1500 - -struct listen_ctx { - ev_io io; - int fd; - struct sockaddr sock; -}; - -struct server { - int fd; - char buf[BUF_SIZE]; // server send from, remote recv into - int buf_len; - char stage; - struct server_ctx *recv_ctx; - struct server_ctx *send_ctx; - struct remote *remote; -}; -struct server_ctx { - ev_io io; - int connected; - struct server *server; -}; -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; -}; -struct remote_ctx { - ev_io io; - int connected; - struct remote *remote; -}; - - -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); -static void remote_recv_cb (EV_P_ ev_io *w, int revents); -static void remote_send_cb (EV_P_ ev_io *w, int revents); -struct remote* new_remote(int fd); -void free_remote(struct remote *remote); -void close_and_free_remote(EV_P_ struct remote *remote); -struct server* new_server(int fd); -void free_server(struct server *server); -void close_and_free_server(EV_P_ struct server *server); -