From 8e6724a1fd9362c0d82d0b3165cd88e818fd4ddb Mon Sep 17 00:00:00 2001 From: Max Lv Date: Sat, 31 Aug 2013 17:35:34 +0800 Subject: [PATCH] fix a crash --- src/udprelay.c | 58 +++++++++++++++++++++++++++----------------------- src/udprelay.h | 1 - 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/udprelay.c b/src/udprelay.c index c93aaf17..c23bf8d3 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -219,7 +219,6 @@ int create_server_socket(const char *host, const char *port) { struct remote_ctx *new_remote_ctx(int fd) { struct remote_ctx *ctx = malloc(sizeof(struct remote_ctx)); memset(ctx, 0, sizeof(struct remote_ctx)); - ctx->buf = malloc(BUF_SIZE); ctx->server_ctx = NULL; ctx->fd = fd; ev_io_init(&ctx->io, remote_recv_cb, fd, EV_READ); @@ -229,7 +228,6 @@ struct remote_ctx *new_remote_ctx(int fd) { struct server_ctx * new_server_ctx(int fd) { struct server_ctx *ctx = malloc(sizeof(struct server_ctx)); memset(ctx, 0, sizeof(struct server_ctx)); - ctx->buf = malloc(BUF_SIZE); ctx->fd = fd; ev_io_init(&ctx->io, server_recv_cb, fd, EV_READ); return ctx; @@ -267,9 +265,6 @@ void close_and_free_remote(EV_P_ struct remote_ctx *ctx) { if (ctx->addr_header != NULL) { free(ctx->addr_header); } - if (ctx->buf != NULL) { - free(ctx->buf); - } free(ctx); } } @@ -389,9 +384,9 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { ev_timer_again(EV_A_ &remote_ctx->watcher); struct sockaddr src_addr; - char *buf = remote_ctx->buf; int addr_len = sizeof(src_addr); int addr_header_len = remote_ctx->addr_header_len; + char *buf = malloc(BUF_SIZE); // recv ssize_t buf_len = recvfrom(remote_ctx->fd, buf, BUF_SIZE, 0, &src_addr, &addr_len); @@ -402,7 +397,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { if (verbose) { ERROR("udprelay_server_recvfrom"); } - return; + goto CLEAN_UP; } if (verbose) { @@ -415,7 +410,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { int len = parse_udprealy_header(buf, buf_len, NULL, NULL); if (len == 0 || len != addr_header_len) { // error in parse header - return; + goto CLEAN_UP; } buf_len -= addr_header_len; memmove(buf, buf + addr_header_len, buf_len); @@ -429,7 +424,7 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { buf = tmpbuf; buf_len += addr_header_len; - ss_encrypt_all(BLOCK_SIZE, buf, &buf_len, server_ctx->method); + ss_encrypt_all(BUF_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)); @@ -438,12 +433,15 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents) { ERROR("udprelay_sendto_local"); } +CLEAN_UP: + free(buf); + } static void server_recv_cb (EV_P_ ev_io *w, int revents) { struct server_ctx *server_ctx = (struct server_ctx *)w; struct sockaddr src_addr; - char *buf = server_ctx->buf; + char *buf = malloc(BUF_SIZE); int addr_len = sizeof(src_addr); int offset = 0; @@ -456,7 +454,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { if (verbose) { ERROR("udprelay_server_recvfrom"); } - return; + goto CLEAN_UP; } if (verbose) { @@ -518,22 +516,32 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { buf_len - offset, host, port); if (addr_header_len == 0) { // error in parse header - return; + goto CLEAN_UP; } char *addr_header = buf + offset; char *key = hash_key(addr_header, addr_header_len, &src_addr); struct cache *conn_cache = server_ctx->conn_cache; + struct remote_ctx *remote_ctx = NULL; + cache_lookup(conn_cache, key, (void*)&remote_ctx); + + if (remote_ctx == NULL) { + if (verbose) { + LOGD("[udp] cache missed: %s:%s", host, port); + } + } else { + if (verbose) { + LOGD("[udp] cache hit: %s:%s", host, port); + } + } + #ifdef UDPRELAY_LOCAL if (frag) { LOGE("drop a message since frag is not 0, but %d", frag); - return; + goto CLEAN_UP; } - struct remote_ctx *remote_ctx = NULL; - cache_lookup(conn_cache, key, (void*)&remote_ctx); - if (remote_ctx == NULL) { struct addrinfo hints; @@ -547,7 +555,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { &hints, &result); if (s != 0 || result == NULL) { LOGE("getaddrinfo: %s", gai_strerror(s)); - return; + goto CLEAN_UP; } // Bind to any port @@ -556,7 +564,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { ERROR("udprelay bind() error.."); // remember to free addrinfo freeaddrinfo(result); - return; + goto CLEAN_UP; } setnonblocking(remotefd); @@ -581,7 +589,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { buf_len -= 3; memmove(buf, buf + 3, buf_len); - ss_encrypt_all(BLOCK_SIZE, buf, &buf_len, server_ctx->method); + ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); int s = sendto(remote_ctx->fd, buf, buf_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr)); @@ -594,13 +602,6 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { buf_len -= offset; memmove(buf, buf + offset, buf_len); - if (verbose) { - LOGD("[udp] send to: %s:%s", host, port); - } - - struct remote_ctx *remote_ctx = NULL; - cache_lookup(conn_cache, key, (void*)remote_ctx); - if (remote_ctx == NULL) { struct addrinfo hints; asyncns_query_t *query; @@ -613,7 +614,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { if (query == NULL) { ERROR("udp_asyncns_getaddrinfo"); - return; + goto CLEAN_UP; } struct query_ctx *query_ctx = new_query_ctx(query, buf, buf_len); @@ -635,6 +636,9 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) { } #endif +CLEAN_UP: + free(buf); + } void free_cb(void *element) { diff --git a/src/udprelay.h b/src/udprelay.h index e3f0108d..8372043f 100644 --- a/src/udprelay.h +++ b/src/udprelay.h @@ -48,7 +48,6 @@ struct remote_ctx { ev_io io; ev_timer watcher; int fd; - char *buf; // server send from, remote recv into int addr_header_len; char addr_header[384]; struct sockaddr src_addr;