54#define MCAST_COUNT_RATE 900
93 return "Multicast Group";
103 debugs(15, 3,
"whichPeer: from " << from);
106 for (j = 0; j < p->n_addresses; ++j) {
107 if (from == p->addresses[j] && from.
port() == p->icp.port) {
142 assert(request !=
nullptr);
147 debugs(15, 2,
"multicast-siblings optimization match for " << *p <<
", " << request->
url.
authority());
172 checklist.
syncAle(request,
nullptr);
223 return remaining > 0;
234 const int usableIdles = 0;
236 const int available = standbys + usableIdles;
237 debugs(15, 7, available <<
'=' << standbys <<
'+' << usableIdles);
238 return available > 0;
276 debugs(15, 3,
"neighborsCount: " << count);
288 const auto p = peer.get();
299 debugs(15, 3,
"returning " << *p);
303 debugs(15, 3,
"none found");
316 const auto p = peer.get();
317 if (!p->options.roundrobin)
330 if (p->weight == q->
weight) {
359 const auto p = peer.get();
361 if (!p->options.weighted_roundrobin)
378 if (!p->options.weighted_roundrobin)
390 if (weighted_rtt < 1)
395 debugs(15, 3,
"getWeightedRoundRobinParent: weighted_rtt " << weighted_rtt);
428 static bool event_added =
false;
475 const auto p = peer.get();
480 if (!p->options.default_parent)
486 debugs(15, 3,
"returning " << *p);
492 debugs(15, 3,
"none found");
500 "Peer Cache Statistics",
515 if (0 != strcmp(thisPeer->host, me))
519 if (thisPeer->http_port != s->s.port())
525 peersToRemove.push_back(thisPeer.get());
530 while (peersToRemove.size()) {
531 const auto p = peersToRemove.back();
532 peersToRemove.pop_back();
540 echo_port = sep ? ntohs((
unsigned short) sep->s_port) : 7;
551 const char *url = entry->
url();
555 int peers_pinged = 0;
556 int parent_timeout = 0, parent_exprep = 0;
557 int sibling_timeout = 0, sibling_exprep = 0;
558 int mcast_timeout = 0, mcast_exprep = 0;
579 debugs(15, 5,
"candidate: " << *p);
586 debugs(15, 4,
"pinging cache_peer " << *p <<
" for '" << url <<
"'");
590 debugs(15, 3,
"neighborsUdpPing: reqnum = " << reqnum);
593 if (p->options.htcp && !p->options.htcp_only_clr) {
595 debugs(15,
DBG_CRITICAL,
"ERROR: HTCP is disabled! Cannot send HTCP request to peer.");
599 debugs(15, 3,
"neighborsUdpPing: sending HTCP query");
614 debugs(15, 4,
"neighborsUdpPing: Looks like a dumb cache, send DECHO ping");
632 ++ p->stats.pings_sent;
635 mcast_exprep += p->mcast.n_replies_expected;
636 mcast_timeout += (p->stats.rtt * p->mcast.n_replies_expected);
642 parent_timeout += p->stats.rtt;
645 sibling_timeout += p->stats.rtt;
672 *exprep = parent_exprep + sibling_exprep + mcast_exprep;
682 *timeout = 2 * parent_timeout / parent_exprep;
683 else if (mcast_exprep)
684 *timeout = 2 * mcast_timeout / mcast_exprep;
686 *timeout = 2 * sibling_timeout / sibling_exprep;
711 debugs(15, 5,
"cache_peer " << *p);
715 debugs(15, 5,
"peerDigestLookup: gone!");
718 debugs(15, 5,
"peerDigestLookup: !peerHTTPOkay");
721 debugs(15, 5,
"peerDigestLookup: note need");
729 debugs(15, 5,
"OK to lookup cache_peer " << *p);
736 debugs(15, 5,
"HIT for cache_peer " << *p);
757 int choice_count = 0;
758 int ichoice_count = 0;
784 debugs(15, 5,
"cache_peer " << *p <<
" rtt: " << p_rtt);
787 if (!best_p || (p_rtt && p_rtt < best_rtt)) {
794 debugs(15, 4,
"cache_peer " << *p <<
" leads with rtt " << best_rtt);
798 debugs(15, 4,
"neighborsDigestSelect: choices: " << choice_count <<
" (" << ichoice_count <<
")");
843 int rtt, rtt_av_factor;
853 if (rtt < 1 || rtt > 10000)
890 static uint64_t ignoredReplies = 0;
892 debugs(15,
DBG_IMPORTANT,
"WARNING: Ignored " << ignoredReplies <<
" ICP replies from non-peers" <<
893 Debug::Extra <<
"last seen non-peer source address: " << from <<
935 debugs(15, 6,
"neighborsUdpAck: opcode " << opcode <<
" '" <<
storeKeyText(key) <<
"'");
952 if (
nullptr == entry) {
960 debugs(15, 3,
"neighborsUdpAck: '" <<
storeKeyText(key) <<
"' already being fetched.");
965 if (mem ==
nullptr) {
966 debugs(15, 2,
"Ignoring " << opcode_d <<
" for missing mem_obj: " <<
storeKeyText(key));
1004 }
else if (opcode ==
ICP_HIT) {
1015 debug_trap(
"neighborsUdpAck: Found non-ICP cache as SIBLING\n");
1016 debug_trap(
"neighborsUdpAck: non-ICP neighbors must be a PARENT\n");
1033 " because over 95% of its replies are UDP_DENIED");
1043 debugs(15,
DBG_CRITICAL,
"ERROR: neighborsUdpAck: Unexpected ICP reply: " << opcode_d);
1051 if (!strcasecmp(name, p->name))
1062 peerProbeConnect(const_cast<CachePeer*>(p));
1072 debugs(15, 8,
"DOWN (no-ip): " << *p);
1077 debugs(15, 8,
"UP (no-query): " << *p);
1083 debugs(15, 8,
"DOWN (dead): " << *p);
1087 debugs(15, 8,
"UP: " << *p);
1094 return max(
static_cast<time_t
>(1), timeout);
1114 if (ia ==
nullptr) {
1128 debugs(15, 2,
"--> IP address #" << idx <<
": " << p->
addresses[idx]);
1192 debugs(15, 8,
"yes, probing " << p);
1196 debugs(15, 8,
"yes, just probed " << p);
1257 eventAdd(
"peerCountMcastPeersStart",
1268 const auto peer =
static_cast<CachePeer*
>(data);
1287 snprintf(url,
MAX_URL,
"http://");
1290 const auto mx = MasterXaction::MakePortless<XactionInitiator::initPeerMcast>();
1298 psstate->request = req;
1300 psstate->entry = fake;
1305 mem->
request = psstate->request;
1315 eventAdd(
"peerCountMcastPeersDone",
1327 peerCountMcastPeersAbort(psstate);
1344 " replies, "<< std::setw(4)<< std::setprecision(2) <<
1353 fake->
unlock(
"peerCountMcastPeersDone");
1366 ++ psstate->ping.n_recv;
1387 os <<
" proxy-only";
1393 os <<
" background-ping";
1402 os <<
" round-robin";
1413 os <<
" sourcehash";
1416 os <<
" weighted-round-robin";
1419 os <<
" multicast-responder";
1422 os <<
" multicast-siblings";
1425 os <<
" weight=" << p->
weight;
1428 os <<
" closest-only";
1433 std::vector<const char *, PoolingAllocator<const char *> > opts;
1435 opts.push_back(
"oldsquid");
1437 opts.push_back(
"no-clr");
1439 opts.push_back(
"no-purge-clr");
1441 opts.push_back(
"only-clr");
1443 opts.push_back(
"forward-clr");
1449 os <<
" no-netdb-exchange";
1457 os <<
" login=" << p->
login;
1468#if USE_CACHE_DIGESTS
1476 os <<
" allow-miss";
1488 os <<
" originserver";
1491 os <<
" forceddomain=" << p->
domain;
1494 os <<
" connection-auth=off";
1496 os <<
" connection-auth=on";
1498 os <<
" connection-auth=auto";
1515 for (
const auto &peer: *peers) {
1516 const auto e = peer.get();
1517 assert(e->host !=
nullptr);
1528 for (i = 0; i < e->n_addresses; ++i) {
1539 if (!e->options.no_query) {
1543 if (e->stats.last_reply > 0)
1552 e->stats.pings_acked,
1558 if (!e->options.no_query) {
1562 if (e->options.htcp) {
1573 if (e->icp.counts[op] == 0)
1590 if (e->stats.last_connect_failure) {
1607 debugs(15, 6,
"neighborsHtcpReply: " <<
1608 (htcp->
hit ?
"HIT" :
"MISS") <<
" " <<
1619 debugs(12, 3,
"neighyborsHtcpReply: Cache key '" <<
storeKeyText(key) <<
"' not found");
1626 debugs(15, 3,
"neighborsUdpAck: '" <<
storeKeyText(key) <<
"' already being fetched.");
1631 if (mem ==
nullptr) {
1638 debugs(15, 2,
"neighborsUdpAck: Entry " <<
storeKeyText(key) <<
" is not PING_WAITING");
1666 debugs(15, 3,
"neighborsHtcpReply: e = " << e);
1680 if (!p->options.htcp) {
1683 if (p->options.htcp_no_clr) {
1689 debugs(15, 3,
"neighborsHtcpClear: sending CLR to " << p->in_addr.toUrl(buf, 128));
1690 htcpClear(e, req, method, p.get(), reason);
const CachePeers & CurrentCachePeers()
void DeleteConfigured(CachePeer *const peer)
destroys the given peer after removing it from the set of configured peers
std::vector< CachePeer *, PoolingAllocator< CachePeer * > > RawCachePeers
Temporary, local storage of raw pointers to zero or more Config.peers.
void CallContextCreator(Fun &&creator)
void CallService(const CodeContext::Pointer &serviceContext, Fun &&service)
void CallBack(const CodeContext::Pointer &callbackContext, Fun &&callback)
CommCbFunPtrCallT< Dialer > * commCbCall(int debugSection, int debugLevel, const char *callName, const Dialer &dialer)
void CNCB(const Comm::ConnectionPointer &conn, Comm::Flag status, int xerrno, void *data)
void getOutgoingAddress(HttpRequest *request, const Comm::ConnectionPointer &conn)
RawPointerT< Pointer > RawPointer(const char *label, const Pointer &ptr)
convenience wrapper for creating RawPointerT<> objects
AnyP::PortCfgPointer HttpPortList
list of Squid http(s)_port configured
int matchDomainName(const char *h, const char *d, MatchDomainNameFlags flags)
int cbdataReferenceValid(const void *p)
#define cbdataReferenceDone(var)
#define cbdataReference(var)
Acl::Answer const & fastCheck()
void updateAle(const AccessLogEntry::Pointer &)
void syncAle(HttpRequest *adaptedRequest, const char *logUri) const override
assigns uninitialized adapted_request and url ALE components
SBuf & authority(bool requirePort=false) const
void port(const Port p)
reset authority port subcomponent
void host(const char *src)
std::ostream manipulator to print containers as flat lists
auto & prefixedBy(const char *const p)
a c-string to print before the first item (if any). Caller must ensure lifetime.
static void Start(const Pointer &job)
bool contains(const cache_key *key) const
CbcPointer< PeerPoolMgr > mgr
pool manager
struct CachePeer::@21::@27 flags
void noteSuccess()
reacts to a successful establishment of a connection to this cache_peer
NeighborTypeDomainList * typelist
int connection_auth
0 - off, 1 - on, 2 - auto
struct CachePeer::@20 options
int logged_state
so we can print dead/revived msgs
time_t last_connect_probe
Security::PeerOptions secure
security settings for peer connection
time_t connect_timeout_raw
connect_timeout; use connectTimeout() instead!
struct CachePeer::@18 stats
struct CachePeer::@21 mcast
char * domain
Forced domain.
int limit
the limit itself
struct CachePeer::@25 standby
optional "cache_peer standby=limit" feature
PrecomputedCodeContextPointer probeCodeContext
PconnPool * pool
idle connection pool for this peer
bool waitingForClose
a conn must close before we open a standby conn
struct CachePeer::icp_ icp
time_t connectTimeout() const
struct CachePeer::@19 htcp
void noteFailure()
reacts to a failed attempt to establish a connection to this cache_peer
Ip::Address addresses[10]
int conn_open
current opened connections
bool reprobe
whether to do another TCP probe after current TCP probes
cache_peer configuration storage
CachePeer & nextPeerToPing(size_t iteration)
auto size() const
the number of currently stored (i.e. added and not removed) cache_peers
Cbc * valid() const
was set and is valid
static const Pointer & Current()
static void Reset()
forgets the current context, setting it to nil/unknown
void setHost(const char *)
set the hostname note for this connection
void setPeer(CachePeer *p)
static std::ostream & Extra(std::ostream &)
size_t size() const noexcept
all cached IPs
IpsSelector< IpsIterator > goodAndBad() const
all IPs
bool empty() const noexcept
whether we cached no IPs at all
encapsulates DNS lookup results
char cd_host[SQUIDHOSTNAMELEN]
static HttpRequest * FromUrlXXX(const char *url, const MasterXaction::Pointer &, const HttpRequestMethod &method=Http::METHOD_GET)
AnyP::Uri url
the request URI
void setEmpty()
Fast reset of the stored content to what would be after default constructor.
char * toUrl(char *buf, unsigned int len) const
unsigned short port() const
IRCB * ping_reply_callback
HttpRequestPointer request
struct timeval start_ping
representation of a neighbor_type_domain configuration directive. A POD
NeighborTypeDomainList * next
struct PeerDigest::@67 flags
static void Checkpoint(const Pointer &mgr, const char *reason)
AccessLogEntry::Pointer al
info for the future access.log entry
void * peerCountMcastPeerXXX
a hack to help peerCountMcastPeersStart()
virtual void dumpCfg(std::ostream &, const char *pfx) const
output squid.conf syntax with 'pfx' prefix on parameters for the stored settings
struct SquidConfig::@77 Timeout
struct SquidConfig::@90 onoff
struct SquidConfig::@78 Port
time_t backgroundPingRate
int unlock(const char *context)
bool hasDisk(const sdirno dirn=-1, const sfileno filen=-1) const
const char * getMD5Text() const
ping_status_t ping_status
StoreEntry * findCallbackXXX(const cache_key *)
A const & max(A const &lhs, A const &rhs)
#define debugs(SECTION, LEVEL, CONTENT)
#define RTT_BACKGROUND_AV_FACTOR
#define PEER_TCP_MAGIC_COUNT
#define PEER_MAX_ADDRESSES
#define EBIT_TEST(flag, bit)
@ PING_WAITING
Sent ICP queries to peers and still awaiting responses.
void eventAddIsh(const char *name, EVH *func, void *arg, double delta_ish, int weight)
int eventFind(EVH *func, void *arg)
void eventDelete(EVH *func, void *arg)
void eventAdd(const char *name, EVH *func, void *arg, double when, int weight, bool cbdata)
void ipcache_nbgethostbyname(const char *name, IPH *handler, void *handlerData)
int icpSetCacheKey(const cache_key *key)
void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from, AccessLogEntryPointer)
Comm::ConnectionPointer icpOutgoingConn
Comm::ConnectionPointer icpIncomingConn
int htcpQuery(StoreEntry *e, HttpRequest *req, CachePeer *p)
void htcpClear(StoreEntry *e, HttpRequest *req, const HttpRequestMethod &, CachePeer *p, htcp_clr_reason reason)
void HTTPMSGLOCK(Http::Message *a)
const char * icp_opcode_str[]
#define MAX_IPSTRLEN
Length of buffer that needs to be allocated to old a null-terminated IP-string.
void IPH(const ipcache_addrs *, const Dns::LookupDetails &details, void *)
const char * lookup_t_str[]
int mcastSetTtl(int fd, int mcast_ttl)
bool IsConnOpen(const Comm::ConnectionPointer &conn)
int intPercent(const int a, const int b)
double doubleAverage(const double, const double, int, const int)
int intAverage(const int, const int, int, const int)
void RegisterAction(char const *action, char const *desc, OBJH *handler, Protected, Atomic, Format)
Controller & Root()
safely access controller singleton
const char * FormatHttpd(time_t)
static void dump_peers(StoreEntry *, CachePeers *)
static void peerClearRRLoop(void *data)
static void peerScheduleDnsRefreshCheck(const double delayInSeconds)
static void peerCountMcastPeersDone(void *data)
void peerNoteDigestLookup(HttpRequest *request, CachePeer *p, lookup_t lookup)
static int peerWouldBePinged(const CachePeer *, PeerSelector *)
static void neighborAliveHtcp(CachePeer *, const MemObject *, const HtcpReplyData *)
static void peerCountMcastPeersSchedule(CachePeer *p, time_t when)
void neighborsHtcpClear(StoreEntry *e, HttpRequest *req, const HttpRequestMethod &method, htcp_clr_reason reason)
CachePeer * getFirstUpParent(PeerSelector *ps)
CachePeer * findCachePeerByName(const char *const name)
cache_peer with a given name (or nil)
static IPH peerDNSConfigure
CachePeer * whichPeer(const Ip::Address &from)
static void peerCountMcastPeersCreateAndSend(CachePeer *p)
initiates an ICP transaction to a multicast peer
void neighborsHtcpReply(const cache_key *key, HtcpReplyData *htcp, const Ip::Address &from)
static void neighborUpdateRtt(CachePeer *p, MemObject *mem)
static CNCB peerProbeConnectDone
void peerAlive(CachePeer *p)
void neighbors_init(void)
static OBJH neighborDumpPeers
bool peerHasConnAvailable(const CachePeer *p)
Whether the peer has idle or standby connections that can be used now.
int neighborsCount(PeerSelector *ps)
static void peerCountMcastPeersAbort(PeerSelector *)
void dump_peer_options(StoreEntry *sentry, CachePeer *p)
int neighborUp(const CachePeer *p)
static bool peerProbeIsBusy(const CachePeer *p)
whether new TCP probes are currently banned
int peerHTTPOkay(const CachePeer *p, PeerSelector *ps)
CachePeer * getDefaultParent(PeerSelector *ps)
CachePeer * getRoundRobinParent(PeerSelector *ps)
const char * neighborTypeStr(const CachePeer *p)
time_t positiveTimeout(const time_t timeout)
bool peerAllowedToUse(const CachePeer *, PeerSelector *)
static void neighborsRegisterWithCacheManager()
void peerClearRRStart(void)
bool peerCanOpenMore(const CachePeer *p)
Whether we can open new connections to the peer (e.g., despite max-conn)
static void peerDnsRefreshStart()
peer_t neighborType(const CachePeer *p, const AnyP::Uri &url)
int neighborsUdpPing(HttpRequest *request, StoreEntry *entry, IRCB *callback, PeerSelector *ps, int *exprep, int *timeout)
CachePeer * neighborsDigestSelect(PeerSelector *ps)
static IRCB peerCountHandleIcpReply
static unsigned short echo_port
static void neighborAlive(CachePeer *, const MemObject *, const icp_common_t *)
lookup_t peerDigestLookup(CachePeer *p, PeerSelector *ps)
static void neighborCountIgnored(CachePeer *)
void peerConnClosed(CachePeer *p)
Notifies peer of an associated connection closure.
static void neighborIgnoreNonPeer(const Ip::Address &, icp_opcode)
static int ignoreMulticastReply(CachePeer *p, PeerSelector *ps)
void neighborsUdpAck(const cache_key *key, icp_common_t *header, const Ip::Address &from)
static void peerProbeConnect(CachePeer *, const bool reprobeIfBusy=false)
CachePeer * getWeightedRoundRobinParent(PeerSelector *ps)
static void peerCountMcastPeersStart(void *data)
static void peerDnsRefreshCheck(void *)
int netdbHostRtt(const char *host)
void netdbExchangeStart(void *data)
struct servent * xgetservbyname(const char *name, const char *proto)
POSIX getservbyname(3) equivalent.
void peerDigestNeeded(PeerDigest *pd)
#define LOCAL_ARRAY(type, name, size)
bool statSawRecentRequests()
unsigned char cache_key
Store key.
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
StoreEntry * storeCreateEntry(const char *url, const char *logUrl, const RequestFlags &flags, const HttpRequestMethod &method)
const cache_key * storeKeyPublicByRequest(HttpRequest *request, const KeyScope keyScope)
const char * storeKeyText(const cache_key *key)
struct timeval current_time
the current UNIX time in timeval {seconds, microseconds} format
int tvSubMsec(struct timeval t1, struct timeval t2)
void IRCB(CachePeer *, peer_t, AnyP::ProtocolType, void *, void *data)