]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Author: Adrian Chadd <adrian@squid-cache.org>
authorAmos Jeffries <squid3@treenet.co.nz>
Fri, 25 Sep 2009 11:09:37 +0000 (23:09 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Fri, 25 Sep 2009 11:09:37 +0000 (23:09 +1200)
A tproxy cache cluster (eg behind WCCPv2) can't peer.

The issue stems from the forwarding logic creating source address spoofed
sockets to destinations that are inside the cluster. Since the WCCPv2
router won't redirect packets with an origin of the proxy MAC (at least for
L2 peering), source spoofed packets go out and are routed normally. The
packets back from the destination peer have a remote end of the spoofed IP,
and are instead sent to teh original client rather than the proxy.

The forwarding logic needs to be taught to optionally enable tproxy source
spoofing on connections based on a peer flag.

Just for completeness - tproxy'ed connections to a upstream or peer proxy
which is -outside- of the WCCPv2 tproxy cluster work fine.

src/cache_cf.cc
src/cf.data.pre
src/forward.cc
src/neighbors.cc
src/structs.h

index 8ebcf903886f434069ef00c8d8c34d9818027126..20c5024e3caa7b0a51c95f755255b95368c39d3d 100644 (file)
@@ -1730,6 +1730,8 @@ parse_peer(peer ** head)
             p->options.background_ping = 1;
         } else if (!strcasecmp(token, "no-digest")) {
             p->options.no_digest = 1;
+        } else if (!strcasecmp(token, "no-tproxy")) {
+            p->options.no_tproxy = 1;
         } else if (!strcasecmp(token, "multicast-responder")) {
             p->options.mcast_responder = 1;
         } else if (!strncasecmp(token, "weight=", 7)) {
index dbe160d9b99b342dbe3659c28c917f3d3ce392bd..1c50d4c66219f0a4ed3e10795b1f4912e72fb1f4 100644 (file)
@@ -1942,6 +1942,9 @@ DOC_START
                        Can be used by outgoing access controls through the
                        peername ACL type.
        
+       no-tproxy       Do not use the client-spoof TPROXY support when forwarding
+                       requests to this peer. Use normal address selection instead.
+       
        proxy-only      objects fetched from the peer will not be stored locally.
        
 DOC_END
index 4328f6c83ece07a4c71a3a96483155c679561fe4..9f789d3ece0dc1031de825198823c644d635ceb4 100644 (file)
@@ -775,7 +775,6 @@ FwdState::connectStart()
 
     IpAddress outgoing;
     unsigned short tos;
-
     IpAddress client_addr;
     assert(fs);
     assert(server_fd == -1);
@@ -791,8 +790,11 @@ FwdState::connectStart()
         ctimeout = Config.Timeout.connect;
     }
 
-    if (request->flags.spoof_client_ip)
-        client_addr = request->client_addr;
+    if (request->flags.spoof_client_ip) {
+        if (!fs->_peer || !fs->_peer->options.no_tproxy)
+            client_addr = request->client_addr;
+        // else no tproxy today ...
+    }
 
     if (ftimeout < 0)
         ftimeout = 5;
@@ -869,7 +871,9 @@ FwdState::connectStart()
 
     int flags = COMM_NONBLOCKING;
     if (request->flags.spoof_client_ip) {
-        flags |= COMM_TRANSPARENT;
+        if (!fs->_peer || !fs->_peer->options.no_tproxy)
+            flags |= COMM_TRANSPARENT;
+        // else no tproxy today ...
     }
 
     fd = comm_openex(SOCK_STREAM, IPPROTO_TCP, outgoing, flags, tos, url);
@@ -1342,8 +1346,11 @@ aclMapTOS(acl_tos * head, ACLChecklist * ch)
 IpAddress
 getOutgoingAddr(HttpRequest * request, struct peer *dst_peer)
 {
-    if (request && request->flags.spoof_client_ip)
-        return request->client_addr;
+    if (request && request->flags.spoof_client_ip) {
+        if (!dst_peer || !dst_peer->options.no_tproxy)
+            return request->client_addr;
+        // else no tproxy today ...
+    }
 
     if (!Config.accessList.outgoing_address) {
         return IpAddress(); // anything will do.
index 834d656ecb909b100bd6f3da791c5de498ea078b..06e5f84391af7a50e27ed484c51cd61766a7e1ec 100644 (file)
@@ -1618,6 +1618,9 @@ dump_peer_options(StoreEntry * sentry, peer * p)
     if (p->options.allow_miss)
         storeAppendPrintf(sentry, " allow-miss");
 
+    if (p->options.no_tproxy)
+        storeAppendPrintf(sentry, " no-tproxy");
+
     if (p->max_conn > 0)
         storeAppendPrintf(sentry, " max-conn=%d", p->max_conn);
 
index e945dbcd1c5d3a985d4cbd5922015daf02ce20f9..661236ee8b2c51787e9bc33f5a4fe0b5a58a3102 100644 (file)
@@ -884,6 +884,7 @@ struct peer {
         unsigned int userhash:1;
         unsigned int sourcehash:1;
         unsigned int originserver:1;
+        unsigned int no_tproxy:1;
     } options;
 
     int weight;