Hi Henrik, Amos, etc

I've been trying to compile Squid-2.7.STABLE8 (squid-2.HEAD-20100222)
but am having difficulty applying the Visolve TProxy-4 patch
 * http://www.visolve.com/squid/squid-tproxy.php

The patch no longer applies cleanly. I spent some time trying to
resolve the conflicts, and after successful compilation, Squid is
listening on its port, but also complains to cachelog as follows and
it's not spoofing the source IP:
{{{
Accepting proxy HTTP connections at 192.168.251.106, port 800, FD 27.
...
commBind: Cannot bind socket FD 31 to 192.168.251.106:800: (98)
Address already in use
}}}

I'm compiling on an Ubuntu 9.10 machine with Linux kernel
2.6.31-19-generic and Linux headers packages installed
{{{
aptitude search ~ilinux-headers
i   linux-headers-2.6.31-19
   - Header files related to Linux kernel version 2.6.31
i   linux-headers-2.6.31-19-generic
   - Linux kernel headers for version 2.6.31 on x86/x86_64
i A linux-headers-generic
   - Generic Linux kernel headers
}}}

I'm deploying this on a Slackware based box with custom Linux Kernel
2.6.31.6 (TProxy module enabled)
{{{
cachebox# dmesg  | grep -i tproxy
NF_TPROXY: Transparent proxy support initialized, version 4.1.0
NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd.
}}}

I think the problem might be caused by this recent patch to the libcap
code, particularly - around tools.c:
 * http://www.squid-cache.org/Versions/v2/HEAD/changesets/12640.patch

It looked like the changes to tools.c that had previously been applied
by the Tproxy patch are now part of the 2.7 tree, but re-factored
slightly. Then again I may be totally off the mark :)

I've attached my latest version of the patch in which I rejected all
the Tproxy changes to tools.c.

Has anyone already prepared a more up to date version of the Tproxy
patch? If not, I'd like to help fix the patch, but perhaps someone can
quickly summarise what might be the problem and what needs doing.

-RichardW.
Index: configure
===================================================================
--- configure	(revision 9786)
+++ configure	(working copy)
@@ -9554,7 +9554,6 @@
 	grp.h \
 	libc.h \
 	linux/netfilter_ipv4.h \
-	linux/netfilter_ipv4/ip_tproxy.h \
 	malloc.h \
 	math.h \
 	memory.h \
@@ -29104,10 +29103,10 @@
 fi
 
 if test "$LINUX_TPROXY"; then
-    { $as_echo "$as_me:$LINENO: checking if TPROXY header files are installed" >&5
-$as_echo_n "checking if TPROXY header files are installed... " >&6; }
+    { echo "$as_me:$LINENO: checking if sys/capability header files are installed" >&5
+echo $ECHO_N "checking if sys/capability header files are installed... $ECHO_C" >&6; }
     # hold on to your hats...
-    if test "$ac_cv_header_linux_netfilter_ipv4_ip_tproxy_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then
+    if test "$ac_cv_header_sys_capability_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then
 	LINUX_TPROXY="yes"
 
 cat >>confdefs.h <<\_ACEOF
@@ -29122,8 +29121,12 @@
 _ACEOF
 
     fi
-    { $as_echo "$as_me:$LINENO: result: $LINUX_TPROXY" >&5
-$as_echo "$LINUX_TPROXY" >&6; }
+    { echo "$as_me:$LINENO: result: $LINUX_TPROXY" >&5
+echo "${ECHO_T}$LINUX_TPROXY" >&6; }
+
+    if test "$LINUX_TPROXY" = "no"  ; then
+        echo "WARNING: Cannot find necessary system capability headers files"
+        echo "         Linux TProxy-4 support WILL NOT be enabled"
     if test "$use_libcap" != "yes"; then
        { $as_echo "$as_me:$LINENO: WARNING: Missing needed capabilities (libcap or libcap2) for TPROXY" >&5
 $as_echo "$as_me: WARNING: Missing needed capabilities (libcap or libcap2) for TPROXY" >&2;}
@@ -29131,11 +29134,6 @@
        sleep 10
     fi
 fi
-if test "$LINUX_TPROXY" = "no" && test "$LINUX_NETFILTER" = "yes"; then
-    echo "WARNING: Cannot find TPROXY headers, you need to patch your kernel with the"
-    echo "tproxy package from:"
-    echo " - lynx http://www.balabit.com/downloads/files/tproxy/";
-    sleep 10
 fi
 
 if test -z "$USE_GNUREGEX" ; then
Index: configure.in
===================================================================
--- configure.in	(revision 9786)
+++ configure.in	(working copy)
@@ -1802,7 +1802,6 @@
 	grp.h \
 	libc.h \
 	linux/netfilter_ipv4.h \
-	linux/netfilter_ipv4/ip_tproxy.h \
 	malloc.h \
 	math.h \
 	memory.h \
@@ -2946,9 +2945,9 @@
 dnl Linux Netfilter/TPROXY support requires some specific header files and libcap
 dnl Shamelessly copied from shamelessly copied from above
 if test "$LINUX_TPROXY"; then
-    AC_MSG_CHECKING(if TPROXY header files are installed)
+    AC_MSG_CHECKING(if sys/capability header files are installed)
     # hold on to your hats...
-    if test "$ac_cv_header_linux_netfilter_ipv4_ip_tproxy_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then
+    if test "$ac_cv_header_sys_capability_h" = "yes" && test "$LINUX_NETFILTER" = "yes"; then
 	LINUX_TPROXY="yes"
 	AC_DEFINE(LINUX_TPROXY, 1, [Enable real Transparent Proxy support for Netfilter TPROXY.])
     else
@@ -2961,13 +2960,12 @@
        LINUX_TPROXY="no"
        sleep 10
     fi
+
+    if test "$LINUX_TPROXY" = "no"  ; then
+        echo "WARNING: Cannot find necessary system capability headers files"
+        echo "         Linux TProxy-4 support WILL NOT be enabled"
+    fi
 fi
-if test "$LINUX_TPROXY" = "no" && test "$LINUX_NETFILTER" = "yes"; then
-    echo "WARNING: Cannot find TPROXY headers, you need to patch your kernel with the"
-    echo "tproxy package from:"
-    echo " - lynx http://www.balabit.com/downloads/files/tproxy/";
-    sleep 10
-fi
 
 if test -z "$USE_GNUREGEX" ; then
     case "$host" in
Index: src/ssl.c
===================================================================
--- src/ssl.c	(revision 9786)
+++ src/ssl.c	(working copy)
@@ -499,6 +499,11 @@
     char *url = http->uri;
     struct in_addr outgoing;
     unsigned long tos;
+#ifdef LINUX_TPROXY
+    int flags;
+#endif
+
+
     /*
      * client_addr == no_addr indicates this is an "internal" request
      * from peer_digest.c, asn.c, netdb.c, etc and should always
@@ -522,11 +527,17 @@
     outgoing = getOutgoingAddr(request);
     tos = getOutgoingTOS(request);
     /* Create socket. */
+    flags = COMM_NONBLOCKING;
+#ifdef LINUX_TPROXY
+    if (request->flags.tproxy) {
+	flags |= COMM_TRANSPARENT;
+    }
+#endif
     sock = comm_openex(SOCK_STREAM,
 	IPPROTO_TCP,
 	outgoing,
 	0,
-	COMM_NONBLOCKING,
+	flags,
 	tos,
 	url);
     if (sock == COMM_ERROR) {
Index: src/structs.h
===================================================================
--- src/structs.h	(revision 9786)
+++ src/structs.h	(working copy)
@@ -942,6 +942,7 @@
 	unsigned int close_on_exec:1;
 	unsigned int backoff:1;	/* keep track of whether the fd is backed off */
 	unsigned int dnsfailed:1;	/* did the dns lookup fail */
+        unsigned int transparent:1;
     } flags;
     comm_pending read_pending;
     comm_pending write_pending;
Index: src/defines.h
===================================================================
--- src/defines.h	(revision 9786)
+++ src/defines.h	(working copy)
@@ -93,6 +93,9 @@
 #define COMM_NONBLOCKING	0x01
 #define COMM_NOCLOEXEC		0x02
 #define COMM_REUSEADDR		0x04
+#ifdef LINUX_TPROXY
+#define COMM_TRANSPARENT	0x08
+#endif
 
 #define do_debug(SECTION, LEVEL) \
 	((_db_level = (LEVEL)) <= debugLevels[SECTION])
Index: src/comm.c
===================================================================
--- src/comm.c	(revision 9786)
+++ src/comm.c	(working copy)
@@ -47,6 +47,12 @@
 #include <netinet/tcp.h>
 #endif
 
+#ifdef LINUX_TPROXY
+#ifndef IP_TRANSPARENT
+#define IP_TRANSPARENT 19
+#endif
+#endif
+
 typedef struct {
     char *host;
     u_short port;
@@ -65,6 +71,9 @@
 static void commSetReuseAddr(int);
 static void commSetNoLinger(int);
 static void CommWriteStateCallbackAndFree(int fd, int code);
+#ifdef LINUX_TPROXY
+static void commSetTransparent(int);
+#endif
 #ifdef TCP_NODELAY
 static void commSetTcpNoDelay(int);
 #endif
@@ -258,6 +267,12 @@
 	if (opt_reuseaddr)
 	    commSetReuseAddr(new_socket);
     }
+#ifdef LINUX_TPROXY
+    if (flags & COMM_TRANSPARENT) {
+	F->flags.transparent = 1;
+	commSetTransparent(new_socket);
+    }
+#endif
     if (addr.s_addr != no_addr.s_addr) {
 	if (commBind(new_socket, addr, port) != COMM_OK) {
 	    comm_close(new_socket);
@@ -435,6 +450,12 @@
      * yuck, this has assumptions about comm_open() arguments for
      * the original socket
      */
+#ifdef LINUX_TPROXY
+    if (F->flags.transparent) {
+	commSetTransparent(cs->fd);
+    }
+#endif
+
     if (commBind(cs->fd, F->local_addr, F->local_port) != COMM_OK) {
 	debug(5, 0) ("commResetFD: bind: %s\n", xstrerror());
 	return 0;
@@ -1534,3 +1555,19 @@
 	}
     }
 }
+
+#ifdef LINUX_TPROXY
+static void
+commSetTransparent(int fd)
+{
+    int on = 1;
+    debug(5, 3) ("commSetTransparent: FD %d\n", fd);
+    if (setsockopt(fd, SOL_IP, IP_TRANSPARENT, (char*)&on, sizeof(on)) < 0) {
+	debug(5, 1) ("commSetTransparent: FD %d: %s\n", fd, xstrerror());
+    } 
+    fd_table[fd].flags.transparent = 1;
+}
+#endif
+
+
+
Index: src/forward.c
===================================================================
--- src/forward.c	(revision 9786)
+++ src/forward.c	(working copy)
@@ -40,9 +40,6 @@
 #include <linux/types.h>
 #include <linux/netfilter_ipv4.h>
 #endif
-#if LINUX_TPROXY
-#include <linux/netfilter_ipv4/ip_tproxy.h>
-#endif
 
 static PSC fwdStartComplete;
 static void fwdDispatch(FwdState *);
@@ -515,7 +512,7 @@
     struct in_addr outgoing;
     unsigned short tos;
 #if LINUX_TPROXY
-    struct in_tproxy itp;
+    int flags;
 #endif
     int idle = -1;
 
@@ -624,11 +621,19 @@
 
     debug(17, 3) ("fwdConnectStart: got addr %s, tos %d\n",
 	inet_ntoa(outgoing), tos);
+    flags = COMM_NONBLOCKING;
+#ifdef LINUX_TPROXY
+    if ((outgoing.s_addr == INADDR_ANY) && fwdState->request->flags.tproxy) {
+        outgoing = fwdState->request->client_addr;
+        flags |= COMM_TRANSPARENT;
+        debug(17,3)("fwdConnectStart: setting outgoing.s_addr=%08X (will set TRANSPARENT)\n", outgoing.s_addr);
+    } 
+#endif
     fd = comm_openex(SOCK_STREAM,
 	IPPROTO_TCP,
 	outgoing,
 	0,
-	COMM_NONBLOCKING,
+	flags,
 	tos,
 	url);
     if (fd < 0) {
@@ -661,32 +666,6 @@
     if (fs->peer) {
 	hierarchyNote(&fwdState->request->hier, fs->code, fs->peer->name);
     } else {
-#if LINUX_TPROXY
-	if (fwdState->request->flags.tproxy) {
-
-	    itp.v.addr.faddr.s_addr = fwdState->src.sin_addr.s_addr;
-	    itp.v.addr.fport = 0;
-
-	    /* If these syscalls fail then we just fallback to connecting
-	     * normally by simply ignoring the errors...
-	     */
-	    itp.op = TPROXY_ASSIGN;
-	    if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) {
-		debug(20, 1) ("tproxy ip=%s,0x%x,port=%d ERROR ASSIGN\n",
-		    inet_ntoa(itp.v.addr.faddr),
-		    itp.v.addr.faddr.s_addr,
-		    itp.v.addr.fport);
-	    } else {
-		itp.op = TPROXY_FLAGS;
-		itp.v.flags = ITP_CONNECT;
-		if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) {
-		    debug(20, 1) ("tproxy ip=%x,port=%d ERROR CONNECT\n",
-			itp.v.addr.faddr.s_addr,
-			itp.v.addr.fport);
-		}
-	    }
-	}
-#endif
 	hierarchyNote(&fwdState->request->hier, fs->code, fwdState->request->host);
     }
 
Index: src/client_side.c
===================================================================
--- src/client_side.c	(revision 9786)
+++ src/client_side.c	(working copy)
@@ -5172,6 +5172,7 @@
 {
     http_port_list *s;
     int fd;
+    int flags;
     for (s = Config.Sockaddr.http; s; s = s->next) {
 	if (MAXHTTPPORTS == NHttpSockets) {
 	    debug(1, 1) ("WARNING: You have too many 'http_port' lines.\n");
@@ -5193,11 +5194,17 @@
 		"HTTP Socket");
 	} else {
 	    enter_suid();
+	    flags = COMM_NONBLOCKING;
+#ifdef LINUX_TPROXY
+	    if (s->tproxy) {
+		flags |= COMM_TRANSPARENT;
+	    }
+#endif
 	    fd = comm_open(SOCK_STREAM,
 		IPPROTO_TCP,
 		s->s.sin_addr,
 		ntohs(s->s.sin_port),
-		COMM_NONBLOCKING,
+		flags,
 		"HTTP Socket");
 	    leave_suid();
 	}

Reply via email to