From: Amos Jeffries Date: Tue, 14 Oct 2008 09:54:26 +0000 (+1300) Subject: Bug 1441: tcp_outgoing_address + peering need acl matching actual endpoint X-Git-Tag: SQUID_3_2_0_1~1408 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6db78a1a87cd1cdb1c90cc9acff40ebc7dfb480a;p=thirdparty%2Fsquid.git Bug 1441: tcp_outgoing_address + peering need acl matching actual endpoint Adds the 'peername' ACL to match against the cache_peer name=X values. Also, adds peername ACL tests to tcp_outgoing_addr. NOTE: Only checks against the first peer of all possible peers selected for the connection. So on failures the outgoing address may still be incorrect for the secondary peers. Thanks for testing to Andrew McMillan --- diff --git a/src/ACLChecklist.cc b/src/ACLChecklist.cc index 37ea646b6b..6ec7414009 100644 --- a/src/ACLChecklist.cc +++ b/src/ACLChecklist.cc @@ -358,6 +358,7 @@ ACLChecklist::operator delete (void *address) ACLChecklist::ACLChecklist() : accessList (NULL), + dst_peer(NULL), request (NULL), reply (NULL), auth_user_request (NULL), diff --git a/src/ACLChecklist.h b/src/ACLChecklist.h index 72a0cced07..3e2f422283 100644 --- a/src/ACLChecklist.h +++ b/src/ACLChecklist.h @@ -35,6 +35,7 @@ #include "typedefs.h" #include "client_side.h" +#include "structs.h" class ExternalACLEntry; @@ -128,6 +129,8 @@ public: IPAddress my_addr; + struct peer *dst_peer; + HttpRequest *request; /* for acls that look at reply data */ HttpReply *reply; diff --git a/src/ACLMyPortName.cc b/src/ACLMyPortName.cc index d1b42dc574..1cfabd327a 100644 --- a/src/ACLMyPortName.cc +++ b/src/ACLMyPortName.cc @@ -39,9 +39,6 @@ #include "ACLStringData.h" #include "ACLChecklist.h" -/* explicit template instantiation required for some systems */ - -template class ACLStrategised; ACL::Prototype ACLMyPortName::RegistryProtoype(&ACLMyPortName::RegistryEntry_, "myportname"); diff --git a/src/ACLPeerName.cc b/src/ACLPeerName.cc new file mode 100644 index 0000000000..8e3d4b9388 --- /dev/null +++ b/src/ACLPeerName.cc @@ -0,0 +1,24 @@ +#include "squid.h" +#include "ACLPeerName.h" +#include "ACLStringData.h" +#include "ACLChecklist.h" + +ACL::Prototype ACLPeerName::RegistryProtoype(&ACLPeerName::RegistryEntry_, "peername"); + +ACLStrategised ACLPeerName::RegistryEntry_(new ACLStringData, ACLPeerNameStrategy::Instance(), "peername"); + +int +ACLPeerNameStrategy::match (ACLData * &data, ACLChecklist *checklist) +{ + if (checklist->dst_peer != NULL && checklist->dst_peer->name != NULL) + return data->match(checklist->dst_peer->name); + return 0; +} + +ACLPeerNameStrategy * +ACLPeerNameStrategy::Instance() +{ + return &Instance_; +} + +ACLPeerNameStrategy ACLPeerNameStrategy::Instance_; diff --git a/src/ACLPeerName.h b/src/ACLPeerName.h new file mode 100644 index 0000000000..c7abebf203 --- /dev/null +++ b/src/ACLPeerName.h @@ -0,0 +1,33 @@ +#ifndef SQUID_ACLPEERNAME_H +#define SQUID_ACLPEERNAME_H + +#include "ACLStrategy.h" +#include "ACLStrategised.h" + +class ACLPeerNameStrategy : public ACLStrategy +{ + +public: + virtual int match (ACLData * &, ACLChecklist *); + static ACLPeerNameStrategy *Instance(); + /* Not implemented to prevent copies of the instance. */ + /* Not private to prevent brain dead g+++ warnings about + * private constructors with no friends */ + ACLPeerNameStrategy(ACLPeerNameStrategy const &); + +private: + static ACLPeerNameStrategy Instance_; + ACLPeerNameStrategy(){} + + ACLPeerNameStrategy&operator=(ACLPeerNameStrategy const &); +}; + +class ACLPeerName +{ + +private: + static ACL::Prototype RegistryProtoype; + static ACLStrategised RegistryEntry_; +}; + +#endif /* SQUID_ACLPEERNAME_H */ diff --git a/src/ACLStrategised.cc b/src/ACLStrategised.cc index 8093738f27..85cc1ed934 100644 --- a/src/ACLStrategised.cc +++ b/src/ACLStrategised.cc @@ -42,11 +42,15 @@ #include "ACLDomainData.h" /* - * moved template instantiation into ACLStrategized.cc from - * ACLHTTPRepHeader.cc and ACLHTTPReqHeader.cc to compile on - * Mac OSX 10.5 Leopard, this corrects a duplicate symbol error + * moved template instantiation into ACLStrategized.cc + * to compile on Mac OSX 10.5 Leopard. + * This corrects a duplicate symbol error */ /* explicit template instantiation required for some systems */ +/* ACLHTTPRepHeader + ACLHTTPReqHeader */ template class ACLStrategised; + +/* ACLMyPortName + ACLMyPeerName */ +template class ACLStrategised; diff --git a/src/Makefile.am b/src/Makefile.am index 4bfb3f4182..17ebd27b2f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -365,6 +365,8 @@ squid_ACLSOURCES = \ ACLMyPort.h \ ACLMyPortName.cc \ ACLMyPortName.h \ + ACLPeerName.cc \ + ACLPeerName.h \ ACLProtocol.cc \ ACLProtocol.h \ ACLProtocolData.cc \ diff --git a/src/cf.data.pre b/src/cf.data.pre index 14d2fb1274..7ed08c83dd 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -518,6 +518,10 @@ DOC_START # cache_peer_access mycache.mydomain.net allow asexample # cache_peer_access mycache_mydomain.net deny all + acl aclname peername myPeer ... + # match against a named cache_peer entry + # set unique name= on cache_peer lines for reliable use. + acl aclname time [day-abbrevs] [h1:m1-h2:m2] # day-abbrevs: # S - Sunday @@ -1360,6 +1364,12 @@ DOC_START tcp_outgoing_address 2002::1 to_ipv6 tcp_outgoing_address 10.1.0.3 !to_ipv6 + + WARNING: + 'dst ipv6' bases its selection assuming DIRECT access. + If peers are used the peername ACL are needed to select outgoing + address which can link to the peer. + DOC_END COMMENT_START @@ -1766,7 +1776,7 @@ DOC_START use 'name=xxx' if you have multiple peers on the same host but different ports. This name can be used to differentiate the peers in cache_peer_access and similar - directives. + directives. Including the peername ACL type. use 'forceddomain=name' to forcibly set the Host header of requests forwarded to this peer. Useful in accelerator diff --git a/src/forward.cc b/src/forward.cc index 39471e21d9..a8ef963efb 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -857,7 +857,7 @@ FwdState::connectStart() #endif - outgoing = getOutgoingAddr(request); + outgoing = getOutgoingAddr(request, fs->_peer); tos = getOutgoingTOS(request); @@ -1323,13 +1323,15 @@ aclMapTOS(acl_tos * head, ACLChecklist * ch) } IPAddress -getOutgoingAddr(HttpRequest * request) +getOutgoingAddr(HttpRequest * request, struct peer *dst_peer) { ACLChecklist ch; if (request && request->flags.spoof_client_ip) return request->client_addr; + ch.dst_peer = dst_peer; + if (request) { ch.src_addr = request->client_addr; ch.my_addr = request->my_addr; diff --git a/src/neighbors.cc b/src/neighbors.cc index 537b65d6e1..c1f9cbd1d0 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1380,7 +1380,7 @@ peerProbeConnect(peer * p) if (squid_curtime - p->stats.last_connect_probe == 0) return ret;/* don't probe to often */ - IPAddress temp(getOutgoingAddr(NULL)); + IPAddress temp(getOutgoingAddr(NULL,p)); fd = comm_open(SOCK_STREAM, IPPROTO_TCP, temp, COMM_NONBLOCKING, p->host); diff --git a/src/protos.h b/src/protos.h index 94379bfb8f..90203bbec3 100644 --- a/src/protos.h +++ b/src/protos.h @@ -445,7 +445,7 @@ SQUIDCEXTERN void peerDigestNeeded(PeerDigest * pd); SQUIDCEXTERN void peerDigestNotePeerGone(PeerDigest * pd); SQUIDCEXTERN void peerDigestStatsReport(const PeerDigest * pd, StoreEntry * e); -extern IPAddress getOutgoingAddr(HttpRequest * request); +extern IPAddress getOutgoingAddr(HttpRequest * request, struct peer *dst_peer); unsigned long getOutgoingTOS(HttpRequest * request); SQUIDCEXTERN void urnStart(HttpRequest *, StoreEntry *); diff --git a/src/tunnel.cc b/src/tunnel.cc index 81844bbe30..3e994f92d1 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -635,7 +635,7 @@ tunnelStart(ClientHttpRequest * http, int64_t * size_ptr, int *status_ptr) statCounter.server.all.requests++; statCounter.server.other.requests++; /* Create socket. */ - IPAddress temp = getOutgoingAddr(request); + IPAddress temp = getOutgoingAddr(request,NULL); sock = comm_openex(SOCK_STREAM, IPPROTO_TCP, temp,