]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Author: Adrian Chadd <adrian@squid-cache.org>
authorAmos Jeffries <squid3@treenet.co.nz>
Sun, 27 Sep 2009 00:28:52 +0000 (13:28 +1300)
committerAmos Jeffries <squid3@treenet.co.nz>
Sun, 27 Sep 2009 00:28:52 +0000 (13:28 +1300)
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 b56ecc38e3ac30dd94d46d0d3b98914446897ac2..474ee15b2926138959f32cd5cfadb0af4fcb028a 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 4703109eed5eccc1e03e957f3faea0ed6211bcc8..6b01717266df9d175d383727b44ecc35b72bc8f1 100644 (file)
@@ -1918,6 +1918,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 6f0895726b162ad6cd654339eddd83cb405629d2..08176792514de81dbd541ac3d907bad8db17cb8f 100644 (file)
@@ -774,7 +774,6 @@ FwdState::connectStart()
 
     IpAddress outgoing;
     unsigned short tos;
-
     IpAddress client_addr;
     assert(fs);
     assert(server_fd == -1);
@@ -790,8 +789,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;
@@ -868,7 +870,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);
@@ -1341,8 +1345,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 00ef0165c745fd89acb9d18015522a754976411f..6eaf5c8c2f46490d60d3c12d6d7c8c520230a2a2 100644 (file)
@@ -1624,6 +1624,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 fb20eb0f317032e7fa9dc17948afc3ebdf1a8a59..05d2d56f7c6d30a7296a0314578d90b6c3bac353 100644 (file)
@@ -879,6 +879,7 @@ struct peer {
         unsigned int userhash:1;
         unsigned int sourcehash:1;
         unsigned int originserver:1;
+        unsigned int no_tproxy:1;
     } options;
 
     int weight;