[tor-commits] [torsocks/master] Add reentrant functions gethostby*

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


commit c4f9f73a392b9f360d3a2b25e9ac5607e2b83230
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Tue Aug 6 08:05:30 2013 -0400

    Add reentrant functions gethostby*
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/lib/gethostbyname.c |  111 +++++++++++++++++++++++++++++++++++++++++++++--
 src/lib/torsocks.h      |   32 ++++++++++++++
 2 files changed, 140 insertions(+), 3 deletions(-)

diff --git a/src/lib/gethostbyname.c b/src/lib/gethostbyname.c
index af47e73..87dace1 100644
--- a/src/lib/gethostbyname.c
+++ b/src/lib/gethostbyname.c
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2000-2008 - Shaun Clowes <delius at progsoc.org> 
- * 				 2008-2011 - Robert Hogan <robert at roberthogan.net>
- * 				 	  2013 - David Goulet <dgoulet at ev0ke.net>
+ * Copyright (C) 2000-2008 - Shaun Clowes <delius at progsoc.org> 2008-2011 -
+ * Robert Hogan <robert at roberthogan.net> 2013 - David Goulet
+ * <dgoulet at ev0ke.net>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License, version 2 only, as
@@ -374,3 +374,108 @@ LIBC_GETHOSTBYADDR_R_DECL
 {
 	return tsocks_gethostbyaddr_r(LIBC_GETHOSTBYADDR_R_ARGS);
 }
+
+/*
+ * Torsocks call for gethostbyname(3).
+ *
+ * NOTE: GNU extension. Reentrant version.
+ */
+LIBC_GETHOSTBYNAME_R_RET_TYPE tsocks_gethostbyname_r(LIBC_GETHOSTBYNAME_R_SIG)
+{
+	int ret;
+	/* This call is always using AF_INET. */
+	uint32_t ip;
+	const char *ret_str;
+	struct hostent *he = NULL;
+
+	struct data {
+		char addr[INET_ADDRSTRLEN];
+		char *addr_list[2];
+		char padding[];
+	} *data;
+
+	DBG("[gethostbyname_r] Requesting %s hostname", __name);
+
+	if (!__name) {
+		*__h_errnop = HOST_NOT_FOUND;
+		ret = -1;
+		goto error;
+	}
+
+	if (__buflen < sizeof(*data)) {
+		ret = ERANGE;
+		goto error;
+	}
+
+	/* Resolve the given hostname through Tor. */
+	ret = tsocks_tor_resolve(__name, &ip);
+	if (ret < 0) {
+		goto error;
+	}
+
+	data = (struct data *) __buf;
+	memset(data, 0, sizeof(*data));
+	/* Ease our life a bit. */
+	he = __ret;
+
+	ret_str = inet_ntop(AF_INET, &ip, data->addr, sizeof(data->addr));
+	if (!ret_str) {
+		PERROR("inet_ntop");
+		*__h_errnop = NO_ADDRESS;
+		goto error;
+	}
+
+	memcpy(data->addr, &ip, sizeof(ip));
+	data->addr_list[0] = data->addr;
+	data->addr_list[1] = NULL;
+	he->h_addr_list = data->addr_list;
+
+	he->h_name = (char *) __name;
+	he->h_aliases = NULL;
+	he->h_length = sizeof(in_addr_t);
+	he->h_addrtype = AF_INET;
+
+	DBG("[gethostbyname_r] Hostname %s resolved to %s", __name,
+			inet_ntoa(*((struct in_addr *) &ip)));
+
+error:
+	return ret;
+}
+
+/*
+ * Libc hijacked symbol gethostbyname_r(3).
+ */
+LIBC_GETHOSTBYNAME_R_DECL
+{
+	return tsocks_gethostbyname_r(LIBC_GETHOSTBYNAME_R_ARGS);
+}
+
+/*
+ * Torsocks call for gethostbyname(3).
+ *
+ * NOTE: GNU extension. Reentrant version.
+ */
+LIBC_GETHOSTBYNAME2_R_RET_TYPE tsocks_gethostbyname2_r(LIBC_GETHOSTBYNAME2_R_SIG)
+{
+	DBG("[gethostbyname2_r] Requesting %s hostname", __name);
+
+	/*
+	 * For now, there is no way of resolving a domain name to IPv6 through Tor
+	 * so only accept INET request thus using the original gethostbyname().
+	 */
+	if (__af != AF_INET) {
+		*__h_errnop = HOST_NOT_FOUND;
+		return -1;
+	}
+
+	return tsocks_gethostbyname_r(__name, __ret, __buf, __buflen, __result,
+			__h_errnop);
+}
+
+/*
+ * Libc hijacked symbol gethostbyname2_r(3).
+ */
+LIBC_GETHOSTBYNAME2_R_DECL
+{
+	return tsocks_gethostbyname2_r(LIBC_GETHOSTBYNAME2_R_ARGS);
+}
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index 55d46d6..f1a93ef 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -81,6 +81,26 @@ char tsocks_he_name[255];
 #define LIBC_GETHOSTBYNAME2_SIG const char *__name, int __af
 #define LIBC_GETHOSTBYNAME2_ARGS __name, __af
 
+/* GNU extension. Reentrant version. */
+#define LIBC_GETHOSTBYNAME_R_NAME gethostbyname_r
+#define LIBC_GETHOSTBYNAME_R_NAME_STR XSTR(LIBC_GETHOSTBYNAME_R_NAME)
+#define LIBC_GETHOSTBYNAME_R_RET_TYPE int
+#define LIBC_GETHOSTBYNAME_R_SIG const char *__name, \
+	struct hostent *__ret, char *__buf, size_t __buflen, \
+	struct hostent **__result, int *__h_errnop
+#define LIBC_GETHOSTBYNAME_R_ARGS __name, __ret, __buf, \
+	__buflen, __result, __h_errnop
+
+/* GNU extension. Reentrant version 2. */
+#define LIBC_GETHOSTBYNAME2_R_NAME gethostbyname2_r
+#define LIBC_GETHOSTBYNAME2_R_NAME_STR XSTR(LIBC_GETHOSTBYNAME2_R_NAME)
+#define LIBC_GETHOSTBYNAME2_R_RET_TYPE int
+#define LIBC_GETHOSTBYNAME2_R_SIG const char *__name, int __af, \
+	struct hostent *__ret, char *__buf, size_t __buflen, \
+struct hostent **__result, int *__h_errnop
+#define LIBC_GETHOSTBYNAME2_R_ARGS __name, __af, __ret, __buf, \
+	__buflen, __result, __h_errnop
+
 /* gethostbyaddr(3) - DEPRECATED in glibc. */
 #include <sys/socket.h>
 
@@ -146,12 +166,24 @@ TSOCKS_LIBC_DECL(gethostbyname, LIBC_GETHOSTBYNAME_RET_TYPE,
 #define LIBC_GETHOSTBYNAME_DECL LIBC_GETHOSTBYNAME_RET_TYPE \
 		LIBC_GETHOSTBYNAME_NAME(LIBC_GETHOSTBYNAME_SIG)
 
+/* gethostbyname_r(3) */
+TSOCKS_LIBC_DECL(gethostbyname_r, LIBC_GETHOSTBYNAME_R_RET_TYPE,
+		LIBC_GETHOSTBYNAME_R_SIG)
+#define LIBC_GETHOSTBYNAME_R_DECL LIBC_GETHOSTBYNAME_R_RET_TYPE \
+		LIBC_GETHOSTBYNAME_R_NAME(LIBC_GETHOSTBYNAME_R_SIG)
+
 /* gethostbyname2(3) */
 TSOCKS_LIBC_DECL(gethostbyname2, LIBC_GETHOSTBYNAME2_RET_TYPE,
 		LIBC_GETHOSTBYNAME2_SIG)
 #define LIBC_GETHOSTBYNAME2_DECL LIBC_GETHOSTBYNAME2_RET_TYPE \
 		LIBC_GETHOSTBYNAME2_NAME(LIBC_GETHOSTBYNAME2_SIG)
 
+/* gethostbyname2_r(3) */
+TSOCKS_LIBC_DECL(gethostbyname2_r, LIBC_GETHOSTBYNAME2_R_RET_TYPE,
+		LIBC_GETHOSTBYNAME2_R_SIG)
+#define LIBC_GETHOSTBYNAME2_R_DECL LIBC_GETHOSTBYNAME2_R_RET_TYPE \
+		LIBC_GETHOSTBYNAME2_R_NAME(LIBC_GETHOSTBYNAME2_R_SIG)
+
 /* gethostbyaddr(3) */
 TSOCKS_LIBC_DECL(gethostbyaddr, LIBC_GETHOSTBYADDR_RET_TYPE,
 		LIBC_GETHOSTBYADDR_SIG)





More information about the tor-commits mailing list