|
|
@ -216,14 +216,17 @@ static int construct_udprealy_header(const struct sockaddr_storage *in_addr, |
|
|
|
#endif |
|
|
|
|
|
|
|
static int parse_udprealy_header(const char * buf, const int buf_len, |
|
|
|
char *host, char *port, |
|
|
|
int *auth, char *host, char *port, |
|
|
|
struct sockaddr_storage *storage) |
|
|
|
{ |
|
|
|
|
|
|
|
const uint8_t atyp = *(uint8_t *)buf; |
|
|
|
int offset = 1; |
|
|
|
|
|
|
|
if (auth != NULL) *auth |= (atyp & ONETIMEAUTH_FLAG); |
|
|
|
|
|
|
|
// get remote addr and port |
|
|
|
if (atyp == 1) { |
|
|
|
if ((atyp & ADDRTYPE_MASK) == 1) { |
|
|
|
// IP V4 |
|
|
|
size_t in_addr_len = sizeof(struct in_addr); |
|
|
|
if (buf_len > in_addr_len) { |
|
|
@ -239,7 +242,7 @@ static int parse_udprealy_header(const char * buf, const int buf_len, |
|
|
|
} |
|
|
|
offset += in_addr_len; |
|
|
|
} |
|
|
|
} else if (atyp == 3) { |
|
|
|
} else if ((atyp & ADDRTYPE_MASK) == 3) { |
|
|
|
// Domain name |
|
|
|
uint8_t name_len = *(uint8_t *)(buf + offset); |
|
|
|
if (name_len < buf_len && name_len < 255 && name_len > 0) { |
|
|
@ -264,7 +267,7 @@ static int parse_udprealy_header(const char * buf, const int buf_len, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (atyp == 4) { |
|
|
|
} else if ((atyp & ADDRTYPE_MASK) == 4) { |
|
|
|
// IP V6 |
|
|
|
size_t in6_addr_len = sizeof(struct in6_addr); |
|
|
|
if (buf_len > in6_addr_len) { |
|
|
@ -657,14 +660,14 @@ static void remote_recv_cb(EV_P_ ev_io *w, int revents) |
|
|
|
#ifdef UDPRELAY_REDIR |
|
|
|
struct sockaddr_storage dst_addr; |
|
|
|
memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); |
|
|
|
int len = parse_udprealy_header(buf, buf_len, NULL, NULL, &dst_addr); |
|
|
|
int len = parse_udprealy_header(buf, buf_len, NULL, NULL, NULL, &dst_addr); |
|
|
|
|
|
|
|
if (dst_addr.ss_family != AF_INET && dst_addr.ss_family != AF_INET6) { |
|
|
|
LOGI("[udp] ss-redir does not support domain name"); |
|
|
|
goto CLEAN_UP; |
|
|
|
} |
|
|
|
#else |
|
|
|
int len = parse_udprealy_header(buf, buf_len, NULL, NULL, NULL); |
|
|
|
int len = parse_udprealy_header(buf, buf_len, NULL, NULL, NULL, NULL); |
|
|
|
#endif |
|
|
|
|
|
|
|
if (len == 0) { |
|
|
@ -830,7 +833,7 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) |
|
|
|
|
|
|
|
tx += buf_len; |
|
|
|
|
|
|
|
buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method, 1); |
|
|
|
buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method, server_ctx->auth); |
|
|
|
if (buf == NULL) { |
|
|
|
ERROR("[udp] server_ss_decrypt_all"); |
|
|
|
goto CLEAN_UP; |
|
|
@ -972,8 +975,8 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) |
|
|
|
struct sockaddr_storage dst_addr; |
|
|
|
memset(&dst_addr, 0, sizeof(struct sockaddr_storage)); |
|
|
|
|
|
|
|
int addr_header_len = parse_udprealy_header(buf + offset, |
|
|
|
buf_len - offset, host, port, |
|
|
|
int addr_header_len = parse_udprealy_header(buf + offset, buf_len - offset, |
|
|
|
&server_ctx->auth, host, port, |
|
|
|
&dst_addr); |
|
|
|
if (addr_header_len == 0) { |
|
|
|
// error in parse header |
|
|
@ -1089,7 +1092,11 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents) |
|
|
|
memmove(buf, buf + offset, buf_len); |
|
|
|
} |
|
|
|
|
|
|
|
buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method, 1); |
|
|
|
if (server_ctx->auth) { |
|
|
|
buf[0] |= ONETIMEAUTH_FLAG; |
|
|
|
} |
|
|
|
|
|
|
|
buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method, server_ctx->auth); |
|
|
|
|
|
|
|
int s = sendto(remote_ctx->fd, buf, buf_len, 0, remote_addr, remote_addr_len); |
|
|
|
|
|
|
@ -1213,7 +1220,7 @@ int init_udprelay(const char *server_host, const char *server_port, |
|
|
|
const ss_addr_t tunnel_addr, |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
int method, int timeout, const char *iface) |
|
|
|
int method, int auth, int timeout, const char *iface) |
|
|
|
{ |
|
|
|
// Inilitialize ev loop |
|
|
|
struct ev_loop *loop = EV_DEFAULT; |
|
|
@ -1236,6 +1243,7 @@ int init_udprelay(const char *server_host, const char *server_port, |
|
|
|
#ifdef UDPRELAY_REMOTE |
|
|
|
server_ctx->loop = loop; |
|
|
|
#endif |
|
|
|
server_ctx->auth = auth; |
|
|
|
server_ctx->timeout = max(timeout, MIN_UDP_TIMEOUT); |
|
|
|
server_ctx->method = method; |
|
|
|
server_ctx->iface = iface; |
|
|
|