commit b8cc3b6a5d0996c1589d18604b31b6c5655c391a Author: David Goulet dgoulet@ev0ke.net Date: Mon Jun 24 12:48:54 2013 -0400
Add domain name SOCKS5 connect support
Signed-off-by: David Goulet dgoulet@ev0ke.net --- src/common/connection.c | 1 + src/common/connection.h | 7 +++++++ src/common/socks5.c | 37 +++++++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/src/common/connection.c b/src/common/connection.c index b926f15..8fcbcf3 100644 --- a/src/common/connection.c +++ b/src/common/connection.c @@ -251,6 +251,7 @@ void connection_destroy(struct connection *conn) return; }
+ free(conn->dest_addr.hostname.addr); free(conn); }
diff --git a/src/common/connection.h b/src/common/connection.h index 17f940c..379f158 100644 --- a/src/common/connection.h +++ b/src/common/connection.h @@ -30,6 +30,7 @@ enum connection_domain { CONNECTION_DOMAIN_INET = 1, CONNECTION_DOMAIN_INET6 = 2, + CONNECTION_DOMAIN_NAME = 3, };
/* @@ -37,6 +38,12 @@ enum connection_domain { */ struct connection_addr { enum connection_domain domain; + + struct { + char *addr; + uint16_t port; + } hostname; + union { struct sockaddr_in sin; struct sockaddr_in6 sin6; diff --git a/src/common/socks5.c b/src/common/socks5.c index e06528a..91beb05 100644 --- a/src/common/socks5.c +++ b/src/common/socks5.c @@ -244,8 +244,9 @@ int socks5_send_connect_request(struct connection *conn) /* Always zeroed. */ msg.rsv = 0;
- /* Select connection socket domain. */ - if (conn->dest_addr.domain == CONNECTION_DOMAIN_INET) { + switch (conn->dest_addr.domain) { + case CONNECTION_DOMAIN_INET: + { struct socks5_request_ipv4 req_ipv4;
msg.atyp = SOCKS5_ATYP_IPV4; @@ -260,7 +261,10 @@ int socks5_send_connect_request(struct connection *conn) /* Copy ipv4 request portion in the buffer. */ memcpy(buffer + buf_len, &req_ipv4, sizeof(req_ipv4)); buf_len += sizeof(req_ipv4); - } else if (conn->dest_addr.domain == CONNECTION_DOMAIN_INET6) { + break; + } + case CONNECTION_DOMAIN_INET6: + { struct socks5_request_ipv6 req_ipv6;
msg.atyp = SOCKS5_ATYP_IPV6; @@ -275,7 +279,28 @@ int socks5_send_connect_request(struct connection *conn) /* Copy ipv6 request portion in the buffer. */ memcpy(buffer + buf_len, &req_ipv6, sizeof(req_ipv6)); buf_len += sizeof(req_ipv6); - } else { + break; + } + case CONNECTION_DOMAIN_NAME: + { + struct socks5_request_domain req_name; + + msg.atyp = SOCKS5_ATYP_DOMAIN; + /* Copy the first part of the request. */ + memcpy(buffer, &msg, buf_len); + + /* Setup domain name request buffer. */ + memcpy(req_name.name, conn->dest_addr.hostname.addr, + sizeof(req_name.name)); + req_name.port = conn->dest_addr.hostname.port; + req_name.len = strlen(conn->dest_addr.hostname.addr); + + /* Copy ipv6 request portion in the buffer. */ + memcpy(buffer + buf_len, &req_name, sizeof(req_name)); + buf_len += sizeof(req_name); + break; + } + default: ERR("Socks5 connection domain unknown %d", conn->dest_addr.domain); ret = -EINVAL; goto error; @@ -318,6 +343,10 @@ int socks5_recv_connect_reply(struct connection *conn) recv_len += sizeof(uint16_t);
switch (tsocks_config.socks5_addr.domain) { + case CONNECTION_DOMAIN_NAME: + /* + * Tor returns and IPv4 upon resolution. Same for .onion address. + */ case CONNECTION_DOMAIN_INET: recv_len+= 4; break;
tor-commits@lists.torproject.org