From 1d044b9adaedfe8fcac19095bd906aa9901b925c Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sun, 18 Aug 2013 20:55:19 +0800 Subject: [PATCH] works, but buggy --- src/local.c | 17 ++++++++----- src/server.c | 4 +-- src/udprelay.c | 68 +++++++++++++++++++++----------------------------- 3 files changed, 42 insertions(+), 47 deletions(-) diff --git a/src/local.c b/src/local.c index 1f022add..8949be17 100644 --- a/src/local.c +++ b/src/local.c @@ -39,7 +39,7 @@ #define BUF_SIZE 512 #endif -static int verbose = 0; +int verbose = 0; static int setnonblocking(int fd) { int flags; @@ -182,7 +182,13 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { } else if (server->stage == 1) { struct socks5_request *request = (struct socks5_request *)remote->buf; + struct sockaddr_in s_addr; + memset(&s_addr, 0, sizeof(s_addr)); + if (request->cmd == 3) { + socklen_t addr_len = sizeof(s_addr); + getsockname(server->fd, (struct sockaddr *)&s_addr, + &addr_len); if (verbose) { LOGD("udp assc request accepted."); } @@ -282,13 +288,12 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { response.rsv = 0; response.atyp = 1; - struct in_addr sin_addr; - memset(&sin_addr, 0, sizeof(struct in_addr)); - memcpy(server->buf, &response, sizeof(struct socks5_response)); - memset(server->buf + sizeof(struct socks5_response), 0, sizeof(struct in_addr) + sizeof(uint16_t)); + memcpy(server->buf + sizeof(struct socks5_response), &s_addr.sin_addr, sizeof(s_addr.sin_addr)); + memcpy(server->buf + sizeof(struct socks5_response) + sizeof(s_addr.sin_addr), + &s_addr.sin_port, sizeof(s_addr.sin_port)); - int reply_size = sizeof(struct socks5_response) + sizeof(struct in_addr) + sizeof(uint16_t); + int reply_size = sizeof(struct socks5_response) + sizeof(s_addr.sin_addr) + sizeof(s_addr.sin_port); int s = send(server->fd, server->buf, reply_size, 0); if (s < reply_size) { LOGE("failed to send fake reply."); diff --git a/src/server.c b/src/server.c index 9770f22e..8c44a59a 100644 --- a/src/server.c +++ b/src/server.c @@ -39,7 +39,7 @@ #define BUF_SIZE 512 #endif -static int verbose = 0; +int verbose = 0; static int remote_conn = 0; static int server_conn = 0; @@ -886,7 +886,7 @@ int main (int argc, char **argv) { } // Setup UDP - udprelay(server_host[0], server_port, m, iface); + udprelay(server_host[0], server_port, asyncns, m, iface); // start ev loop ev_run (loop, 0); diff --git a/src/udprelay.c b/src/udprelay.c index 22dbffeb..c93aaf17 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -30,22 +30,6 @@ #include "udprelay.h" #include "cache.h" -#ifdef UDPRELAY_REMOTE -struct udprelay_header { - uint8_t atyp; -}; -#else -#ifdef UDPRELAY_LOCAL -struct udprelay_header { - uint16_t rsv; - uint8_t frag; - uint8_t atyp; -}; -#else -#error "No UDPRELAY defined" -#endif -#endif - #ifdef UDPRELAY_REMOTE #ifdef UDPRELAY_LOCAL #error "UDPRELAY_REMOTE and UDPRELAY_LOCAL should not be both defined" @@ -62,7 +46,7 @@ struct udprelay_header { #define BUF_SIZE MAX_UDP_PACKET_SIZE -static int verbose = 0; +extern int verbose; static int remote_conn = 0; static int server_conn = 0; @@ -96,10 +80,10 @@ static char *hash_key(const char *header, const int header_len, const struct soc return (char*) MD5((const uint8_t *)key, sizeof(struct sockaddr) + header_len, NULL); } -static int parse_udprealy_header(const char* buf, const int buf_len, - const int atyp, char *host, char *port) { +static int parse_udprealy_header(const char* buf, const int buf_len, char *host, char *port) { - int offset = 0; + const uint8_t atyp = *(uint8_t*)buf; + int offset = 1; // get remote addr and port if (atyp == 1) { // IP V4 @@ -132,7 +116,7 @@ static int parse_udprealy_header(const char* buf, const int buf_len, } } - if (offset == 0){ + if (offset == 1){ LOGE("invalid header with addr type %d", atyp); return 0; } @@ -327,7 +311,7 @@ static void query_resolve_cb(EV_P_ ev_timer *watcher, int revents) { } if (verbose) { - LOGD("asyncns resolved."); + LOGD("[udp] asyncns resolved."); } ev_timer_stop(EV_A_ watcher); @@ -422,21 +406,19 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { } if (verbose) { - LOGD("receive a packet."); + LOGD("[udp] remote receive a packet."); } #ifdef UDPRELAY_LOCAL buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); - uint8_t atyp = *(uint8_t*)buf; - int offset = 1; - int len = parse_udprealy_header(buf + offset, - buf_len - offset, atyp, NULL, NULL); + + int len = parse_udprealy_header(buf, buf_len, NULL, NULL); if (len == 0 || len != addr_header_len) { // error in parse header return; } - buf_len = buf_len - offset - addr_header_len; - memmove(buf, buf + offset + addr_header_len, buf_len); + buf_len -= addr_header_len; + memmove(buf, buf + addr_header_len, buf_len); #endif #ifdef UDPRELAY_REMOTE @@ -446,19 +428,20 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { free(buf); buf = tmpbuf; buf_len += addr_header_len; + + ss_encrypt_all(BLOCK_SIZE, buf, &buf_len, server_ctx->method); #endif int s = sendto(remote_ctx->fd, buf, buf_len, 0, &remote_ctx->src_addr, sizeof(remote_ctx->src_addr)); if (s == -1) { - ERROR("udprelay_sendto_remote"); + ERROR("udprelay_sendto_local"); } } static void server_recv_cb (EV_P_ ev_io *w, int revents) { struct server_ctx *server_ctx = (struct server_ctx *)w; - struct udprelay_header *udprelay_header; struct sockaddr src_addr; char *buf = server_ctx->buf; @@ -477,15 +460,17 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { } if (verbose) { - LOGD("receive a packet."); + LOGD("[udp] server receive a packet."); } #ifdef UDPRELAY_REMOTE buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); #endif - udprelay_header = (struct udprelay_header *)buf; - offset += sizeof(struct udprelay_header); +#ifdef UDPRELAY_LOCAL + uint8_t frag = *(uint8_t*)(buf + 2); + offset += 3; +#endif /* * @@ -530,19 +515,19 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { char port[64] = {0}; int addr_header_len = parse_udprealy_header(buf + offset, - buf_len - offset, udprelay_header->atyp, host, port); + buf_len - offset, host, port); if (addr_header_len == 0) { // error in parse header return; } - char *addr_header = buf + offset - sizeof(udprelay_header->atyp); + char *addr_header = buf + offset; char *key = hash_key(addr_header, addr_header_len, &src_addr); struct cache *conn_cache = server_ctx->conn_cache; #ifdef UDPRELAY_LOCAL - if (udprelay_header->frag) { - LOGE("drop a message since frag is not 0"); + if (frag) { + LOGE("drop a message since frag is not 0, but %d", frag); return; } @@ -610,7 +595,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { memmove(buf, buf + offset, buf_len); if (verbose) { - LOGD("send to: %s:%s", host, port); + LOGD("[udp] send to: %s:%s", host, port); } struct remote_ctx *remote_ctx = NULL; @@ -654,6 +639,11 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { void free_cb(void *element) { struct remote_ctx *remote_ctx = (struct remote_ctx *)element; + + if (verbose) { + LOGD("free a remote ctx"); + } + close_and_free_remote(EV_DEFAULT, remote_ctx); }