[tor-commits] [torsocks/master] Implement the getaddrinfo(3) torsocks call

dgoulet at torproject.org dgoulet at torproject.org
Fri Apr 4 22:40:25 UTC 2014


commit 5c5707e9684932d7659b4e6166dc1ec9facef317
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Sat Jun 22 20:19:50 2013 -0400

    Implement the getaddrinfo(3) torsocks call
    
    The tor resolve API does not support IPv6 yet at this commit so
    getaddrinfo basically only supports IPv4 for now.
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/lib/torsocks.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/torsocks.h |   17 +++++++++++
 2 files changed, 96 insertions(+)

diff --git a/src/lib/torsocks.c b/src/lib/torsocks.c
index f6e3501..7793e38 100644
--- a/src/lib/torsocks.c
+++ b/src/lib/torsocks.c
@@ -362,6 +362,9 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
 		goto error;
 	}
 
+	DBG("[connect] Socket family %s and type %d",
+			__addr->sa_family == AF_INET ? "AF_INET" : "AF_INET6", sock_type);
+
 	/*
 	 * 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
@@ -478,3 +481,79 @@ LIBC_GETHOSTBYNAME_DECL
 {
 	return tsocks_gethostbyname(LIBC_GETHOSTBYNAME_ARGS);
 }
+
+/*
+ * Torsocks call for getaddrinfo(3).
+ */
+LIBC_GETADDRINFO_RET_TYPE tsocks_getaddrinfo(LIBC_GETADDRINFO_SIG)
+{
+	int ret, af;
+	struct in_addr addr4;
+	struct in6_addr addr6;
+	void *addr;
+	char *ip_str, ipv4[INET_ADDRSTRLEN], ipv6[INET6_ADDRSTRLEN];
+	socklen_t ip_str_size;
+	const char *node;
+
+	DBG("[getaddrinfo] Requesting %s hostname", __node);
+
+	if (!__node) {
+		ret = EAI_NONAME;
+		goto error;
+	}
+
+	/* Use right domain for the next step. */
+	switch (__hints->ai_family) {
+	default:
+		/* Default value is to use IPv4. */
+	case AF_INET:
+		addr = &addr4;
+		ip_str = ipv4;
+		ip_str_size = sizeof(ipv4);
+		af = AF_INET;
+		break;
+	case AF_INET6:
+		addr = &addr6;
+		ip_str = ipv6;
+		ip_str_size = sizeof(ipv6);
+		af = AF_INET6;
+		break;
+	}
+
+	ret = inet_pton(af, __node, &addr);
+	if (ret == 0) {
+		/* The node most probably is a DNS name. */
+		ret = tor_resolve(__node, (uint32_t *) addr);
+		if (ret < 0) {
+			ret = EAI_FAIL;
+			goto error;
+		}
+
+		(void) inet_ntop(af, addr, ip_str, ip_str_size);
+		node = ip_str;
+		DBG("[getaddrinfo] Node %s resolved to %s", __node, node);
+	} else {
+		node = __node;
+		DBG("[getaddrinfo] Node %s will be passed to the libc call", node);
+	}
+
+	ret = tsocks_libc_getaddrinfo(node, __service, __hints, __res);
+	if (ret) {
+		goto error;
+	}
+
+	return 0;
+
+error:
+	return ret;
+}
+
+/*
+ * Libc hijacked symbol getaddrinfo(3).
+ */
+LIBC_GETADDRINFO_DECL
+{
+	tsocks_libc_getaddrinfo = find_libc_symbol(LIBC_GETADDRINFO_NAME_STR,
+			TSOCKS_SYM_EXIT_NOT_FOUND);
+	return tsocks_getaddrinfo(LIBC_GETADDRINFO_ARGS);
+}
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index 7581764..adbe67f 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -64,6 +64,17 @@ char tsocks_he_addr[INET_ADDRSTRLEN];
 #define LIBC_GETHOSTBYNAME_SIG const char *__name
 #define LIBC_GETHOSTBYNAME_ARGS __name
 
+/* getaddrinfo(3) */
+#include <netdb.h>
+
+#define LIBC_GETADDRINFO_NAME getaddrinfo
+#define LIBC_GETADDRINFO_NAME_STR XSTR(LIBC_GETADDRINFO_NAME)
+#define LIBC_GETADDRINFO_RET_TYPE int
+#define LIBC_GETADDRINFO_SIG \
+	const char *__node, const char *__service, const struct addrinfo *__hints,\
+	struct addrinfo **__res
+#define LIBC_GETADDRINFO_ARGS  __node, __service, __hints, __res
+
 #else
 #error "OS not supported."
 #endif /* __linux__ , __FreeBSD__, __darwin__ */
@@ -84,6 +95,12 @@ TSOCKS_LIBC_DECL(gethostbyname, LIBC_GETHOSTBYNAME_RET_TYPE,
 #define LIBC_GETHOSTBYNAME_DECL LIBC_GETHOSTBYNAME_RET_TYPE \
 		LIBC_GETHOSTBYNAME_NAME(LIBC_GETHOSTBYNAME_SIG)
 
+/* getaddrinfo(3) */
+TSOCKS_LIBC_DECL(getaddrinfo, LIBC_GETADDRINFO_RET_TYPE,
+		LIBC_GETADDRINFO_SIG)
+#define LIBC_GETADDRINFO_DECL LIBC_GETADDRINFO_RET_TYPE \
+		LIBC_GETADDRINFO_NAME(LIBC_GETADDRINFO_SIG)
+
 /*
  * Those are actions to do during the lookup process of libc symbols. For
  * instance the connect(2) syscall is essential to Torsocks so the function





More information about the tor-commits mailing list