From: Amos Jeffries Date: Wed, 26 Mar 2008 11:49:34 +0000 (+1200) Subject: Merged from trunk. X-Git-Tag: BASIC_TPROXY4~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f1e0717c66cb5c2766133080880a8cf91abf0c1b;p=thirdparty%2Fsquid.git Merged from trunk. Added final step of TPROXY4 patch - settign of IP_TRANSPARENT option --- f1e0717c66cb5c2766133080880a8cf91abf0c1b diff --cc configure.in index 6df159b07e,6df159b07e..13fb91d007 --- a/configure.in +++ b/configure.in @@@ -1219,13 -1219,13 +1219,26 @@@ dnl "-64" from LDFLAG fi dnl Enable Linux transparent proxy support --AC_ARG_ENABLE(linux-tproxy, --[ --enable-linux-tproxy -- Enable real Transparent Proxy support for Netfilter TPROXY.], ++AC_ARG_ENABLE(linux-tproxy2, ++[ --enable-linux-tproxy2 ++ Enable real Transparent Proxy support for Netfilter TPROXY (version 2).], [ if test "$enableval" = "yes" ; then -- echo "Linux Netfilter/TPROXY enabled" -- AC_DEFINE(LINUX_TPROXY, 1, [Enable real Transparent Proxy support for Netfilter TPROXY.]) -- LINUX_TPROXY="yes" ++ echo "Linux Netfilter/TPROXY v2 enabled" ++ AC_DEFINE(LINUX_TPROXY2, 1, [Enable real Transparent Proxy support for Netfilter TPROXY v2.]) ++ LINUX_TPROXY2="yes" ++ if test -z "$LINUX_NETFILTER"; then ++ echo "Linux-Netfilter Transparent Proxy automatically enabled" ++ LINUX_NETFILTER="yes" ++ fi ++ fi ++]) ++AC_ARG_ENABLE(linux-tproxy4, ++[ --enable-linux-tproxy4 ++ Enable real Transparent Proxy support for Netfilter TPROXY (version 4+).], ++[ if test "$enableval" = "yes" ; then ++ echo "Linux Netfilter/TPROXY v4 enabled" ++ AC_DEFINE(LINUX_TPROXY4, 1, [Enable real Transparent Proxy support for Netfilter TPROXY v4.]) ++ LINUX_TPROXY4="yes" if test -z "$LINUX_NETFILTER"; then echo "Linux-Netfilter Transparent Proxy automatically enabled" LINUX_NETFILTER="yes" @@@ -2882,25 -2882,25 +2895,26 @@@ if test "$LINUX_NETFILTER" = "no" ; the sleep 10 fi --dnl Linux Netfilter/TPROXY support requires some specific header files ++dnl Linux Netfilter/TPROXYv2 support requires some specific header files dnl Shamelessly copied from shamelessly copied from above --if test "$LINUX_TPROXY" ; then -- AC_MSG_CHECKING(if TPROXY header files are installed) ++if test "$LINUX_TPROXY2" ; then ++ AC_MSG_CHECKING(if TPROXYv2 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 -- LINUX_TPROXY="yes" -- AC_DEFINE(LINUX_TPROXY, 1, [Enable real Transparent Proxy support for Netfilter TPROXY.]) ++ LINUX_TPROXY2="yes" ++ AC_DEFINE(LINUX_TPROXY2, 1, [Enable real Transparent Proxy support for Netfilter TPROXY v2.]) else -- LINUX_TPROXY="no" -- AC_DEFINE(LINUX_TPROXY, 0, [Enable real Transparent Proxy support for Netfilter TPROXY.]) ++ LINUX_TPROXY2="no" ++ AC_DEFINE(LINUX_TPROXY2, 0, [Enable real Transparent Proxy support for Netfilter TPROXY v2.]) ++ fi ++ AC_MSG_RESULT($LINUX_TPROXY2) ++ if test "$LINUX_TPROXY2" = "no" && test "$LINUX_NETFILTER" = "yes"; then ++ echo "WARNING: Cannot find TPROXY v2 headers, you need to install the" ++ echo "tproxy package from:" ++ echo " - lynx http://www.balabit.com/downloads/tproxy/" ++ echo "Or select the '--enable-linux-tproxy4' option instead." ++ sleep 10 fi -- AC_MSG_RESULT($LINUX_TPROXY) --fi --if test "$LINUX_TPROXY" = "no" && test "$LINUX_NETFILTER" = "yes"; then -- echo "WARNING: Cannot find TPROXY headers, you need to install the" -- echo "tproxy package from:" -- echo " - lynx http://www.balabit.com/downloads/tproxy/" -- sleep 10 fi if test -z "$USE_GNUREGEX" ; then diff --cc include/autoconf.h.in index 712aa4a35a,712aa4a35a..815f5b998f --- a/include/autoconf.h.in +++ b/include/autoconf.h.in @@@ -792,8 -792,8 +792,11 @@@ /* Enable support for Transparent Proxy on Linux (Netfilter) systems */ #undef LINUX_NETFILTER --/* Enable real Transparent Proxy support for Netfilter TPROXY. */ --#undef LINUX_TPROXY ++/* Enable real Transparent Proxy support for Netfilter TPROXY v2. */ ++#undef LINUX_TPROXY2 ++ ++/* Enable real Transparent Proxy support for Netfilter TPROXY v4. */ ++#undef LINUX_TPROXY4 /* If we need to declare sys_errlist[] as external */ #undef NEED_SYS_ERRLIST diff --cc src/IPInterception.cc index e7d510b2b9,e7d510b2b9..5feb509169 --- a/src/IPInterception.cc +++ b/src/IPInterception.cc @@@ -1,4 -1,4 +1,3 @@@ -- /* * $Id: IPInterception.cc,v 1.20 2008/02/05 22:38:24 amosjeffries Exp $ * @@@ -88,11 -88,11 +87,12 @@@ #include #endif --#if IPF_TRANSPARENT int -- clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst) { ++ ++#if IPF_TRANSPARENT /* --enable-ipf-transparent */ ++ dst = me; if( !me.IsIPv4() ) return -1; if( !peer.IsIPv4() ) return -1; @@@ -198,12 -198,12 +198,11 @@@ return 0; } --} --#elif LINUX_NETFILTER --int --clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst) --{ ++ ++ ++#elif LINUX_NETFILTER || LINUX_TPROXY4 /* --enable-linux-netfilter OR --enable-linux-tproxy4 */ ++ dst = me; if( !me.IsIPv4() ) return -1; if( !peer.IsIPv4() ) return -1; @@@ -213,12 -213,12 +212,16 @@@ dst.GetAddrInfo(lookup,AF_INET); ++#if LINUX_NETFILTER if (getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, lookup->ai_addr, &lookup->ai_addrlen) != 0) ++#elif LINUX_TPROXY4 ++ if (getsockopt(fd, SOL_IP, IP_TRANSPARENT, lookup->ai_addr, &lookup->ai_addrlen) != 0) ++#endif { dst.FreeAddrInfo(lookup); if (squid_curtime - last_reported > 60) { -- debugs(89, 1, "clientNatLookup: peer " << peer << " NF getsockopt(SO_ORIGINAL_DST) failed: " << xstrerror()); ++ debugs(89, 1, "clientNatLookup: peer " << peer << " NF getsockopt(" << (LINUX_NETFILTER?"SO_ORIGINAL_DST":"IP_TRANSPARENT") << ") failed: " << xstrerror()); last_reported = squid_curtime; } @@@ -234,13 -234,13 +237,9 @@@ return 0; else return -1; --} --#elif PF_TRANSPARENT --int --clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress dst) --{ ++#elif PF_TRANSPARENT /* --enable-pf-transparent */ struct pfioc_natlook nl; static int pffd = -1; @@@ -300,12 -300,12 +299,10 @@@ else return -1; } --} --#elif IPFW_TRANSPARENT --int --clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst) --{ ++ ++#elif IPFW_TRANSPARENT /* --enable-ipfw-transparent */ ++ int ret; struct addrinfo *lookup = NULL; @@@ -330,14 -330,14 +327,13 @@@ dst.FreeAddrInfo(lookup); return 0; --} --#else --int --clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst) --{ ++ ++#else /* none of the transparent options configured */ ++ debugs(89, 1, "WARNING: transparent proxying not supported"); return -1; --} ++ #endif ++} diff --cc src/IPInterception.h index 7c810de544,7c810de544..0e349b81fa --- a/src/IPInterception.h +++ b/src/IPInterception.h @@@ -1,4 -1,4 +1,3 @@@ -- /* * $Id: IPInterception.h,v 1.7 2007/12/14 23:11:45 amosjeffries Exp $ * @@@ -30,13 -30,13 +29,15 @@@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */ -- #ifndef SQUID_IPINTERCEPTION_H #define SQUID_IPINTERCEPTION_H #include "IPAddress.h" --SQUIDCEXTERN int --clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst); ++#if LINUX_TPROXY4 && !defined(IP_TRANSPARENT) ++#define IP_TRANSPARENT 19 ++#endif ++ ++SQUIDCEXTERN int clientNatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst); #endif /* SQUID_IPINTERCEPTION_H */ diff --cc src/ProtoPort.h index 8873dbea6e,ff696cf970..9d1ea8fa0a --- a/src/ProtoPort.h +++ b/src/ProtoPort.h @@@ -35,9 -31,8 +31,9 @@@ struct http_port_lis int vport; /* virtual port support, -1 for dynamic, >0 static*/ int disable_pmtu_discovery; --#if LINUX_TPROXY - unsigned int tproxy: - 1; /* spoof client ip using tproxy */ ++ ++#if LINUX_TPROXY2 || LINUX_TPROXY4 + unsigned int tproxy:1; /* spoof client ip using tproxy */ #endif struct { diff --cc src/cache_cf.cc index d3c708144c,9080a07b2a..d05034d035 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@@ -1,4 -1,4 +1,3 @@@ -- /* * $Id: cache_cf.cc,v 1.544 2008/03/04 12:00:36 amosjeffries Exp $ * @@@ -2932,7 -2928,7 +2927,7 @@@ parse_http_port_option(http_port_list else self_destruct(); --#if LINUX_TPROXY ++#if LINUX_TPROXY2 || LINUX_TPROXY4 } else if (strcmp(token, "tproxy") == 0) { s->tproxy = 1; @@@ -2945,6 -2941,6 +2940,7 @@@ } #endif #endif ++ } else if (strcmp(token, "ipv4") == 0) { #if USE_IPV6 if( !s->s.SetIPv4() ) { diff --cc src/client_side.cc index 76b253b779,db8561a4b2..5cb617f5d9 --- a/src/client_side.cc +++ b/src/client_side.cc @@@ -2217,8 -2213,8 +2213,7 @@@ clientProcessRequest(ConnStateData *con request->flags.transparent = http->flags.transparent; --#if LINUX_TPROXY -- ++#if LINUX_TPROXY2 || LINUX_TPROXY4 request->flags.tproxy = conn->port->tproxy && need_linux_tproxy; #endif @@@ -3124,6 -3118,6 +3117,13 @@@ clientHttpConnectionsOpen(void if (fd < 0) continue; ++#if LINUX_TPROXY4 ++ /* because the transparent/non-transparent port info is only known here. ++ * we have to set the IP_TRANSPARENT option here. */ ++ if(s->transparent) ++ comm_set_transparent(fd,0); ++#endif ++ comm_listen(fd); comm_accept(fd, httpAccept, s); diff --cc src/comm.cc index 513c71a2ce,5d6e503424..f3798a26a2 --- a/src/comm.cc +++ b/src/comm.cc @@@ -627,6 -627,6 +627,18 @@@ comm_set_v6only(int fd, int tos #endif /* sockopt */ } ++void ++comm_set_transparent(int fd, int tos) ++{ ++#if LINUX_TPROXY4 ++ if (setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, (char *) &tos, sizeof(int)) < 0) { ++ debugs(50, 1, "comm_open: setsockopt(IP_TRANSPARENT) on FD " << fd << ": " << xstrerror()); ++ } ++#else ++ debugs(50, 0, "WARNING: comm_open: setsockopt(IP_TRANSPARENT) not supported on this platform"); ++#endif /* sockopt */ ++} ++ /** * Create a socket. Default is blocking, stream (TCP) socket. IO_TYPE * is OR of flags specified in defines.h:COMM_* diff --cc src/forward.cc index 48e060311b,d8e47225d9..2c01441062 --- a/src/forward.cc +++ b/src/forward.cc @@@ -49,8 -49,8 +49,12 @@@ #include "SquidTime.h" #include "Store.h" --#if LINUX_TPROXY ++#if LINUX_TPROXY2 ++#ifdef HAVE_LINUX_NETFILTER_IPV4_IP_TPROXY_H #include ++#else ++#error " TPROXY v2 Header file missing: linux/netfilter_ipv4/ip_tproxy.h. Perhapse you meant to use TPROXY v4 ? " ++#endif #endif static PSC fwdStartCompleteWrapper; diff --cc src/forward.h index 90e46956d9,d15149cb43..c3a8d77ef8 --- a/src/forward.h +++ b/src/forward.h @@@ -95,18 -95,11 +95,11 @@@ private struct { - - unsigned int dont_retry: - 1; - - unsigned int ftp_pasv_failed: - 1; - - unsigned int forward_completed:1; - } - - flags; - #if LINUX_NETFILTER + unsigned int dont_retry:1; + unsigned int ftp_pasv_failed:1; + unsigned int forward_completed:1; + } flags; -#if LINUX_NETFILTER ++#if LINUX_NETFILTER || LINUX_TPROXY2 || LINUX_TPROXY4 IPAddress src; #endif diff --cc src/globals.h index 0d6afa2d9a,0d6afa2d9a..9d581252fc --- a/src/globals.h +++ b/src/globals.h @@@ -185,7 -185,7 +185,7 @@@ extern "C extern const char *external_acl_message; /* NULL */ extern int opt_send_signal; /* -1 */ extern int opt_no_daemon; /* 0 */ --#if LINUX_TPROXY ++#if LINUX_TPROXY2 || LINUX_TPROXY4 extern int need_linux_tproxy; /* 0 */ #endif diff --cc src/http.cc index 3b48de45d7,3b48de45d7..18f643688a --- a/src/http.cc +++ b/src/http.cc @@@ -1229,7 -1229,7 +1229,8 @@@ HttpStateData::processReplyBody( comm_remove_close_handler(fd, closeHandler); closeHandler = NULL; fwd->unregister(fd); --#if LINUX_TPROXY ++ ++#if LINUX_TPROXY2 || LINUX_TPROXY4 if (orig_request->flags.tproxy) client_addr = orig_request->client_addr; diff --cc src/structs.h index 014b82db5d,b65065a9a3..dfbce3fe16 --- a/src/structs.h +++ b/src/structs.h @@@ -1164,71 -1029,34 +1029,34 @@@ struct request_flag #if HTTP_VIOLATIONS nocache_hack = 0; #endif --#if LINUX_TPROXY ++#if LINUX_TPROXY2 || LINUX_TPROXY4 tproxy = 0; #endif - } - unsigned int range: - 1; - - unsigned int nocache: - 1; - - unsigned int ims: - 1; - - unsigned int auth: - 1; - - unsigned int cachable: - 1; - - unsigned int hierarchical: - 1; - - unsigned int loopdetect: - 1; - - unsigned int proxy_keepalive: - 1; - - unsigned int proxying: - 1; /* this should be killed, also in httpstateflags */ - - unsigned int refresh: - 1; - - unsigned int redirected: - 1; - - unsigned int need_validation: - 1; + unsigned int range:1; + unsigned int nocache:1; + unsigned int ims:1; + unsigned int auth:1; + unsigned int cachable:1; + unsigned int hierarchical:1; + unsigned int loopdetect:1; + unsigned int proxy_keepalive:1; + unsigned int proxying:1; /* this should be killed, also in httpstateflags */ + unsigned int refresh:1; + unsigned int redirected:1; + unsigned int need_validation:1; #if HTTP_VIOLATIONS - - unsigned int nocache_hack: - 1; /* for changing/ignoring no-cache requests */ + unsigned int nocache_hack:1; /* for changing/ignoring no-cache requests */ #endif - - unsigned int accelerated: - 1; - - unsigned int transparent: - 1; - - #if LINUX_TPROXY - unsigned int tproxy: - 1; /* spoof client ip using tproxy */ + unsigned int accelerated:1; + unsigned int transparent:1; -#if LINUX_TPROXY ++#if LINUX_TPROXY2 || LINUX_TPROXY4 + unsigned int tproxy:1; /* spoof client ip using tproxy */ #endif - unsigned int internal: - 1; - - unsigned int internalclient: - 1; - - unsigned int must_keepalive: - 1; + unsigned int internal:1; + unsigned int internalclient:1; + unsigned int must_keepalive:1; // When adding new flags, please update cloneAdaptationImmune() as needed. diff --cc src/tools.cc index 47255438ea,bf3f7c4528..aa87a254a7 --- a/src/tools.cc +++ b/src/tools.cc @@@ -1238,7 -1236,7 +1236,7 @@@ keepCapabilities(void if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { /* Silent failure unless TPROXY is required. Maybe not started as root */ --#if LINUX_TPROXY ++#if LINUX_TPROXY2 || LINUX_TPROXY4 if (need_linux_tproxy) debugs(1, 1, "Error - tproxy support requires capability setting which has failed. Continuing without tproxy support"); @@@ -1248,7 -1246,7 +1246,6 @@@ #endif } -- #endif } @@@ -1275,10 -1273,10 +1272,13 @@@ restoreCapabilities(int keep cap->inheritable = 0; cap->effective = (1 << CAP_NET_BIND_SERVICE); --#if LINUX_TPROXY ++#if LINUX_TPROXY2 if (need_linux_tproxy) cap->effective |= (1 << CAP_NET_ADMIN) | (1 << CAP_NET_BROADCAST); ++#elif LINUX_TPROXY4 ++ if (need_linux_tproxy) ++ cap->effective |= (1 << CAP_NET_ADMIN); #endif @@@ -1287,7 -1285,7 +1287,7 @@@ if (capset(head, cap) != 0) { /* Silent failure unless TPROXY is required */ --#if LINUX_TPROXY ++#if LINUX_TPROXY2 || LINUX_TPROXY4 if (need_linux_tproxy) debugs(50, 1, "Error enabling needed capabilities. Will continue without tproxy support"); @@@ -1301,14 -1299,14 +1301,14 @@@ nocap: xfree(head); xfree(cap); --#else --#if LINUX_TPROXY ++#else /* not defined(_SQUID_LINUX_) && HAVE_SYS_CAPABILITY_H */ ++ ++#if LINUX_TPROXY2 || LINUX_TPROXY4 if (need_linux_tproxy) debugs(50, 1, "Missing needed capability support. Will continue without tproxy support"); need_linux_tproxy = 0; -- #endif #endif