diff options
-rw-r--r-- | configure.ac | 35 | ||||
-rw-r--r-- | src/or/connection_edge.c | 33 |
2 files changed, 66 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac index e7560b2bfc..88b4da006d 100644 --- a/configure.ac +++ b/configure.ac @@ -937,6 +937,14 @@ AC_CHECK_HEADERS(net/pfvar.h, net_pfvar_found=1, net_pfvar_found=0, #ifdef HAVE_NET_IF_H #include <net/if.h> #endif]) + +AC_CHECK_HEADERS(linux/if.h,[],[], +[ +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +]) + AC_CHECK_HEADERS(linux/netfilter_ipv4.h, linux_netfilter_ipv4=1, linux_netfilter_ipv4=0, [#ifdef HAVE_SYS_TYPES_H @@ -958,6 +966,30 @@ AC_CHECK_HEADERS(linux/netfilter_ipv4.h, #include <netinet/in.h> #endif]) +AC_CHECK_HEADERS(linux/netfilter_ipv6/ip6_tables.h, + linux_netfilter_ipv6_ip6_tables=1, linux_netfilter_ipv6_ip6_tables=0, +[#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#ifdef HAVE_LINUX_TYPES_H +#include <linux/types.h> +#endif +#ifdef HAVE_NETINET_IN6_H +#include <netinet/in6.h> +#endif +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif +#ifdef HAVE_LINUX_IF_H +#include <linux/if.h> +#endif]) + if test x$transparent = xtrue ; then transparent_ok=0 if test x$net_if_found = x1 && test x$net_pfvar_found = x1 ; then @@ -966,6 +998,9 @@ if test x$transparent = xtrue ; then if test x$linux_netfilter_ipv4 = x1 ; then transparent_ok=1 fi + if test x$linux_netfilter_ipv6_ip6_tables = x1 ; then + transparent_ok=1 + fi if test x$transparent_ok = x1 ; then AC_DEFINE(USE_TRANSPARENT, 1, "Define to enable transparent proxy support") case $host in diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index a90ca00883..09645d04b9 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -46,8 +46,20 @@ #ifdef HAVE_LINUX_NETFILTER_IPV4_H #include <linux/netfilter_ipv4.h> #define TRANS_NETFILTER +#define TRANS_NETFILTER_IPV4 #endif +#ifdef HAVE_LINUX_IF_H +#include <linux/if.h> +#endif + +#ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H +#include <linux/netfilter_ipv6/ip6_tables.h> +#define TRANS_NETFILTER +#define TRANS_NETFILTER_IPV6 +#endif + + #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H) #include <net/if.h> #include <net/pfvar.h> @@ -1401,10 +1413,27 @@ destination_from_socket(entry_connection_t *conn, socks_request_t *req) struct sockaddr_storage orig_dst; socklen_t orig_dst_len = sizeof(orig_dst); tor_addr_t addr; + int rv; #ifdef TRANS_NETFILTER - if (getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IP, SO_ORIGINAL_DST, - (struct sockaddr*)&orig_dst, &orig_dst_len) < 0) { + switch (ENTRY_TO_CONN(conn)->socket_family) { +#ifdef TRANS_NETFILTER_IPV4 + case AF_INET: + rv = getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IP, SO_ORIGINAL_DST, + (struct sockaddr*)&orig_dst, &orig_dst_len); + break; +#endif +#ifdef TRANS_NETFILTER_IPV6 + case AF_INET6: + rv = getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IPV6, IP6T_SO_ORIGINAL_DST, + (struct sockaddr*)&orig_dst, &orig_dst_len); + break; +#endif + default: + log_warn(LD_BUG, "Received transparent data from an unsuported socket family."); + return -1; + } + if (rv < 0) { int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s); log_warn(LD_NET, "getsockopt() failed: %s", tor_socket_strerror(e)); return -1; |