Browse Source

fix a crash

pull/14/head
Max Lv 11 years ago
parent
commit
8e6724a1fd
2 changed files with 31 additions and 28 deletions
  1. 58
      src/udprelay.c
  2. 1
      src/udprelay.h

58
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 *new_remote_ctx(int fd) {
struct remote_ctx *ctx = malloc(sizeof(struct remote_ctx)); struct remote_ctx *ctx = malloc(sizeof(struct remote_ctx));
memset(ctx, 0, sizeof(struct remote_ctx)); memset(ctx, 0, sizeof(struct remote_ctx));
ctx->buf = malloc(BUF_SIZE);
ctx->server_ctx = NULL; ctx->server_ctx = NULL;
ctx->fd = fd; ctx->fd = fd;
ev_io_init(&ctx->io, remote_recv_cb, fd, EV_READ); 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 * new_server_ctx(int fd) {
struct server_ctx *ctx = malloc(sizeof(struct server_ctx)); struct server_ctx *ctx = malloc(sizeof(struct server_ctx));
memset(ctx, 0, sizeof(struct server_ctx)); memset(ctx, 0, sizeof(struct server_ctx));
ctx->buf = malloc(BUF_SIZE);
ctx->fd = fd; ctx->fd = fd;
ev_io_init(&ctx->io, server_recv_cb, fd, EV_READ); ev_io_init(&ctx->io, server_recv_cb, fd, EV_READ);
return ctx; return ctx;
@ -267,9 +265,6 @@ void close_and_free_remote(EV_P_ struct remote_ctx *ctx) {
if (ctx->addr_header != NULL) { if (ctx->addr_header != NULL) {
free(ctx->addr_header); free(ctx->addr_header);
} }
if (ctx->buf != NULL) {
free(ctx->buf);
}
free(ctx); 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); ev_timer_again(EV_A_ &remote_ctx->watcher);
struct sockaddr src_addr; struct sockaddr src_addr;
char *buf = remote_ctx->buf;
int addr_len = sizeof(src_addr); int addr_len = sizeof(src_addr);
int addr_header_len = remote_ctx->addr_header_len; int addr_header_len = remote_ctx->addr_header_len;
char *buf = malloc(BUF_SIZE);
// recv // recv
ssize_t buf_len = recvfrom(remote_ctx->fd, buf, BUF_SIZE, 0, &src_addr, &addr_len); 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) { if (verbose) {
ERROR("udprelay_server_recvfrom"); ERROR("udprelay_server_recvfrom");
} }
return;
goto CLEAN_UP;
} }
if (verbose) { 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); int len = parse_udprealy_header(buf, buf_len, NULL, NULL);
if (len == 0 || len != addr_header_len) { if (len == 0 || len != addr_header_len) {
// error in parse header // error in parse header
return;
goto CLEAN_UP;
} }
buf_len -= addr_header_len; buf_len -= addr_header_len;
memmove(buf, buf + addr_header_len, buf_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 = tmpbuf;
buf_len += addr_header_len; 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 #endif
int s = sendto(remote_ctx->fd, buf, buf_len, 0, &remote_ctx->src_addr, sizeof(remote_ctx->src_addr)); 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"); ERROR("udprelay_sendto_local");
} }
CLEAN_UP:
free(buf);
} }
static void server_recv_cb (EV_P_ ev_io *w, int revents) { static void server_recv_cb (EV_P_ ev_io *w, int revents) {
struct server_ctx *server_ctx = (struct server_ctx *)w; struct server_ctx *server_ctx = (struct server_ctx *)w;
struct sockaddr src_addr; struct sockaddr src_addr;
char *buf = server_ctx->buf;
char *buf = malloc(BUF_SIZE);
int addr_len = sizeof(src_addr); int addr_len = sizeof(src_addr);
int offset = 0; int offset = 0;
@ -456,7 +454,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
if (verbose) { if (verbose) {
ERROR("udprelay_server_recvfrom"); ERROR("udprelay_server_recvfrom");
} }
return;
goto CLEAN_UP;
} }
if (verbose) { if (verbose) {
@ -518,22 +516,32 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
buf_len - offset, host, port); buf_len - offset, host, port);
if (addr_header_len == 0) { if (addr_header_len == 0) {
// error in parse header // error in parse header
return;
goto CLEAN_UP;
} }
char *addr_header = buf + offset; char *addr_header = buf + offset;
char *key = hash_key(addr_header, addr_header_len, &src_addr); char *key = hash_key(addr_header, addr_header_len, &src_addr);
struct cache *conn_cache = server_ctx->conn_cache; 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 #ifdef UDPRELAY_LOCAL
if (frag) { if (frag) {
LOGE("drop a message since frag is not 0, but %d", 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) { if (remote_ctx == NULL) {
struct addrinfo hints; struct addrinfo hints;
@ -547,7 +555,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
&hints, &result); &hints, &result);
if (s != 0 || result == NULL) { if (s != 0 || result == NULL) {
LOGE("getaddrinfo: %s", gai_strerror(s)); LOGE("getaddrinfo: %s", gai_strerror(s));
return;
goto CLEAN_UP;
} }
// Bind to any port // Bind to any port
@ -556,7 +564,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
ERROR("udprelay bind() error.."); ERROR("udprelay bind() error..");
// remember to free addrinfo // remember to free addrinfo
freeaddrinfo(result); freeaddrinfo(result);
return;
goto CLEAN_UP;
} }
setnonblocking(remotefd); setnonblocking(remotefd);
@ -581,7 +589,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
buf_len -= 3; buf_len -= 3;
memmove(buf, buf + 3, buf_len); 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)); 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; buf_len -= offset;
memmove(buf, buf + offset, buf_len); 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) { if (remote_ctx == NULL) {
struct addrinfo hints; struct addrinfo hints;
asyncns_query_t *query; asyncns_query_t *query;
@ -613,7 +614,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents) {
if (query == NULL) { if (query == NULL) {
ERROR("udp_asyncns_getaddrinfo"); ERROR("udp_asyncns_getaddrinfo");
return;
goto CLEAN_UP;
} }
struct query_ctx *query_ctx = new_query_ctx(query, buf, buf_len); 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 #endif
CLEAN_UP:
free(buf);
} }
void free_cb(void *element) { void free_cb(void *element) {

1
src/udprelay.h

@ -48,7 +48,6 @@ struct remote_ctx {
ev_io io; ev_io io;
ev_timer watcher; ev_timer watcher;
int fd; int fd;
char *buf; // server send from, remote recv into
int addr_header_len; int addr_header_len;
char addr_header[384]; char addr_header[384];
struct sockaddr src_addr; struct sockaddr src_addr;

Loading…
Cancel
Save