[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [torsocks/master] Fix: remove the use of IPv4 sockaddr in connect
commit e9d747f7fe76673b5940dd39e2de3d2caf67132c
Author: David Goulet <dgoulet@xxxxxxxxx>
Date: Thu Feb 20 14:24:23 2014 +0000
Fix: remove the use of IPv4 sockaddr in connect
This modifies the onion find by ip to use generic sockaddr structure.
Also, a utils call is added to extract the port from a sockaddr
structure depending on the family.
This is a step in the direction of fully supported IPv6 thus removing
the use of a cast sockaddr_in.
Signed-off-by: David Goulet <dgoulet@xxxxxxxxx>
---
src/common/onion.c | 16 +++++++++++++---
src/common/onion.h | 2 +-
src/common/utils.c | 24 ++++++++++++++++++++++++
src/common/utils.h | 1 +
src/lib/connect.c | 8 ++------
src/lib/socket.c | 8 ++------
tests/unit/test_onion.c | 5 ++++-
7 files changed, 47 insertions(+), 17 deletions(-)
diff --git a/src/common/onion.c b/src/common/onion.c
index 573ca19..67b4297 100644
--- a/src/common/onion.c
+++ b/src/common/onion.c
@@ -248,14 +248,24 @@ end:
* Return entry on success or else NULL.
*/
ATTR_HIDDEN
-struct onion_entry *onion_entry_find_by_ip(in_addr_t ip,
+struct onion_entry *onion_entry_find_by_addr(const struct sockaddr *sa,
struct onion_pool *pool)
{
int i;
struct onion_entry *entry = NULL;
+ const struct sockaddr_in *sin;
+
+ assert(sa);
+
+ /* Onion cookie are only IPv4. */
+ if (sa->sa_family == AF_INET6) {
+ goto end;
+ }
+
+ sin = (const struct sockaddr_in *) sa;
DBG("[onion] Finding onion entry for IP %s",
- inet_ntoa(*((struct in_addr *) &ip)));
+ inet_ntoa((*((struct in_addr *) &sin->sin_addr.s_addr))));
/*
* XXX: This can be improved by simply getting the offset of the IP with
@@ -264,7 +274,7 @@ struct onion_entry *onion_entry_find_by_ip(in_addr_t ip,
* entries is 45.
*/
for (i = 0; i < pool->count; i++) {
- if (pool->entries[i]->ip == ip) {
+ if (pool->entries[i]->ip == sin->sin_addr.s_addr) {
entry = pool->entries[i];
DBG("[onion] Onion entry name %s found in pool.",
entry->hostname);
diff --git a/src/common/onion.h b/src/common/onion.h
index 90b4d5b..64e8574 100644
--- a/src/common/onion.h
+++ b/src/common/onion.h
@@ -112,7 +112,7 @@ struct onion_entry *onion_entry_create(struct onion_pool *pool,
const char *onion_name);
struct onion_entry *onion_entry_find_by_name(const char *onion_name,
struct onion_pool *pool);
-struct onion_entry *onion_entry_find_by_ip(in_addr_t ip,
+struct onion_entry *onion_entry_find_by_addr(const struct sockaddr *sa,
struct onion_pool *pool);
static inline void onion_pool_lock(struct onion_pool *pool)
diff --git a/src/common/utils.c b/src/common/utils.c
index ba34e33..890bbde 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -344,3 +344,27 @@ int utils_is_addr_any(const struct sockaddr *sa)
end:
return ret;
}
+
+/*
+ * For a given sockaddr, return the port value considering the address family
+ * structure.
+ *
+ * Return the port number in the sockaddr sa or -1 is family is not unknown.
+ */
+ATTR_HIDDEN
+int utils_get_port_from_addr(const struct sockaddr *sa)
+{
+ int port;
+
+ assert(sa);
+
+ if (sa->sa_family == AF_INET) {
+ port = ((const struct sockaddr_in *) sa)->sin_port;
+ } else if (sa->sa_family == AF_INET6) {
+ port = ((const struct sockaddr_in6 *) sa)->sin6_port;
+ } else {
+ port = -1;
+ }
+
+ return port;
+}
diff --git a/src/common/utils.h b/src/common/utils.h
index 2f950aa..83ea825 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -33,5 +33,6 @@ int utils_is_address_ipv6(const char *ip);
int utils_sockaddr_is_localhost(const struct sockaddr *sa);
int utils_localhost_resolve(const char *name, int af, void *buf, size_t len);
int utils_is_addr_any(const struct sockaddr *sa);
+int utils_get_port_from_addr(const struct sockaddr *sa);
#endif /* TORSOCKS_UTILS_H */
diff --git a/src/lib/connect.c b/src/lib/connect.c
index 03f6900..6622119 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -38,7 +38,6 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
socklen_t optlen;
struct connection *new_conn;
struct onion_entry *on_entry;
- struct sockaddr_in *inet_addr;
DBG("Connect catched on fd %d", sockfd);
@@ -77,8 +76,6 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
DBG("[connect] Socket family %s and type %d",
addr->sa_family == AF_INET ? "AF_INET" : "AF_INET6", sock_type);
- inet_addr = (struct sockaddr_in *) addr;
-
/*
* Lock registry to get the connection reference if one. In this code path,
* if a connection object is found, it will not be used since a double
@@ -99,8 +96,7 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
* existing .onion address.
*/
onion_pool_lock(&tsocks_onion_pool);
- on_entry = onion_entry_find_by_ip(inet_addr->sin_addr.s_addr,
- &tsocks_onion_pool);
+ on_entry = onion_entry_find_by_addr(addr, &tsocks_onion_pool);
onion_pool_unlock(&tsocks_onion_pool);
if (on_entry) {
/*
@@ -113,7 +109,7 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
goto error;
}
new_conn->dest_addr.domain = CONNECTION_DOMAIN_NAME;
- new_conn->dest_addr.hostname.port = inet_addr->sin_port;
+ new_conn->dest_addr.hostname.port = utils_get_port_from_addr(addr);
new_conn->dest_addr.hostname.addr = strdup(on_entry->hostname);
if (!new_conn->dest_addr.hostname.addr) {
errno = ENOMEM;
diff --git a/src/lib/socket.c b/src/lib/socket.c
index 36d2a90..cf080b5 100644
--- a/src/lib/socket.c
+++ b/src/lib/socket.c
@@ -33,12 +33,7 @@ LIBC_SOCKET_RET_TYPE tsocks_socket(LIBC_SOCKET_SIG)
domain, type, protocol);
if (type & SOCK_STREAM) {
- if (domain == AF_INET6) {
- /* Tor does not handle IPv6 at the moment. Reject it. */
- ERR("Socket is IPv6. Tor does not handle AF_INET6 connection.");
- errno = EINVAL;
- return -1;
- }
+ goto end;
} else {
if (domain == AF_INET || domain == AF_INET6) {
/*
@@ -56,6 +51,7 @@ LIBC_SOCKET_RET_TYPE tsocks_socket(LIBC_SOCKET_SIG)
}
}
+end:
/* Stream socket for INET/INET6 is good so open it. */
return tsocks_libc_socket(domain, type, protocol);
}
diff --git a/tests/unit/test_onion.c b/tests/unit/test_onion.c
index 0c91f71..c29d5e9 100644
--- a/tests/unit/test_onion.c
+++ b/tests/unit/test_onion.c
@@ -34,6 +34,7 @@ static void test_onion_entry(struct onion_pool *pool)
const char *onion_addr1 = "87idq6tnejk5plpn.onion";
const char *onion_addr2 = "97idq6tnejk5plpn.onion";
const char *onion_addr1_typo = "87idq6tnejk5plpn.onio";
+ struct sockaddr_in sin;
diag("Onion entry subsystem initialization test");
@@ -71,7 +72,9 @@ static void test_onion_entry(struct onion_pool *pool)
inet_ntoa(*((struct in_addr *) &entry->ip))) == 0,
"Valid onion entry found by name");
- entry = onion_entry_find_by_ip(inet_addr(DEFAULT_ONION_ADDR_RANGE), pool);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = inet_addr(DEFAULT_ONION_ADDR_RANGE);
+ entry = onion_entry_find_by_addr((const struct sockaddr *) &sin, pool);
ok(entry &&
pool->count == 1 &&
strcmp(entry->hostname, onion_addr1) == 0 &&
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits