diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3ae28388..dd118ac8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,7 @@ set(SS_SHARED_SOURCES json.c cache.c netutils.c - relay.c + tcprelay.c ) set(LIBSHADOWSOCKS_LIBEV_SOURCE diff --git a/src/Makefile.am b/src/Makefile.am index 02464150..f1cc4c6d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,7 +42,7 @@ common_src = utils.c \ jconf.c \ json.c \ udprelay.c \ - relay.c \ + tcprelay.c \ cache.c \ netutils.c @@ -101,7 +101,7 @@ ss_redir_SOURCES = utils.c \ netutils.c \ cache.c \ udprelay.c \ - relay.c \ + tcprelay.c \ redir.c \ $(crypto_src) \ $(plugin_src) \ @@ -122,5 +122,5 @@ include_HEADERS = shadowsocks.h noinst_HEADERS = acl.h crypto.h stream.h aead.h json.h netutils.h tls.h uthash.h \ cache.h http.h plugin.h resolv.h utils.h base64.h ppbloom.h \ - common.h jconf.h manager.h protocol.h rule.h socks5.h udprelay.h relay.h winsock.h + common.h jconf.h manager.h protocol.h rule.h socks5.h udprelay.h tcprelay.h winsock.h EXTRA_DIST = ss-nat diff --git a/src/local.c b/src/local.c index 4013e76c..3d032acd 100644 --- a/src/local.c +++ b/src/local.c @@ -57,7 +57,7 @@ #include "tls.h" #include "plugin.h" #include "winsock.h" -#include "relay.h" +#include "tcprelay.h" #include "acl.h" #ifndef LIB_ONLY diff --git a/src/netutils.c b/src/netutils.c index 8ddb7677..1fdb693b 100644 --- a/src/netutils.c +++ b/src/netutils.c @@ -601,48 +601,13 @@ sockaddr_cmp_addr(struct sockaddr_storage *addr1, } } -int -validate_hostname(const char *hostname, const int hostname_len) -{ - if (hostname == NULL) - return 0; - - if (hostname_len < 1 || hostname_len > 255) - return 0; - - if (hostname[0] == '.') - return 0; - - const char *label = hostname; - while (label < hostname + hostname_len) { - size_t label_len = hostname_len - (label - hostname); - char *next_dot = strchr(label, '.'); - if (next_dot != NULL) - label_len = next_dot - label; - - if (label + label_len > hostname + hostname_len) - return 0; - - if (label_len > 63 || label_len < 1) - return 0; - - if (label[0] == '-' || label[label_len - 1] == '-') - return 0; - - if (strspn(label, valid_label_bytes) < label_len) - return 0; - - label += label_len + 1; - } - - return 1; -} - char * -hostname_readable(char *dname, uint16_t port) +hostname_readable(const char *dname, + const int dname_len, uint16_t port) { - char *ret = ss_calloc(strlen(dname) + MAX_PORT_STR_LEN, sizeof(*ret)); - sprintf(ret, "%s:%d", dname, ntohs(port)); + size_t len = dname_len + MAX_PORT_STR_LEN; + char *ret = ss_calloc(len , sizeof(*ret)); + snprintf(ret, len, "%.*s:%d", dname_len, dname, ntohs(port)); return ret; } diff --git a/src/netutils.h b/src/netutils.h index 43c2a365..9a829fa4 100644 --- a/src/netutils.h +++ b/src/netutils.h @@ -263,8 +263,7 @@ int sockaddr_cmp(struct sockaddr_storage *addr1, int sockaddr_cmp_addr(struct sockaddr_storage *addr1, struct sockaddr_storage *addr2, socklen_t len); -int validate_hostname(const char *hostname, const int hostname_len); -char *hostname_readable(char *dname, uint16_t port); +char *hostname_readable(const char *dname, const int dname_len, uint16_t port); int is_addr_loopback(const struct sockaddr *addr); diff --git a/src/redir.c b/src/redir.c index b7aa25e4..9541a009 100644 --- a/src/redir.c +++ b/src/redir.c @@ -49,7 +49,7 @@ #include "utils.h" #include "common.h" #include "acl.h" -#include "relay.h" +#include "tcprelay.h" int verbose = 0; int ipv6first = 0; diff --git a/src/server.c b/src/server.c index 1cb43bb1..61596eb0 100644 --- a/src/server.c +++ b/src/server.c @@ -55,7 +55,7 @@ #include "acl.h" #include "plugin.h" #include "winsock.h" -#include "relay.h" +#include "tcprelay.h" #ifndef SSMAXCONN #define SSMAXCONN 1024 diff --git a/src/shadowsocks.h b/src/shadowsocks.h index 0696bb5c..79aa8ea2 100644 --- a/src/shadowsocks.h +++ b/src/shadowsocks.h @@ -123,6 +123,8 @@ void free_ssocks_addr(ssocks_addr_t *destaddr) * parse_ssocks_header * create_ssocks_header * + * CAVEATS: The domain name is not null-terminated + * * / Pre-encryption ////////////////////// * - Shadowsocks Request * +------+----------+----------+----------+ @@ -182,32 +184,9 @@ parse_ssocks_header(buffer_t *buf, ssocks_addr_t *destaddr, int offset) memcpy(dname, buf->data + offset + 1, dname_len); offset += dname_len + 1; + destaddr->dname = dname; + destaddr->dname_len = dname_len; destaddr->port = *(uint16_t *)(buf->data + offset); - - struct cork_ip ip; - if (cork_ip_init(&ip, dname) != -1) { - switch (ip.version) { - case 4: { - struct sockaddr_in *addr - = ss_calloc(1, sizeof(*addr)); - addr->sin_family = AF_INET; - memcpy(&addr->sin_addr, &ip.ip.v4, sizeof(ip.ip.v4)); - addr->sin_port = destaddr->port; - destaddr->addr = (struct sockaddr_storage *)addr; - } break; - case 6: { - struct sockaddr_in6 *addr - = ss_calloc(1, sizeof(*addr)); - addr->sin6_family = AF_INET; - memcpy(&addr->sin6_addr, &ip.ip.v6, sizeof(ip.ip.v6)); - addr->sin6_port = destaddr->port; - destaddr->addr = (struct sockaddr_storage *)addr; - } break; - } - } else { - destaddr->dname = dname; - destaddr->dname_len = dname_len; - } } break; case SSOCKS_ATYP_IPV6: { size_t in6_addr_len = sizeof(struct in_addr); diff --git a/src/relay.c b/src/tcprelay.c similarity index 99% rename from src/relay.c rename to src/tcprelay.c index 1098c7cd..21f67035 100644 --- a/src/relay.c +++ b/src/tcprelay.c @@ -57,7 +57,7 @@ #include "acl.h" #include "plugin.h" -#include "relay.h" +#include "tcprelay.h" extern int acl; extern int verbose; @@ -183,7 +183,7 @@ create_remote(EV_P_ remote_t *remote, buffer_t *buf, if (destaddr->dname_len == -1) { return -1; } else if (destaddr->dname_len <= 0 || - !validate_hostname(destaddr->dname, destaddr->dname_len)) + destaddr->dname_len >= MAX_HOSTNAME_LEN) { destaddr->dname = NULL; } @@ -197,7 +197,7 @@ create_remote(EV_P_ remote_t *remote, buffer_t *buf, if (verbose) { LOGI("%s %s", direct ? "bypassing" : "connecting to", - destaddr->dname ? hostname_readable(destaddr->dname, destaddr->port) + destaddr->dname ? hostname_readable(destaddr->dname, destaddr->dname_len, destaddr->port) : sockaddr_readable("%a:%p", destaddr->addr)); } diff --git a/src/relay.h b/src/tcprelay.h similarity index 98% rename from src/relay.h rename to src/tcprelay.h index 3924fb07..093da435 100644 --- a/src/relay.h +++ b/src/tcprelay.h @@ -20,8 +20,8 @@ * . */ -#ifndef _RELAY_H -#define _RELAY_H +#ifndef _TCP_RELAY_H +#define _TCP_RELAY_H #include diff --git a/src/tunnel.c b/src/tunnel.c index b4efdf31..449feec9 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -54,7 +54,7 @@ #include "utils.h" #include "plugin.h" #include "winsock.h" -#include "relay.h" +#include "tcprelay.h" int verbose = 0; int acl = 0; diff --git a/src/udprelay.c b/src/udprelay.c index 46729db5..0ed361d1 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -691,7 +691,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) } if (destaddr->dname_len <= 0 || - !validate_hostname(destaddr->dname, destaddr->dname_len)) + destaddr->dname_len >= MAX_HOSTNAME_LEN) { destaddr->dname = NULL; } @@ -705,7 +705,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (verbose) { LOGI("%s %s", remote->direct ? "bypassing" : "connecting to", - destaddr->dname ? hostname_readable(destaddr->dname, destaddr->port) + destaddr->dname ? hostname_readable(destaddr->dname, destaddr->dname_len, destaddr->port) : sockaddr_readable("%a:%p", destaddr->addr)); }