[tor-commits] [torsocks/master] Separate libc call in specific files

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


commit cb980d0533539790127ac59509fcce96f8a3e996
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Sun Jun 23 13:20:11 2013 -0400

    Separate libc call in specific files
    
    No code has been changed, only function renaming in torsocks.c and a non
    static function move at the end of torsocks.c
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/lib/Makefile.am     |    3 +-
 src/lib/connect.c       |  117 +++++++++++++++++++++
 src/lib/getaddrinfo.c   |  101 ++++++++++++++++++
 src/lib/gethostbyname.c |   86 ++++++++++++++++
 src/lib/torsocks.c      |  263 +++--------------------------------------------
 src/lib/torsocks.h      |    5 +
 6 files changed, 327 insertions(+), 248 deletions(-)

diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 3c7b3df..bf9237e 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -10,7 +10,8 @@ EXTRA_DIST = torsocks.in usewithtor.in
 
 lib_LTLIBRARIES = libtorsocks.la
 
-libtorsocks_la_SOURCES = torsocks.c torsocks.h
+libtorsocks_la_SOURCES = torsocks.c torsocks.h \
+                         connect.c gethostbyname.c getaddrinfo.c
 
 libtorsocks_la_LIBADD = \
 		$(top_builddir)/src/common/libcommon.la \
diff --git a/src/lib/connect.c b/src/lib/connect.c
new file mode 100644
index 0000000..cee4d76
--- /dev/null
+++ b/src/lib/connect.c
@@ -0,0 +1,117 @@
+/*
+ * 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <assert.h>
+
+#include <common/connection.h>
+#include <common/log.h>
+
+#include "torsocks.h"
+
+/*
+ * Torsocks call for connect(2).
+ */
+LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
+{
+	int ret, sock_type;
+	socklen_t optlen;
+	struct connection *new_conn;
+
+	DBG("Connect catched on fd %d", __sockfd);
+
+	ret = getsockopt(__sockfd, SOL_SOCKET, SO_TYPE, &sock_type, &optlen);
+	if (ret < 0) {
+		/* Use the getsockopt() errno value. */
+		goto error;
+	}
+
+	/* We can't handle a non inet socket. */
+	if (__addr->sa_family != AF_INET &&
+			__addr->sa_family != AF_INET6) {
+		DBG("[conect] Connection is not IPv4/v6. Ignoring.");
+		goto libc_connect;
+	}
+
+	/*
+	 * Refuse non stream socket. There is a chance that this might be a DNS
+	 * request that we can't pass through Tor using raw UDP packet.
+	 */
+	if (sock_type != SOCK_STREAM) {
+		ERR("[connect] UDP or ICMP stream can't be handled. Rejecting.");
+		errno = EBADF;
+		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
+	 * connect() on the same file descriptor is an error so the registry is
+	 * quickly unlocked and no reference is needed.
+	 */
+	connection_registry_lock();
+	new_conn = connection_find(__sockfd);
+	connection_registry_unlock();
+	if (new_conn) {
+		/* Double connect() for the same fd. */
+		errno = EISCONN;
+		goto error;
+	}
+
+	new_conn = connection_create(__sockfd, __addr);
+	if (!new_conn) {
+		errno = ENOMEM;
+		goto error;
+	}
+
+	/* Connect the socket to the Tor network. */
+	ret = tsocks_connect_to_tor(new_conn);
+	if (ret < 0) {
+		errno = -ret;
+		goto error;
+	}
+
+	connection_registry_lock();
+	/* This can't fail since a lookup was done previously. */
+	connection_insert(new_conn);
+	connection_registry_unlock();
+
+	/* Flag errno for success */
+	ret = errno = 0;
+	return ret;
+
+libc_connect:
+	return tsocks_libc_connect(LIBC_CONNECT_ARGS);
+error:
+	/* At this point, errno MUST be set to a valid connect() error value. */
+	return -1;
+}
+
+/*
+ * Libc hijacked symbol connect(2).
+ */
+LIBC_CONNECT_DECL
+{
+	/* Find symbol if not already set. Exit if not found. */
+	tsocks_libc_connect = tsocks_find_libc_symbol(LIBC_CONNECT_NAME_STR,
+			TSOCKS_SYM_EXIT_NOT_FOUND);
+	return tsocks_connect(LIBC_CONNECT_ARGS);
+}
diff --git a/src/lib/getaddrinfo.c b/src/lib/getaddrinfo.c
new file mode 100644
index 0000000..683bfc7
--- /dev/null
+++ b/src/lib/getaddrinfo.c
@@ -0,0 +1,101 @@
+/*
+ * 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <arpa/inet.h>
+#include <assert.h>
+
+#include <common/log.h>
+
+#include "torsocks.h"
+
+/*
+ * 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 = tsocks_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 = tsocks_find_libc_symbol(LIBC_GETADDRINFO_NAME_STR,
+			TSOCKS_SYM_EXIT_NOT_FOUND);
+	return tsocks_getaddrinfo(LIBC_GETADDRINFO_ARGS);
+}
diff --git a/src/lib/gethostbyname.c b/src/lib/gethostbyname.c
new file mode 100644
index 0000000..58a7290
--- /dev/null
+++ b/src/lib/gethostbyname.c
@@ -0,0 +1,86 @@
+/*
+ * 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
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <arpa/inet.h>
+#include <assert.h>
+
+#include <common/log.h>
+
+#include "torsocks.h"
+/*
+ * Torsocks call for gethostbyname(3).
+ *
+ * NOTE: This call is OBSOLETE in the glibc.
+ */
+LIBC_GETHOSTBYNAME_RET_TYPE tsocks_gethostbyname(LIBC_GETHOSTBYNAME_SIG)
+{
+	int ret;
+	uint32_t ip;
+	const char *ret_str;
+
+	DBG("[gethostbyname] Requesting %s hostname", __name);
+
+	if (!__name) {
+		h_errno = HOST_NOT_FOUND;
+		goto error;
+	}
+
+	/* Resolve the given hostname through Tor. */
+	ret = tsocks_tor_resolve(__name, &ip);
+	if (ret < 0) {
+		goto error;
+	}
+
+	/* Reset static host entry of tsocks. */
+	memset(&tsocks_he, 0, sizeof(tsocks_he));
+	memset(tsocks_he_addr_list, 0, sizeof(tsocks_he_addr_list));
+	memset(tsocks_he_addr, 0, sizeof(tsocks_he_addr));
+
+	ret_str = inet_ntop(AF_INET, &ip, tsocks_he_addr, sizeof(tsocks_he_addr));
+	if (!ret_str) {
+		PERROR("inet_ntop");
+		h_errno = NO_ADDRESS;
+		goto error;
+	}
+
+	tsocks_he_addr_list[0] = tsocks_he_addr;
+	tsocks_he_addr_list[1] = NULL;
+
+	tsocks_he.h_name = (char *) __name;
+	tsocks_he.h_aliases = NULL;
+	tsocks_he.h_length = sizeof(in_addr_t);
+	tsocks_he.h_addrtype = AF_INET;
+	tsocks_he.h_addr_list = tsocks_he_addr_list;
+
+	DBG("Hostname %s resolved to %s", __name, tsocks_he_addr);
+
+	errno = 0;
+	return &tsocks_he;
+
+error:
+	return NULL;
+}
+
+/*
+ * Libc hijacked symbol gethostbyname(3).
+ */
+LIBC_GETHOSTBYNAME_DECL
+{
+	return tsocks_gethostbyname(LIBC_GETHOSTBYNAME_ARGS);
+}
diff --git a/src/lib/torsocks.c b/src/lib/torsocks.c
index 7793e38..28cd183 100644
--- a/src/lib/torsocks.c
+++ b/src/lib/torsocks.c
@@ -17,7 +17,6 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <arpa/inet.h>
 #include <assert.h>
 #include <dlfcn.h>
 #include <stdlib.h>
@@ -54,30 +53,6 @@ static void clean_exit(int status)
 }
 
 /*
- * Lookup symbol in the loaded libraries of the binary.
- *
- * Return the function pointer or NULL on error.
- */
-static void *find_libc_symbol(const char *symbol,
-		enum tsocks_sym_action action)
-{
-	void *fct_ptr = NULL;
-
-	assert(symbol);
-
-	fct_ptr = dlsym(RTLD_NEXT, symbol);
-	if (!fct_ptr) {
-		ERR("Unable to find %s", symbol);
-		if (action == TSOCKS_SYM_EXIT_NOT_FOUND) {
-			ERR("This is critical for torsocks. Exiting");
-			clean_exit(EXIT_FAILURE);
-		}
-	}
-
-	return fct_ptr;
-}
-
-/*
  * Initialize torsocks configuration from a given conf file or the default one.
  */
 static void init_config(void)
@@ -130,7 +105,7 @@ static void init_config(void)
  */
 static void init_libc_symbols(void)
 {
-	tsocks_libc_connect = find_libc_symbol(LIBC_CONNECT_NAME_STR,
+	tsocks_libc_connect = tsocks_find_libc_symbol(LIBC_CONNECT_NAME_STR,
 			TSOCKS_SYM_EXIT_NOT_FOUND);
 }
 
@@ -255,7 +230,7 @@ error:
  * Return 0 on success or else a negative value being the errno value that
  * needs to be sent back.
  */
-static int connect_to_tor_network(struct connection *conn)
+int tsocks_connect_to_tor(struct connection *conn)
 {
 	int ret;
 
@@ -287,7 +262,7 @@ error:
  *
  * Return 0 on success else a negative value and the result addr is untouched.
  */
-static int tor_resolve(const char *hostname, uint32_t *ip_addr)
+int tsocks_tor_resolve(const char *hostname, uint32_t *ip_addr)
 {
 	int ret;
 	struct connection conn;
@@ -329,231 +304,25 @@ error:
 }
 
 /*
- * Torsocks call for connect(2).
- */
-LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
-{
-	int ret, sock_type;
-	socklen_t optlen;
-	struct connection *new_conn;
-
-	DBG("Connect catched on fd %d", __sockfd);
-
-	ret = getsockopt(__sockfd, SOL_SOCKET, SO_TYPE, &sock_type, &optlen);
-	if (ret < 0) {
-		/* Use the getsockopt() errno value. */
-		goto error;
-	}
-
-	/* We can't handle a non inet socket. */
-	if (__addr->sa_family != AF_INET &&
-			__addr->sa_family != AF_INET6) {
-		DBG("[conect] Connection is not IPv4/v6. Ignoring.");
-		goto libc_connect;
-	}
-
-	/*
-	 * Refuse non stream socket. There is a chance that this might be a DNS
-	 * request that we can't pass through Tor using raw UDP packet.
-	 */
-	if (sock_type != SOCK_STREAM) {
-		ERR("[connect] UDP or ICMP stream can't be handled. Rejecting.");
-		errno = EBADF;
-		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
-	 * connect() on the same file descriptor is an error so the registry is
-	 * quickly unlocked and no reference is needed.
-	 */
-	connection_registry_lock();
-	new_conn = connection_find(__sockfd);
-	connection_registry_unlock();
-	if (new_conn) {
-		/* Double connect() for the same fd. */
-		errno = EISCONN;
-		goto error;
-	}
-
-	new_conn = connection_create(__sockfd, __addr);
-	if (!new_conn) {
-		errno = ENOMEM;
-		goto error;
-	}
-
-	/* Connect the socket to the Tor network. */
-	ret = connect_to_tor_network(new_conn);
-	if (ret < 0) {
-		errno = -ret;
-		goto error;
-	}
-
-	connection_registry_lock();
-	/* This can't fail since a lookup was done previously. */
-	connection_insert(new_conn);
-	connection_registry_unlock();
-
-	/* Flag errno for success */
-	ret = errno = 0;
-	return ret;
-
-libc_connect:
-	return tsocks_libc_connect(LIBC_CONNECT_ARGS);
-error:
-	/* At this point, errno MUST be set to a valid connect() error value. */
-	return -1;
-}
-
-/*
- * Libc hijacked symbol connect(2).
- */
-LIBC_CONNECT_DECL
-{
-	/* Find symbol if not already set. Exit if not found. */
-	tsocks_libc_connect = find_libc_symbol(LIBC_CONNECT_NAME_STR,
-			TSOCKS_SYM_EXIT_NOT_FOUND);
-	return tsocks_connect(LIBC_CONNECT_ARGS);
-}
-
-/*
- * Torsocks call for gethostbyname(3).
+ * Lookup symbol in the loaded libraries of the binary.
  *
- * NOTE: This call is OBSOLETE in the glibc.
- */
-LIBC_GETHOSTBYNAME_RET_TYPE tsocks_gethostbyname(LIBC_GETHOSTBYNAME_SIG)
-{
-	int ret;
-	uint32_t ip;
-	const char *ret_str;
-
-	DBG("[gethostbyname] Requesting %s hostname", __name);
-
-	if (!__name) {
-		h_errno = HOST_NOT_FOUND;
-		goto error;
-	}
-
-	/* Resolve the given hostname through Tor. */
-	ret = tor_resolve(__name, &ip);
-	if (ret < 0) {
-		goto error;
-	}
-
-	/* Reset static host entry of tsocks. */
-	memset(&tsocks_he, 0, sizeof(tsocks_he));
-	memset(tsocks_he_addr_list, 0, sizeof(tsocks_he_addr_list));
-	memset(tsocks_he_addr, 0, sizeof(tsocks_he_addr));
-
-	ret_str = inet_ntop(AF_INET, &ip, tsocks_he_addr, sizeof(tsocks_he_addr));
-	if (!ret_str) {
-		PERROR("inet_ntop");
-		h_errno = NO_ADDRESS;
-		goto error;
-	}
-
-	tsocks_he_addr_list[0] = tsocks_he_addr;
-	tsocks_he_addr_list[1] = NULL;
-
-	tsocks_he.h_name = (char *) __name;
-	tsocks_he.h_aliases = NULL;
-	tsocks_he.h_length = sizeof(in_addr_t);
-	tsocks_he.h_addrtype = AF_INET;
-	tsocks_he.h_addr_list = tsocks_he_addr_list;
-
-	DBG("Hostname %s resolved to %s", __name, tsocks_he_addr);
-
-	errno = 0;
-	return &tsocks_he;
-
-error:
-	return NULL;
-}
-
-/*
- * Libc hijacked symbol gethostbyname(3).
- */
-LIBC_GETHOSTBYNAME_DECL
-{
-	return tsocks_gethostbyname(LIBC_GETHOSTBYNAME_ARGS);
-}
-
-/*
- * Torsocks call for getaddrinfo(3).
+ * Return the function pointer or NULL on error.
  */
-LIBC_GETADDRINFO_RET_TYPE tsocks_getaddrinfo(LIBC_GETADDRINFO_SIG)
+void *tsocks_find_libc_symbol(const char *symbol,
+		enum tsocks_sym_action action)
 {
-	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;
-	}
+	void *fct_ptr = NULL;
 
-	/* 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;
-	}
+	assert(symbol);
 
-	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;
+	fct_ptr = dlsym(RTLD_NEXT, symbol);
+	if (!fct_ptr) {
+		ERR("Unable to find %s", symbol);
+		if (action == TSOCKS_SYM_EXIT_NOT_FOUND) {
+			ERR("This is critical for torsocks. Exiting");
+			clean_exit(EXIT_FAILURE);
 		}
-
-		(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);
+	return fct_ptr;
 }
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index adbe67f..de62c33 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -114,4 +114,9 @@ enum tsocks_sym_action {
 /* Global configuration. Initialized once in the library constructor. */
 extern struct configuration tsocks_config;
 
+int tsocks_connect_to_tor(struct connection *conn);
+void *tsocks_find_libc_symbol(const char *symbol,
+		enum tsocks_sym_action action);
+int tsocks_tor_resolve(const char *hostname, uint32_t *ip_addr);
+
 #endif /* TORSOCKS_H */





More information about the tor-commits mailing list