From: Amos Jeffries Date: Fri, 25 Sep 2009 11:09:37 +0000 (+1200) Subject: Author: Adrian Chadd X-Git-Tag: SQUID_3_2_0_1~692 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b0758e04c93745979a8f679cec8e08b724d6ec58;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 8ebcf90388..20c5024e3c 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 dbe160d9b9..1c50d4c662 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -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 diff --git a/src/forward.cc b/src/forward.cc index 4328f6c83e..9f789d3ece 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -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. diff --git a/src/neighbors.cc b/src/neighbors.cc index 834d656ecb..06e5f84391 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -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); diff --git a/src/structs.h b/src/structs.h index e945dbcd1c..661236ee8b 100644 --- a/src/structs.h +++ b/src/structs.h @@ -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;