From: Amos Jeffries Date: Sun, 27 Sep 2009 00:28:52 +0000 (+1300) Subject: Author: Adrian Chadd X-Git-Tag: SQUID_3_1_0_14~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=79f7d4b68f7a39e3c3eac548b616327d456ec3b2;p=thirdparty%2Fsquid.git Author: Adrian Chadd 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. --- diff --git a/src/cache_cf.cc b/src/cache_cf.cc index b56ecc38e3..474ee15b29 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -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)) { diff --git a/src/cf.data.pre b/src/cf.data.pre index 4703109eed..6b01717266 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -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 diff --git a/src/forward.cc b/src/forward.cc index 6f0895726b..0817679251 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -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. diff --git a/src/neighbors.cc b/src/neighbors.cc index 00ef0165c7..6eaf5c8c2f 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -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); diff --git a/src/structs.h b/src/structs.h index fb20eb0f31..05d2d56f7c 100644 --- a/src/structs.h +++ b/src/structs.h @@ -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;