Commit 39e71d8f authored by Francisco Blas Izquierdo Riera (klondike)'s avatar Francisco Blas Izquierdo Riera (klondike) Committed by Nick Mathewson
Browse files

Use the appropriate call to getsockopt for IPv6 sockets



The original call to getsockopt to know the original address on transparently
proxyed sockets using REDIRECT in iptables failed with IPv6 addresses because
it assumed all sockets used IPv4.

This patch fixes this by using the appropriate options and adding the headers
containing the needed definitions for these.

This patch is released under the same license as the original file as
long as the author iscredited.
Signed-off-by: default avatarFrancisco Blas Izquierdo Riera (klondike) <klondike@gentoo.org>
parent 808e2b85
......@@ -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
......
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment