/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#include "squid.h"
#include "acl/FilledChecklist.h"
#include "anyp/PortCfg.h"
+#include "base/EnumIterator.h"
#include "CacheDigest.h"
#include "CachePeer.h"
#include "comm/Connection.h"
#include "Store.h"
#include "store_key_md5.h"
#include "tools.h"
-#include "URL.h"
/* count mcast group peers every 15 minutes */
#define MCAST_COUNT_RATE 900
-bool peerAllowedToUse(const CachePeer *, HttpRequest *);
-static int peerWouldBePinged(const CachePeer *, HttpRequest *);
+bool peerAllowedToUse(const CachePeer *, PeerSelector *);
+static int peerWouldBePinged(const CachePeer *, PeerSelector *);
static void neighborRemove(CachePeer *);
static void neighborAlive(CachePeer *, const MemObject *, const icp_common_t *);
#if USE_HTCP
static void neighborCountIgnored(CachePeer *);
static void peerRefreshDNS(void *);
static IPH peerDNSConfigure;
-static bool peerProbeConnect(CachePeer *);
+static void peerProbeConnect(CachePeer *, const bool reprobeIfBusy = false);
static CNCB peerProbeConnectDone;
static void peerCountMcastPeersDone(void *data);
static void peerCountMcastPeersStart(void *data);
static void peerCountMcastPeersSchedule(CachePeer * p, time_t when);
+static void peerCountMcastPeersAbort(PeerSelector *);
+static void peerCountMcastPeersCreateAndSend(CachePeer *p);
static IRCB peerCountHandleIcpReply;
static void neighborIgnoreNonPeer(const Ip::Address &, icp_opcode);
}
peer_t
-neighborType(const CachePeer * p, const HttpRequest * request)
+neighborType(const CachePeer * p, const AnyP::Uri &url)
{
const NeighborTypeDomainList *d = NULL;
for (d = p->typelist; d; d = d->next) {
- if (0 == matchDomainName(request->GetHost(), d->domain))
+ if (0 == matchDomainName(url.host(), d->domain))
if (d->type != PEER_NONE)
return d->type;
}
* \return Whether it is appropriate to fetch REQUEST from PEER.
*/
bool
-peerAllowedToUse(const CachePeer * p, HttpRequest * request)
+peerAllowedToUse(const CachePeer * p, PeerSelector * ps)
{
-
+ assert(ps);
+ HttpRequest *request = ps->request;
assert(request != NULL);
- if (neighborType(p, request) == PEER_SIBLING) {
+ if (neighborType(p, request->url) == PEER_SIBLING) {
#if PEER_MULTICAST_SIBLINGS
if (p->type == PEER_MULTICAST && p->options.mcast_siblings &&
(request->flags.noCache || request->flags.refresh || request->flags.loopDetected || request->flags.needValidation))
- debugs(15, 2, "peerAllowedToUse(" << p->name << ", " << request->GetHost() << ") : multicast-siblings optimization match");
+ debugs(15, 2, "peerAllowedToUse(" << p->name << ", " << request->url.authority() << ") : multicast-siblings optimization match");
#endif
if (request->flags.noCache)
return false;
// CONNECT requests are proxy requests. Not to be forwarded to origin servers.
// Unless the destination port matches, in which case we MAY perform a 'DIRECT' to this CachePeer.
- if (p->options.originserver && request->method == Http::METHOD_CONNECT && request->port != p->in_addr.port())
+ if (p->options.originserver && request->method == Http::METHOD_CONNECT && request->url.port() != p->http_port)
return false;
if (p->access == NULL)
return true;
ACLFilledChecklist checklist(p->access, request, NULL);
-
- return (checklist.fastCheck() == ACCESS_ALLOWED);
+ checklist.al = ps->al;
+ if (ps->al && ps->al->reply) {
+ checklist.reply = ps->al->reply.getRaw();
+ HTTPMSGLOCK(checklist.reply);
+ }
+ checklist.syncAle(request, nullptr);
+ return checklist.fastCheck().allowed();
}
/* Return TRUE if it is okay to send an ICP request to this CachePeer. */
static int
-peerWouldBePinged(const CachePeer * p, HttpRequest * request)
+peerWouldBePinged(const CachePeer * p, PeerSelector * ps)
{
+ assert(ps);
+ HttpRequest *request = ps->request;
+
if (p->icp.port == 0)
return 0;
if (!request->flags.hierarchical)
return 0;
- if (!peerAllowedToUse(p, request))
+ if (!peerAllowedToUse(p, ps))
return 0;
/* Ping dead peers every timeout interval */
/* Return TRUE if it is okay to send an HTTP request to this CachePeer. */
int
-peerHTTPOkay(const CachePeer * p, HttpRequest * request)
+peerHTTPOkay(const CachePeer * p, PeerSelector * ps)
{
if (!peerCanOpenMore(p) && !peerHasConnAvailable(p))
return 0;
- if (!peerAllowedToUse(p, request))
+ if (!peerAllowedToUse(p, ps))
return 0;
if (!neighborUp(p))
}
int
-neighborsCount(HttpRequest * request)
+neighborsCount(PeerSelector *ps)
{
CachePeer *p = NULL;
int count = 0;
for (p = Config.peers; p; p = p->next)
- if (peerWouldBePinged(p, request))
+ if (peerWouldBePinged(p, ps))
++count;
debugs(15, 3, "neighborsCount: " << count);
}
CachePeer *
-getFirstUpParent(HttpRequest * request)
+getFirstUpParent(PeerSelector *ps)
{
+ assert(ps);
+ HttpRequest *request = ps->request;
+
CachePeer *p = NULL;
for (p = Config.peers; p; p = p->next) {
if (!neighborUp(p))
continue;
- if (neighborType(p, request) != PEER_PARENT)
+ if (neighborType(p, request->url) != PEER_PARENT)
continue;
- if (!peerHTTPOkay(p, request))
+ if (!peerHTTPOkay(p, ps))
continue;
break;
}
CachePeer *
-getRoundRobinParent(HttpRequest * request)
+getRoundRobinParent(PeerSelector *ps)
{
+ assert(ps);
+ HttpRequest *request = ps->request;
+
CachePeer *p;
CachePeer *q = NULL;
if (!p->options.roundrobin)
continue;
- if (neighborType(p, request) != PEER_PARENT)
+ if (neighborType(p, request->url) != PEER_PARENT)
continue;
- if (!peerHTTPOkay(p, request))
+ if (!peerHTTPOkay(p, ps))
continue;
if (p->weight == 0)
}
CachePeer *
-getWeightedRoundRobinParent(HttpRequest * request)
+getWeightedRoundRobinParent(PeerSelector *ps)
{
+ assert(ps);
+ HttpRequest *request = ps->request;
+
CachePeer *p;
CachePeer *q = NULL;
int weighted_rtt;
if (!p->options.weighted_roundrobin)
continue;
- if (neighborType(p, request) != PEER_PARENT)
+ if (neighborType(p, request->url) != PEER_PARENT)
continue;
- if (!peerHTTPOkay(p, request))
+ if (!peerHTTPOkay(p, ps))
continue;
if (q && q->rr_count < p->rr_count)
if (!p->options.weighted_roundrobin)
continue;
- if (neighborType(p, request) != PEER_PARENT)
+ if (neighborType(p, request->url) != PEER_PARENT)
continue;
p->rr_count = 0;
* period. The larger the number of requests between cycled resets the
* more balanced the operations.
*
- \param data unused.
- \todo Make the reset timing a selectable parameter in squid.conf
+ * \param data unused
+ *
+ * TODO: Make the reset timing a selectable parameter in squid.conf
*/
static void
peerClearRRLoop(void *data)
}
CachePeer *
-getDefaultParent(HttpRequest * request)
+getDefaultParent(PeerSelector *ps)
{
+ assert(ps);
+ HttpRequest *request = ps->request;
+
CachePeer *p = NULL;
for (p = Config.peers; p; p = p->next) {
- if (neighborType(p, request) != PEER_PARENT)
+ if (neighborType(p, request->url) != PEER_PARENT)
continue;
if (!p->options.default_parent)
continue;
- if (!peerHTTPOkay(p, request))
+ if (!peerHTTPOkay(p, ps))
continue;
debugs(15, 3, "getDefaultParent: returning " << p->host);
if (thisPeer->http_port != s->s.port())
continue;
- debugs(15, DBG_IMPORTANT, "WARNING: Peer looks like this host");
-
- debugs(15, DBG_IMPORTANT, " Ignoring " <<
+ debugs(15, DBG_IMPORTANT, "WARNING: Peer looks like this host." <<
+ Debug::Extra << "Ignoring " <<
neighborTypeStr(thisPeer) << " " << thisPeer->host <<
"/" << thisPeer->http_port << "/" <<
thisPeer->icp.port);
neighborsUdpPing(HttpRequest * request,
StoreEntry * entry,
IRCB * callback,
- void *callback_data,
+ PeerSelector *ps,
int *exprep,
int *timeout)
{
int i;
int reqnum = 0;
int flags;
- icp_common_t *query;
int queries_sent = 0;
int peers_pinged = 0;
int parent_timeout = 0, parent_exprep = 0;
if (Config.peers == NULL)
return 0;
- assert(entry->swap_status == SWAPOUT_NONE);
+ assert(!entry->hasDisk());
mem->start_ping = current_time;
mem->ping_reply_callback = callback;
- mem->ircb_data = callback_data;
+ mem->ircb_data = ps;
reqnum = icpSetCacheKey((const cache_key *)entry->key);
debugs(15, 5, "neighborsUdpPing: Peer " << p->host);
- if (!peerWouldBePinged(p, request))
+ if (!peerWouldBePinged(p, ps))
continue; /* next CachePeer */
++peers_pinged;
if (p->icp.port == echo_port) {
debugs(15, 4, "neighborsUdpPing: Looks like a dumb cache, send DECHO ping");
- query = _icp_common_t::createMessage(ICP_DECHO, 0, url, reqnum, 0);
- icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0);
+ // TODO: Get ALE from callback_data if possible.
+ icpCreateAndSend(ICP_DECHO, 0, url, reqnum, 0,
+ icpOutgoingConn->fd, p->in_addr, nullptr);
} else {
flags = 0;
if (p->icp.version == ICP_VERSION_2)
flags |= ICP_FLAG_SRC_RTT;
- query = _icp_common_t::createMessage(ICP_QUERY, flags, url, reqnum, 0);
-
- icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0.0);
+ // TODO: Get ALE from callback_data if possible.
+ icpCreateAndSend(ICP_QUERY, flags, url, reqnum, 0,
+ icpOutgoingConn->fd, p->in_addr, nullptr);
}
}
}
} else if (neighborUp(p)) {
/* its alive, expect a reply from it */
- if (neighborType(p, request) == PEER_PARENT) {
+ if (neighborType(p, request->url) == PEER_PARENT) {
++parent_exprep;
parent_timeout += p->stats.rtt;
} else {
/* lookup the digest of a given CachePeer */
lookup_t
-peerDigestLookup(CachePeer * p, HttpRequest * request)
+peerDigestLookup(CachePeer * p, PeerSelector * ps)
{
#if USE_CACHE_DIGESTS
+ assert(ps);
+ HttpRequest *request = ps->request;
const cache_key *key = request ? storeKeyPublicByRequest(request) : NULL;
assert(p);
assert(request);
if (!p->digest) {
debugs(15, 5, "peerDigestLookup: gone!");
return LOOKUP_NONE;
- } else if (!peerHTTPOkay(p, request)) {
+ } else if (!peerHTTPOkay(p, ps)) {
debugs(15, 5, "peerDigestLookup: !peerHTTPOkay");
return LOOKUP_NONE;
} else if (!p->digest->flags.needed) {
assert(p->digest->cd);
/* does digest predict a hit? */
- if (!cacheDigestTest(p->digest->cd, key))
+ if (!p->digest->cd->contains(key))
return LOOKUP_MISS;
debugs(15, 5, "peerDigestLookup: peer " << p->host << " says HIT!");
/* select best CachePeer based on cache digests */
CachePeer *
-neighborsDigestSelect(HttpRequest * request)
+neighborsDigestSelect(PeerSelector *ps)
{
CachePeer *best_p = NULL;
#if USE_CACHE_DIGESTS
+ assert(ps);
+ HttpRequest *request = ps->request;
int best_rtt = 0;
int choice_count = 0;
if (i == 1)
first_ping = p;
- lookup = peerDigestLookup(p, request);
+ lookup = peerDigestLookup(p, ps);
if (lookup == LOOKUP_NONE)
continue;
* * from being used
*/
static int
-ignoreMulticastReply(CachePeer * p, MemObject * mem)
+ignoreMulticastReply(CachePeer * p, PeerSelector * ps)
{
if (p == NULL)
return 0;
if (!p->options.mcast_responder)
return 0;
- if (peerHTTPOkay(p, mem->request))
+ if (peerHTTPOkay(p, ps))
return 0;
return 1;
debugs(15, 6, "neighborsUdpAck: opcode " << opcode << " '" << storeKeyText(key) << "'");
- if (NULL != (entry = Store::Root().get(key)))
+ if ((entry = Store::Root().findCallbackXXX(key)))
mem = entry->mem_obj;
if ((p = whichPeer(from)))
return;
}
+ if (!mem->ircb_data) {
+ debugs(12, DBG_IMPORTANT, "BUG: missing ICP callback data for " << *entry);
+ neighborCountIgnored(p);
+ return;
+ }
+
debugs(15, 3, "neighborsUdpAck: " << opcode_d << " for '" << storeKeyText(key) << "' from " << (p ? p->host : "source") << " ");
if (p) {
- ntype = neighborType(p, mem->request);
+ ntype = neighborType(p, mem->request->url);
}
- if (ignoreMulticastReply(p, mem)) {
+ if (ignoreMulticastReply(p, mem->ircb_data)) {
neighborCountIgnored(p);
} else if (opcode == ICP_MISS) {
if (p == NULL) {
neighborUp(const CachePeer * p)
{
if (!p->tcp_up) {
- if (!peerProbeConnect((CachePeer *) p)) {
- debugs(15, 8, "neighborUp: DOWN (probed): " << p->host << " (" << p->in_addr << ")");
- return 0;
- }
+ peerProbeConnect(const_cast<CachePeer*>(p));
+ return 0;
}
/*
return 1;
}
-void
-peerNoteDigestGone(CachePeer * p)
+time_t
+positiveTimeout(const time_t timeout)
{
-#if USE_CACHE_DIGESTS
- cbdataReferenceDone(p->digest);
-#endif
+ return max(static_cast<time_t>(1), timeout);
}
static void
CachePeer *p = (CachePeer *)data;
- int j;
-
if (p->n_addresses == 0) {
debugs(15, DBG_IMPORTANT, "Configuring " << neighborTypeStr(p) << " " << p->host << "/" << p->http_port << "/" << p->icp.port);
return;
}
- if ((int) ia->count < 1) {
+ if (ia->empty()) {
debugs(0, DBG_CRITICAL, "WARNING: No IP address found for '" << p->host << "'!");
return;
}
- p->tcp_up = p->connect_fail_limit;
-
- for (j = 0; j < (int) ia->count && j < PEER_MAX_ADDRESSES; ++j) {
- p->addresses[j] = ia->in_addrs[j];
- debugs(15, 2, "--> IP address #" << j << ": " << p->addresses[j]);
- ++ p->n_addresses;
+ for (const auto &ip: ia->goodAndBad()) { // TODO: Consider using just good().
+ if (p->n_addresses < PEER_MAX_ADDRESSES) {
+ const auto idx = p->n_addresses++;
+ p->addresses[idx] = ip;
+ debugs(15, 2, "--> IP address #" << idx << ": " << p->addresses[idx]);
+ } else {
+ debugs(15, 3, "ignoring remaining " << (ia->size() - p->n_addresses) << " ips");
+ break;
+ }
}
p->in_addr.setEmpty();
p->in_addr = p->addresses[0];
p->in_addr.port(p->icp.port);
+ peerProbeConnect(p, true); // detect any died or revived peers ASAP
+
if (p->type == PEER_MULTICAST)
peerCountMcastPeersSchedule(p, 10);
peerConnectSucceded(CachePeer * p)
{
if (!p->tcp_up) {
- debugs(15, 2, "TCP connection to " << p->host << "/" << p->http_port << " succeded");
+ debugs(15, 2, "TCP connection to " << p->host << "/" << p->http_port << " succeeded");
p->tcp_up = p->connect_fail_limit; // NP: so peerAlive(p) works properly.
peerAlive(p);
if (!p->n_addresses)
p->tcp_up = p->connect_fail_limit;
}
+/// whether new TCP probes are currently banned
+static bool
+peerProbeIsBusy(const CachePeer *p)
+{
+ if (p->testing_now > 0) {
+ debugs(15, 8, "yes, probing " << p);
+ return true;
+ }
+ if (squid_curtime - p->stats.last_connect_probe == 0) {
+ debugs(15, 8, "yes, just probed " << p);
+ return true;
+ }
+ return false;
+}
/*
* peerProbeConnect will be called on dead peers by neighborUp
*/
-static bool
-peerProbeConnect(CachePeer * p)
+static void
+peerProbeConnect(CachePeer *p, const bool reprobeIfBusy)
{
- time_t ctimeout = p->connect_timeout > 0 ? p->connect_timeout : Config.Timeout.peer_connect;
- bool ret = (squid_curtime - p->stats.last_connect_failure) > (ctimeout * 10);
-
- if (p->testing_now > 0)
- return ret;/* probe already running */
-
- if (squid_curtime - p->stats.last_connect_probe == 0)
- return ret;/* don't probe to often */
+ if (peerProbeIsBusy(p)) {
+ p->reprobe = reprobeIfBusy;
+ return;
+ }
+ p->reprobe = false;
+ const auto ctimeout = p->connectTimeout();
/* for each IP address of this CachePeer. find one that we can connect to and probe it. */
for (int i = 0; i < p->n_addresses; ++i) {
Comm::ConnectionPointer conn = new Comm::Connection;
}
p->stats.last_connect_probe = squid_curtime;
-
- return ret;
}
static void
-- p->testing_now;
conn->close();
// TODO: log this traffic.
+
+ if (p->reprobe)
+ peerProbeConnect(p);
}
static void
static void
peerCountMcastPeersStart(void *data)
{
- CachePeer *p = (CachePeer *)data;
- ps_state *psstate;
- StoreEntry *fake;
+ const auto peer = static_cast<CachePeer*>(data);
+ CallContextCreator([peer] {
+ peerCountMcastPeersCreateAndSend(peer);
+ });
+ peerCountMcastPeersSchedule(peer, MCAST_COUNT_RATE);
+}
+
+/// initiates an ICP transaction to a multicast peer
+static void
+peerCountMcastPeersCreateAndSend(CachePeer * const p)
+{
+ // XXX: Do not create lots of complex fake objects (while abusing their
+ // APIs) to pass around a few basic data points like start_ping and ping!
MemObject *mem;
- icp_common_t *query;
int reqnum;
+ // TODO: use class AnyP::Uri instead of constructing and re-parsing a string
LOCAL_ARRAY(char, url, MAX_URL);
assert(p->type == PEER_MULTICAST);
p->mcast.flags.count_event_pending = false;
snprintf(url, MAX_URL, "http://");
p->in_addr.toUrl(url+7, MAX_URL -8 );
strcat(url, "/");
- fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET);
- HttpRequest *req = HttpRequest::CreateFromUrl(url);
- psstate = new ps_state;
+ const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast);
+ auto *req = HttpRequest::FromUrlXXX(url, mx);
+ assert(req != nullptr);
+ const AccessLogEntry::Pointer ale = new AccessLogEntry;
+ ale->request = req;
+ CodeContext::Reset(ale);
+ StoreEntry *fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET);
+ const auto psstate = new PeerSelector(nullptr);
psstate->request = req;
HTTPMSGLOCK(psstate->request);
psstate->entry = fake;
- psstate->callback = NULL;
- psstate->callback_data = cbdataReference(p);
+ psstate->peerCountMcastPeerXXX = cbdataReference(p);
psstate->ping.start = current_time;
+ psstate->al = ale;
mem = fake->mem_obj;
mem->request = psstate->request;
- HTTPMSGLOCK(mem->request);
mem->start_ping = current_time;
mem->ping_reply_callback = peerCountHandleIcpReply;
mem->ircb_data = psstate;
mcastSetTtl(icpOutgoingConn->fd, p->mcast.ttl);
p->mcast.id = mem->id;
reqnum = icpSetCacheKey((const cache_key *)fake->key);
- query = _icp_common_t::createMessage(ICP_QUERY, 0, url, reqnum, 0);
- icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0);
- fake->ping_status = PING_WAITING;
+ icpCreateAndSend(ICP_QUERY, 0, url, reqnum, 0,
+ icpOutgoingConn->fd, p->in_addr, psstate->al);
+ fake->ping_status = PING_WAITING; // TODO: refactor to use PeerSelector::startPingWaiting()
eventAdd("peerCountMcastPeersDone",
peerCountMcastPeersDone,
psstate,
Config.Timeout.mcast_icp_query / 1000.0, 1);
p->mcast.flags.counting = true;
- peerCountMcastPeersSchedule(p, MCAST_COUNT_RATE);
}
static void
peerCountMcastPeersDone(void *data)
{
- ps_state *psstate = (ps_state *)data;
+ const auto psstate = static_cast<PeerSelector*>(data);
+ CallBack(psstate->al, [psstate] {
+ peerCountMcastPeersAbort(psstate);
+ delete psstate;
+ });
+}
+
+/// ends counting of multicast ICP replies
+/// to the ICP query initiated by peerCountMcastPeersCreateAndSend()
+static void
+peerCountMcastPeersAbort(PeerSelector * const psstate)
+{
StoreEntry *fake = psstate->entry;
- if (cbdataReferenceValid(psstate->callback_data)) {
- CachePeer *p = (CachePeer *)psstate->callback_data;
+ if (cbdataReferenceValid(psstate->peerCountMcastPeerXXX)) {
+ CachePeer *p = (CachePeer *)psstate->peerCountMcastPeerXXX;
p->mcast.flags.counting = false;
p->mcast.avg_n_members = Math::doubleAverage(p->mcast.avg_n_members, (double) psstate->ping.n_recv, ++p->mcast.n_times_counted, 10);
debugs(15, DBG_IMPORTANT, "Group " << p->host << ": " << psstate->ping.n_recv <<
p->mcast.n_replies_expected = (int) p->mcast.avg_n_members;
}
- cbdataReferenceDone(psstate->callback_data);
+ cbdataReferenceDone(psstate->peerCountMcastPeerXXX);
- fake->abort(); // sets ENTRY_ABORTED and initiates releated cleanup
- HTTPMSGUNLOCK(fake->mem_obj->request);
+ fake->abort(); // sets ENTRY_ABORTED and initiates related cleanup
+ fake->mem_obj->request = nullptr;
fake->unlock("peerCountMcastPeersDone");
- delete psstate;
}
static void
peerCountHandleIcpReply(CachePeer * p, peer_t, AnyP::ProtocolType proto, void *, void *data)
{
- ps_state *psstate = (ps_state *)data;
+ const auto psstate = static_cast<PeerSelector*>(data);
StoreEntry *fake = psstate->entry;
assert(fake);
MemObject *mem = fake->mem_obj;
if (p->options.htcp) {
storeAppendPrintf(sentry, " htcp");
if (p->options.htcp_oldsquid || p->options.htcp_no_clr || p->options.htcp_no_purge_clr || p->options.htcp_only_clr) {
- int doneopts=0;
- if (p->options.htcp_oldsquid)
- storeAppendPrintf(sentry, "%soldsquid",(doneopts++>0?",":"="));
- if (p->options.htcp_no_clr)
- storeAppendPrintf(sentry, "%sno-clr",(doneopts++>0?",":"="));
- if (p->options.htcp_no_purge_clr)
- storeAppendPrintf(sentry, "%sno-purge-clr",(doneopts++>0?",":"="));
- if (p->options.htcp_only_clr)
- storeAppendPrintf(sentry, "%sonly-clr",(doneopts++>0?",":"="));
+ bool doneopts = false;
+ if (p->options.htcp_oldsquid) {
+ storeAppendPrintf(sentry, "oldsquid");
+ doneopts = true;
+ }
+ if (p->options.htcp_no_clr) {
+ storeAppendPrintf(sentry, "%sno-clr",(doneopts?",":"="));
+ doneopts = true;
+ }
+ if (p->options.htcp_no_purge_clr) {
+ storeAppendPrintf(sentry, "%sno-purge-clr",(doneopts?",":"="));
+ doneopts = true;
+ }
+ if (p->options.htcp_only_clr) {
+ storeAppendPrintf(sentry, "%sonly-clr",(doneopts?",":"="));
+ //doneopts = true; // uncomment if more opts are added
+ }
}
}
#endif
if (p->mcast.ttl > 0)
storeAppendPrintf(sentry, " ttl=%d", p->mcast.ttl);
- if (p->connect_timeout > 0)
- storeAppendPrintf(sentry, " connect-timeout=%d", (int) p->connect_timeout);
+ if (p->connect_timeout_raw > 0)
+ storeAppendPrintf(sentry, " connect-timeout=%d", (int)p->connect_timeout_raw);
if (p->connect_fail_limit != PEER_TCP_MAGIC_COUNT)
storeAppendPrintf(sentry, " connect-fail-limit=%d", p->connect_fail_limit);
else if (p->connection_auth == 2)
storeAppendPrintf(sentry, " connection-auth=auto");
+ p->secure.dumpCfg(sentry,"tls-");
storeAppendPrintf(sentry, "\n");
}
dump_peers(StoreEntry * sentry, CachePeer * peers)
{
char ntoabuf[MAX_IPSTRLEN];
- icp_opcode op;
int i;
if (peers == NULL)
} else {
#endif
- for (op = ICP_INVALID; op < ICP_END; ++op) {
+ for (auto op : WholeEnum<icp_opcode>()) {
if (e->icp.counts[op] == 0)
continue;
void
neighborsHtcpReply(const cache_key * key, HtcpReplyData * htcp, const Ip::Address &from)
{
- StoreEntry *e = Store::Root().get(key);
+ StoreEntry *e = Store::Root().findCallbackXXX(key);
MemObject *mem = NULL;
CachePeer *p;
peer_t ntype = PEER_NONE;
return;
}
+ if (!mem->ircb_data) {
+ debugs(12, DBG_IMPORTANT, "BUG: missing HTCP callback data for " << *e);
+ neighborCountIgnored(p);
+ return;
+ }
+
if (p) {
- ntype = neighborType(p, mem->request);
+ ntype = neighborType(p, mem->request->url);
neighborUpdateRtt(p, mem);
}
- if (ignoreMulticastReply(p, mem)) {
+ if (ignoreMulticastReply(p, mem->ircb_data)) {
neighborCountIgnored(p);
return;
}
debugs(15, 3, "neighborsHtcpReply: e = " << e);
+ // TODO: Refactor (ping_reply_callback,ircb_data) to add CodeContext.
mem->ping_reply_callback(p, ntype, AnyP::PROTO_HTCP, htcp, mem->ircb_data);
}
* Send HTCP CLR messages to all peers configured to receive them.
*/
void
-neighborsHtcpClear(StoreEntry * e, const char *uri, HttpRequest * req, const HttpRequestMethod &method, htcp_clr_reason reason)
+neighborsHtcpClear(StoreEntry * e, HttpRequest * req, const HttpRequestMethod &method, htcp_clr_reason reason)
{
CachePeer *p;
char buf[128];
continue;
}
debugs(15, 3, "neighborsHtcpClear: sending CLR to " << p->in_addr.toUrl(buf, 128));
- htcpClear(e, uri, req, method, p, reason);
+ htcpClear(e, req, method, p, reason);
}
}