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();
 	}
