# UNDF: UNDF-2026-000001185 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -7,6 +7,7 @@ /* DEBUG: section 15 Neighbor Routines */ +#include #include "squid.h" #include "acl/FilledChecklist.h" #include "anyp/PortCfg.h" @@ -53,6 +54,19 @@ static int peerHTTPOkay(const CachePeer *, PeerSelector *); static CachePeer *whichPeer(const Ip::Address &from); +/// Maps (ICP-source-address, icp-port) -> CachePeer* for O(log P) lookup. +/// Built/updated in peerDNSConfigure(); entries removed in DeleteConfigured(). +/// Key: pair to avoid port aliasing from +/// Ip::Address::port() stored inside the address object. +static std::map, CachePeer *> WhichPeerMap; + +/// Register all addresses for \p p in WhichPeerMap. +static void +whichPeerMapAdd(CachePeer *p) +{ + for (int j = 0; j < p->n_addresses; ++j) + WhichPeerMap[{p->addresses[j], p->icp.port}] = p; +} + +/// Remove all addresses for \p p from WhichPeerMap. +static void +whichPeerMapRemove(CachePeer *p) +{ + for (int j = 0; j < p->n_addresses; ++j) + WhichPeerMap.erase({p->addresses[j], p->icp.port}); +} + static CachePeer * whichPeer(const Ip::Address &from) { - int j; - debugs(15, 3, "whichPeer: from " << from); - for (const auto &p: CurrentCachePeers()) { - for (j = 0; j < p->n_addresses; ++j) { - if (from == p->addresses[j] && from.port() == p->icp.port) { - return p.get(); - } - } - } - - return nullptr; + const auto it = WhichPeerMap.find({from, from.port()}); + return (it != WhichPeerMap.end()) ? it->second : nullptr; } --- a/src/neighbors.cc (peerDNSConfigure hunk) +++ b/src/neighbors.cc @@ -1110,6 +1110,10 @@ peerDNSConfigure(const ipcache_addrs *ia, const Dns::LookupDetails &, void *dat CachePeer *p = (CachePeer *)data; + // Remove stale map entries for this peer's old addresses before + // overwriting p->addresses[] and p->n_addresses below. + whichPeerMapRemove(p); + if (p->n_addresses == 0) { debugs(15, Important(29), "Configuring " << neighborTypeStr(p) << " " << *p); @@ -1135,6 +1139,9 @@ peerDNSConfigure(const ipcache_addrs *ia, const Dns::LookupDetails &, void *dat } } + // Rebuild map entries for this peer's new addresses. + whichPeerMapAdd(p); + p->in_addr.setEmpty(); p->in_addr = p->addresses[0]; p->in_addr.port(p->icp.port); --- a/src/CachePeers.cc (DeleteConfigured hunk) +++ b/src/CachePeers.cc @@ -52,6 +52,7 @@ DeleteConfigured(CachePeer * const peer) { Assure(Config.peers); + whichPeerMapRemove(peer); // clean up reverse-lookup map entry Config.peers->remove(peer); }