[tor-commits] [torsocks/master] Add portable is localhost function

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


commit 50e740492c0a1a547fe56952332c1d6fd2751371
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Fri Feb 7 22:14:30 2014 -0500

    Add portable is localhost function
    
    This removes the utils_is_ipv4_local() call and move to a generic
    portable way of checking if the sockaddr is localhost (both ipv4 and
    ipv6 are supported).
    
    Reported-by: Nick Mathewson <nickm at torproject.org>
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/common/compat.h |   11 +++--------
 src/common/utils.c  |   29 +++++++++++++++++++++++++++++
 src/common/utils.h  |   11 +----------
 src/lib/connect.c   |    7 +++----
 4 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/src/common/compat.h b/src/common/compat.h
index e9a59e7..077bcce 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -98,13 +98,8 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
 
 #endif /* __FreeBSD__, __FreeBSD_kernel__, __darwin__, __NetBSD__ */
 
-/*
- * Shamelessly taken from linux/in.h of the libc. This is consider trivial code
- * by the GPL license thus copying it as is should be OK. Slight modification
- * was made to make the check in host byte order.
- */
-#ifndef IN_LOOPBACK
-#define IN_LOOPBACK(a)      ((((long int) (a)) & 0x000000ff) == 0x0000007f)
-#endif
+#define TSOCKS_CLASSA_NET   0xff000000
+#define TSOCKS_LOOPBACK_NET 0x7f000000
+#define TSOCKS_IN6_INIT     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
 
 #endif /* TORSOCKS_COMPAT_H */
diff --git a/src/common/utils.c b/src/common/utils.c
index 0c5c2c8..4ecb9f4 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -18,12 +18,14 @@
  */
 
 #include <arpa/inet.h>
+#include <netinet/in.h>
 #include <sys/socket.h>
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "compat.h"
 #include "macros.h"
 #include "utils.h"
 
@@ -176,3 +178,30 @@ int utils_strcasecmpend(const char *s1, const char *s2)
 		return strncasecmp(s1 + (n1 - n2), s2, n2);
 	}
 }
+
+/*
+ * Return 1 if the given sockaddr is localhost else 0
+ */
+ATTR_HIDDEN
+int utils_sockaddr_is_localhost(const struct sockaddr *sa)
+{
+	int is_localhost;
+
+	assert(sa);
+
+	if (sa->sa_family == AF_INET) {
+		const struct sockaddr_in *sin = (const struct sockaddr_in *) sa;
+		is_localhost = ((ntohl(sin->sin_addr.s_addr) & TSOCKS_CLASSA_NET) ==
+				TSOCKS_LOOPBACK_NET);
+	} else if (sa->sa_family == AF_INET6) {
+		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *) sa;
+		static const uint8_t addr[] = TSOCKS_IN6_INIT;
+		is_localhost = !memcmp(sin6->sin6_addr.s6_addr, addr,
+				sizeof(sin6->sin6_addr.s6_addr));
+	} else {
+		/* Unknown sockaddr family thus not localhost. */
+		is_localhost = 0;
+	}
+
+	return is_localhost;
+}
diff --git a/src/common/utils.h b/src/common/utils.h
index 474b2df..7721dc5 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -30,15 +30,6 @@ int utils_tokenize_ignore_comments(const char *_line, size_t size, char **tokens
 
 int utils_is_address_ipv4(const char *ip);
 int utils_is_address_ipv6(const char *ip);
-
-/*
- * Check if the given IPv4 is in the loopback net (127.x.x.x).
- *
- * Return 1 if so else 0 if not.
- */
-static inline int utils_is_ipv4_local(in_addr_t addr)
-{
-	return IN_LOOPBACK(addr);
-}
+int utils_sockaddr_is_localhost(const struct sockaddr *sa);
 
 #endif /* TORSOCKS_UTILS_H */
diff --git a/src/lib/connect.c b/src/lib/connect.c
index bdc9e6f..8f34e37 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -109,11 +109,10 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
 		new_conn->dest_addr.hostname.port = inet_addr->sin_port;
 	} else {
 		/*
-		 * Check if address is local IPv4. At this point, we are sure it's not
-		 * a .onion cookie address that is by default in the loopback network.
+		 * Check if address is localhost. At this point, we are sure it's not a
+		 * .onion cookie address that is by default in the loopback network.
 		 */
-		if (__addr->sa_family == AF_INET &&
-				utils_is_ipv4_local(inet_addr->sin_addr.s_addr)) {
+		if (utils_sockaddr_is_localhost(__addr)) {
 			WARN("[connect] Connection to a local address are denied since it "
 					"might be a TCP DNS query to a local DNS server. "
 					"Rejecting it for safety reasons.");





More information about the tor-commits mailing list