Browse Source

fix #121

pull/127/head
Max Lv 10 years ago
parent
commit
1fcd60884d
2 changed files with 61 additions and 43 deletions
  1. 96
      src/udprelay.c
  2. 8
      src/udprelay.h

96
src/udprelay.c

@ -96,17 +96,17 @@ static int setinterface(int socket_fd, const char* interface_name)
} }
#endif #endif
static char *hash_key(const char *header, const int header_len, const struct sockaddr *addr)
static char *hash_key(const char *header, const int header_len, const struct sockaddr_storage *addr)
{ {
char key[384]; char key[384];
// calculate hash key // calculate hash key
// assert header_len < 256 // assert header_len < 256
memset(key, 0, 384); memset(key, 0, 384);
memcpy(key, addr, sizeof(struct sockaddr));
memcpy(key + sizeof(struct sockaddr), header, header_len);
memcpy(key, addr, sizeof(struct sockaddr_storage));
memcpy(key + sizeof(struct sockaddr_storage), header, header_len);
return (char*) enc_md5((const uint8_t *)key, sizeof(struct sockaddr) + header_len, NULL);
return (char*) enc_md5((const uint8_t *)key, sizeof(struct sockaddr_storage) + header_len, NULL);
} }
static int parse_udprealy_header(const char* buf, const int buf_len, char *host, char *port) static int parse_udprealy_header(const char* buf, const int buf_len, char *host, char *port)
@ -218,39 +218,45 @@ int create_remote_socket(int ipv6)
{ {
// Try to bind IPv6 first // Try to bind IPv6 first
struct sockaddr_in6 addr; struct sockaddr_in6 addr;
memset(&addr, 0, sizeof(struct sockaddr_in6));
memset(&addr, 0, sizeof(addr));
addr.sin6_len = sizeof(addr);
addr.sin6_family = AF_INET6; addr.sin6_family = AF_INET6;
addr.sin6_addr = in6addr_any; addr.sin6_addr = in6addr_any;
addr.sin6_port = htons(0);
addr.sin6_port = 0;
remote_sock = socket(AF_INET6, SOCK_DGRAM , 0); remote_sock = socket(AF_INET6, SOCK_DGRAM , 0);
if (remote_sock != -1)
if (remote_sock == -1)
{ {
if (bind(remote_sock, (struct sockaddr *)&addr, sizeof(addr)) != -1)
{
return remote_sock;
}
ERROR("Cannot create socket.");
return -1;
}
if (bind(remote_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
{
FATAL("Cannot bind remote.");
return -1;
} }
} }
// Then bind to IPv4
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(0);
remote_sock = socket(AF_INET, SOCK_DGRAM , 0);
if (remote_sock == -1)
else
{ {
ERROR("Cannot create socket.");
return -1;
}
// Or else bind to IPv4
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = 0;
remote_sock = socket(AF_INET, SOCK_DGRAM , 0);
if (remote_sock == -1)
{
ERROR("Cannot create socket.");
return -1;
}
if (bind(remote_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
{
FATAL("Cannot bind remote.");
return -1;
if (bind(remote_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0)
{
FATAL("Cannot bind remote.");
return -1;
}
} }
return remote_sock; return remote_sock;
} }
@ -451,7 +457,7 @@ static void query_resolve_cb(EV_P_ ev_io *w, int revents)
struct remote_ctx *remote_ctx = new_remote(remotefd, query_ctx->server_ctx); struct remote_ctx *remote_ctx = new_remote(remotefd, query_ctx->server_ctx);
remote_ctx->src_addr = query_ctx->src_addr; remote_ctx->src_addr = query_ctx->src_addr;
remote_ctx->dst_addr = *rp->ai_addr;
remote_ctx->dst_addr = *((struct sockaddr_storage *)rp->ai_addr);
remote_ctx->server_ctx = query_ctx->server_ctx; remote_ctx->server_ctx = query_ctx->server_ctx;
remote_ctx->addr_header_len = query_ctx->addr_header_len; remote_ctx->addr_header_len = query_ctx->addr_header_len;
memcpy(remote_ctx->addr_header, query_ctx->addr_header, query_ctx->addr_header_len); memcpy(remote_ctx->addr_header, query_ctx->addr_header, query_ctx->addr_header_len);
@ -463,7 +469,10 @@ static void query_resolve_cb(EV_P_ ev_io *w, int revents)
ev_io_start(EV_A_ &remote_ctx->io); ev_io_start(EV_A_ &remote_ctx->io);
int s = sendto(remote_ctx->fd, query_ctx->buf, query_ctx->buf_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr));
size_t addr_len = sizeof(struct sockaddr_in);
if (remote_ctx->dst_addr.ss_family == AF_INET6)
addr_len = sizeof(struct sockaddr_in6);
int s = sendto(remote_ctx->fd, query_ctx->buf, query_ctx->buf_len, 0, (struct sockaddr *)&remote_ctx->dst_addr, addr_len);
if (s == -1) if (s == -1)
{ {
@ -574,7 +583,10 @@ static void remote_recv_cb (EV_P_ ev_io *w, int revents)
buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method);
#endif #endif
int s = sendto(server_ctx->fd, buf, buf_len, 0, &remote_ctx->src_addr, sizeof(remote_ctx->src_addr));
size_t addr_len = sizeof(struct sockaddr_in);
if (remote_ctx->src_addr.ss_family == AF_INET6)
addr_len = sizeof(struct sockaddr_in6);
int s = sendto(server_ctx->fd, buf, buf_len, 0, (struct sockaddr *)&remote_ctx->src_addr, addr_len);
if (s == -1) if (s == -1)
{ {
@ -589,13 +601,13 @@ CLEAN_UP:
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_storage src_addr;
char *buf = malloc(BUF_SIZE); char *buf = malloc(BUF_SIZE);
socklen_t src_addr_len = sizeof(src_addr);
socklen_t src_addr_len = sizeof(struct sockaddr_storage);
unsigned int offset = 0; unsigned int offset = 0;
ssize_t buf_len = recvfrom(server_ctx->fd, buf, BUF_SIZE, 0, &src_addr, &src_addr_len);
ssize_t buf_len = recvfrom(server_ctx->fd, buf, BUF_SIZE, 0, (struct sockaddr *)&src_addr, &src_addr_len);
if (buf_len == -1) if (buf_len == -1)
{ {
@ -727,14 +739,14 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents)
{ {
if (verbose) if (verbose)
{ {
LOGD("[udp] cache missed: %s:%s <-> %s", host, port, get_addr_str(&src_addr));
LOGD("[udp] cache missed: %s:%s <-> %s", host, port, get_addr_str((struct sockaddr *)&src_addr));
} }
} }
else else
{ {
if (verbose) if (verbose)
{ {
LOGD("[udp] cache hit: %s:%s <-> %s", host, port, get_addr_str(&src_addr));
LOGD("[udp] cache hit: %s:%s <-> %s", host, port, get_addr_str((struct sockaddr *)&src_addr));
} }
} }
@ -788,7 +800,7 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents)
// Init remote_ctx // Init remote_ctx
remote_ctx = new_remote(remotefd, server_ctx); remote_ctx = new_remote(remotefd, server_ctx);
remote_ctx->src_addr = src_addr; remote_ctx->src_addr = src_addr;
remote_ctx->dst_addr = *result->ai_addr;
remote_ctx->dst_addr = *((struct sockaddr_storage *)result->ai_addr);
remote_ctx->addr_header_len = addr_header_len; remote_ctx->addr_header_len = addr_header_len;
memcpy(remote_ctx->addr_header, addr_header, addr_header_len); memcpy(remote_ctx->addr_header, addr_header, addr_header_len);
@ -810,7 +822,10 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents)
buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method); buf = 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));
size_t addr_len = sizeof(struct sockaddr_in);
if (remote_ctx->dst_addr.ss_family == AF_INET6)
addr_len = sizeof(struct sockaddr_in6);
int s = sendto(remote_ctx->fd, buf, buf_len, 0, (struct sockaddr*)&remote_ctx->dst_addr, addr_len);
if (s == -1) if (s == -1)
{ {
@ -846,8 +861,11 @@ static void server_recv_cb (EV_P_ ev_io *w, int revents)
} }
else else
{ {
size_t addr_len = sizeof(struct sockaddr_in);
if (remote_ctx->dst_addr.ss_family == AF_INET6)
addr_len = sizeof(struct sockaddr_in6);
int s = sendto(remote_ctx->fd, buf + addr_header_len, int s = sendto(remote_ctx->fd, buf + addr_header_len,
buf_len - addr_header_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr));
buf_len - addr_header_len, 0, (struct sockaddr*)&remote_ctx->dst_addr, addr_len);
if (s == -1) if (s == -1)
{ {

8
src/udprelay.h

@ -70,7 +70,7 @@ struct resolve_ctx
struct query_ctx struct query_ctx
{ {
asyncns_query_t *query; asyncns_query_t *query;
struct sockaddr src_addr;
struct sockaddr_storage src_addr;
int buf_len; int buf_len;
char *buf; // server send from, remote recv into char *buf; // server send from, remote recv into
int addr_header_len; int addr_header_len;
@ -86,15 +86,15 @@ struct remote_ctx
int fd; int fd;
int addr_header_len; int addr_header_len;
char addr_header[384]; char addr_header[384];
struct sockaddr src_addr;
struct sockaddr dst_addr;
struct sockaddr_storage src_addr;
struct sockaddr_storage dst_addr;
struct server_ctx *server_ctx; struct server_ctx *server_ctx;
}; };
static void server_recv_cb (EV_P_ ev_io *w, int revents); static void server_recv_cb (EV_P_ ev_io *w, int revents);
static void remote_recv_cb (EV_P_ ev_io *w, int revents); static void remote_recv_cb (EV_P_ ev_io *w, int revents);
static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents); static void remote_timeout_cb(EV_P_ ev_timer *watcher, int revents);
static char *hash_key(const char *header, const int header_len, const struct sockaddr *addr);
static char *hash_key(const char *header, const int header_len, const struct sockaddr_storage *addr);
#ifdef UDPRELAY_REMOTE #ifdef UDPRELAY_REMOTE
static void query_resolve_cb(EV_P_ ev_io *w, int revents); static void query_resolve_cb(EV_P_ ev_io *w, int revents);
#endif #endif

Loading…
Cancel
Save