*/
#include "squid.h"
-#include "ProtoPort.h"
#include "acl/FilledChecklist.h"
+#include "anyp/PortCfg.h"
+#include "CacheDigest.h"
+#include "CachePeer.h"
#include "comm/Connection.h"
#include "comm/ConnOpener.h"
-#include "CacheManager.h"
#include "event.h"
+#include "forward.h"
+#include "globals.h"
#include "htcp.h"
#include "HttpRequest.h"
+#include "icmp/net_db.h"
#include "ICP.h"
+#include "int.h"
+#include "ip/Address.h"
+#include "ip/tools.h"
+#include "ipcache.h"
#include "MemObject.h"
+#include "mgr/Registration.h"
+#include "multicast.h"
+#include "neighbors.h"
#include "PeerDigest.h"
#include "PeerSelectState.h"
+#include "SquidConfig.h"
#include "SquidMath.h"
#include "SquidTime.h"
+#include "stat.h"
#include "Store.h"
-#include "icmp/net_db.h"
-#include "ip/Address.h"
+#include "store_key_md5.h"
+#include "tools.h"
+#include "URL.h"
/* count mcast group peers every 15 minutes */
#define MCAST_COUNT_RATE 900
-int peerAllowedToUse(const peer *, HttpRequest *);
-static int peerWouldBePinged(const peer *, HttpRequest *);
-static void neighborRemove(peer *);
-static void neighborAlive(peer *, const MemObject *, const icp_common_t *);
+bool peerAllowedToUse(const CachePeer *, HttpRequest *);
+static int peerWouldBePinged(const CachePeer *, HttpRequest *);
+static void neighborRemove(CachePeer *);
+static void neighborAlive(CachePeer *, const MemObject *, const icp_common_t *);
#if USE_HTCP
-static void neighborAliveHtcp(peer *, const MemObject *, const htcpReplyData *);
+static void neighborAliveHtcp(CachePeer *, const MemObject *, const htcpReplyData *);
#endif
-static void neighborCountIgnored(peer *);
+static void neighborCountIgnored(CachePeer *);
static void peerRefreshDNS(void *);
static IPH peerDNSConfigure;
-static bool peerProbeConnect(peer *);
+static bool peerProbeConnect(CachePeer *);
static CNCB peerProbeConnectDone;
static void peerCountMcastPeersDone(void *data);
static void peerCountMcastPeersStart(void *data);
-static void peerCountMcastPeersSchedule(peer * p, time_t when);
+static void peerCountMcastPeersSchedule(CachePeer * p, time_t when);
static IRCB peerCountHandleIcpReply;
static void neighborIgnoreNonPeer(const Ip::Address &, icp_opcode);
static OBJH neighborDumpPeers;
static OBJH neighborDumpNonPeers;
-static void dump_peers(StoreEntry * sentry, peer * peers);
+static void dump_peers(StoreEntry * sentry, CachePeer * peers);
-static icp_common_t echo_hdr;
-static u_short echo_port;
+static unsigned short echo_port;
static int NLateReplies = 0;
-static peer *first_ping = NULL;
+static CachePeer *first_ping = NULL;
const char *
-neighborTypeStr(const peer * p)
+neighborTypeStr(const CachePeer * p)
{
if (p->type == PEER_NONE)
return "Non-Peer";
return "Parent";
}
-
-peer *
+CachePeer *
whichPeer(const Ip::Address &from)
{
int j;
- peer *p = NULL;
+ CachePeer *p = NULL;
debugs(15, 3, "whichPeer: from " << from);
for (p = Config.peers; p; p = p->next) {
- for (j = 0; j < p->n_addresses; j++) {
+ for (j = 0; j < p->n_addresses; ++j) {
if (from == p->addresses[j] && from.GetPort() == p->icp.port) {
return p;
}
}
peer_t
-neighborType(const peer * p, const HttpRequest * request)
+neighborType(const CachePeer * p, const HttpRequest * request)
{
- const struct _domain_type *d = NULL;
+ const domain_type *d = NULL;
for (d = p->typelist; d; d = d->next) {
if (0 == matchDomainName(request->GetHost(), d->domain))
return p->type;
}
-/*
- * peerAllowedToUse
- *
- * this function figures out if it is appropriate to fetch REQUEST
- * from PEER.
+/**
+ * \return Whether it is appropriate to fetch REQUEST from PEER.
*/
-int
-peerAllowedToUse(const peer * p, HttpRequest * request)
+bool
+peerAllowedToUse(const CachePeer * p, HttpRequest * request)
{
- const struct _domain_ping *d = NULL;
- int do_ping = 1;
+ const domain_ping *d = NULL;
assert(request != NULL);
if (neighborType(p, request) == PEER_SIBLING) {
debugs(15, 2, "peerAllowedToUse(" << p->name << ", " << request->GetHost() << ") : multicast-siblings optimization match");
#endif
if (request->flags.nocache)
- return 0;
+ return false;
if (request->flags.refresh)
- return 0;
+ return false;
if (request->flags.loopdetect)
- return 0;
+ return false;
if (request->flags.need_validation)
- return 0;
+ return false;
}
- if (p->peer_domain == NULL && p->access == NULL)
- return do_ping;
+ // 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 == METHOD_CONNECT && request->port != p->in_addr.GetPort())
+ return false;
- do_ping = 0;
+ if (p->peer_domain == NULL && p->access == NULL)
+ return true;
+ bool do_ping = false;
for (d = p->peer_domain; d; d = d->next) {
if (0 == matchDomainName(request->GetHost(), d->domain)) {
do_ping = d->do_ping;
do_ping = !d->do_ping;
}
- if (p->peer_domain && 0 == do_ping)
- return do_ping;
+ if (p->peer_domain && !do_ping)
+ return false;
if (p->access == NULL)
return do_ping;
checklist.src_addr = request->client_addr;
checklist.my_addr = request->my_addr;
-#if 0 && USE_IDENT
- /*
- * this is currently broken because 'request->user_ident' has been
- * moved to conn->rfc931 and we don't have access to the parent
- * ConnStateData here.
- */
- if (request->user_ident[0])
- xstrncpy(checklist.rfc931, request->user_ident, USER_IDENT_SZ);
-
-#endif
-
- return checklist.fastCheck();
+ return (checklist.fastCheck() == ACCESS_ALLOWED);
}
-/* Return TRUE if it is okay to send an ICP request to this peer. */
+/* Return TRUE if it is okay to send an ICP request to this CachePeer. */
static int
-peerWouldBePinged(const peer * p, HttpRequest * request)
+peerWouldBePinged(const CachePeer * p, HttpRequest * request)
{
- if (!peerAllowedToUse(p, request))
+ if (p->icp.port == 0)
return 0;
if (p->options.no_query)
return 0;
- if (p->options.background_ping && (squid_curtime - p->stats.last_query < Config.backgroundPingRate))
- return 0;
-
if (p->options.mcast_responder)
return 0;
if (p->n_addresses == 0)
return 0;
- if (p->icp.port == 0)
+ if (p->options.background_ping && (squid_curtime - p->stats.last_query < Config.backgroundPingRate))
return 0;
/* the case below seems strange, but can happen if the
if (!request->flags.hierarchical)
return 0;
+ if (!peerAllowedToUse(p, request))
+ return 0;
+
/* Ping dead peers every timeout interval */
if (squid_curtime - p->stats.last_query > Config.Timeout.deadPeer)
return 1;
return 1;
}
-/* Return TRUE if it is okay to send an HTTP request to this peer. */
+/* Return TRUE if it is okay to send an HTTP request to this CachePeer. */
int
-peerHTTPOkay(const peer * p, HttpRequest * request)
+peerHTTPOkay(const CachePeer * p, HttpRequest * request)
{
+ if (p->max_conn)
+ if (p->stats.conn_open >= p->max_conn)
+ return 0;
+
if (!peerAllowedToUse(p, request))
return 0;
if (!neighborUp(p))
return 0;
- if (p->max_conn)
- if (p->stats.conn_open >= p->max_conn)
- return 0;
-
return 1;
}
int
neighborsCount(HttpRequest * request)
{
- peer *p = NULL;
+ CachePeer *p = NULL;
int count = 0;
for (p = Config.peers; p; p = p->next)
if (peerWouldBePinged(p, request))
- count++;
+ ++count;
debugs(15, 3, "neighborsCount: " << count);
return count;
}
-peer *
+CachePeer *
getFirstUpParent(HttpRequest * request)
{
- peer *p = NULL;
+ CachePeer *p = NULL;
for (p = Config.peers; p; p = p->next) {
if (!neighborUp(p))
return p;
}
-peer *
+CachePeer *
getRoundRobinParent(HttpRequest * request)
{
- peer *p;
- peer *q = NULL;
+ CachePeer *p;
+ CachePeer *q = NULL;
for (p = Config.peers; p; p = p->next) {
if (!p->options.roundrobin)
if (p->weight == q->weight) {
if (q->rr_count < p->rr_count)
continue;
- } else if ( (double) q->rr_count / q->weight < (double) p->rr_count / p->weight) {
+ } else if ( ((double) q->rr_count / q->weight) < ((double) p->rr_count / p->weight)) {
continue;
}
}
}
if (q)
- q->rr_count++;
+ ++ q->rr_count;
debugs(15, 3, HERE << "returning " << (q ? q->host : "NULL"));
return q;
}
-peer *
+CachePeer *
getWeightedRoundRobinParent(HttpRequest * request)
{
- peer *p;
- peer *q = NULL;
+ CachePeer *p;
+ CachePeer *q = NULL;
int weighted_rtt;
for (p = Config.peers; p; p = p->next) {
}
/**
- * This gets called on startup and restart to kick off the peer round-robin
+ * This gets called on startup and restart to kick off the CachePeer round-robin
* maintenance event. It ensures that no matter how many times its called
* no more than one event is scheduled.
*/
void
peerClearRRStart(void)
{
- static int event_added = 0;
+ static bool event_added = false;
if (!event_added) {
peerClearRRLoop(NULL);
+ event_added=true;
}
}
* Called whenever the round-robin counters need to be reset to a sane state.
* So far those times are:
* - On startup and reconfigure - to set the counters to sane initial settings.
- * - When a peer has revived from dead, to prevent the revived peer being
+ * - When a CachePeer has revived from dead, to prevent the revived CachePeer being
* flooded with requests which it has 'missed' during the down period.
*/
void
peerClearRR()
{
- peer *p = NULL;
+ CachePeer *p = NULL;
for (p = Config.peers; p; p = p->next) {
p->rr_count = 0;
}
}
/**
- * Perform all actions when a peer is detected revived.
+ * Perform all actions when a CachePeer is detected revived.
*/
void
-peerAlive(peer *p)
+peerAlive(CachePeer *p)
{
if (p->stats.logged_state == PEER_DEAD && p->tcp_up) {
- debugs(15, 1, "Detected REVIVED " << neighborTypeStr(p) << ": " << p->name);
+ debugs(15, DBG_IMPORTANT, "Detected REVIVED " << neighborTypeStr(p) << ": " << p->name);
p->stats.logged_state = PEER_ALIVE;
peerClearRR();
}
p->stats.probe_start = 0;
}
-peer *
+CachePeer *
getDefaultParent(HttpRequest * request)
{
- peer *p = NULL;
+ CachePeer *p = NULL;
for (p = Config.peers; p; p = p->next) {
if (neighborType(p, request) != PEER_PARENT)
return NULL;
}
-/*
- * XXX DW thinks this function is equivalent to/redundant with
- * getFirstUpParent(). peerHTTPOkay() only returns true if the
- * peer is UP anyway, so this function would not return a
- * DOWN parent.
- */
-peer *
-getAnyParent(HttpRequest * request)
-{
- peer *p = NULL;
-
- for (p = Config.peers; p; p = p->next) {
- if (neighborType(p, request) != PEER_PARENT)
- continue;
-
- if (!peerHTTPOkay(p, request))
- continue;
-
- debugs(15, 3, "getAnyParent: returning " << p->host);
-
- return p;
- }
-
- debugs(15, 3, "getAnyParent: returning NULL");
- return NULL;
-}
-
-peer *
-getNextPeer(peer * p)
+CachePeer *
+getNextPeer(CachePeer * p)
{
return p->next;
}
-peer *
+CachePeer *
getFirstPeer(void)
{
return Config.peers;
}
static void
-neighborRemove(peer * target)
+neighborRemove(CachePeer * target)
{
- peer *p = NULL;
- peer **P = NULL;
+ CachePeer *p = NULL;
+ CachePeer **P = NULL;
p = Config.peers;
P = &Config.peers;
if (p) {
*P = p->next;
cbdataFree(p);
- Config.npeers--;
+ --Config.npeers;
}
first_ping = Config.peers;
static void
neighborsRegisterWithCacheManager()
{
- CacheManager *manager = CacheManager::GetInstance();
- manager->registerAction("server_list",
- "Peer Cache Statistics",
- neighborDumpPeers, 0, 1);
-
- if (theInIcpConnection >= 0) {
- manager->registerAction("non_peers",
- "List of Unknown sites sending ICP messages",
- neighborDumpNonPeers, 0, 1);
+ Mgr::RegisterAction("server_list",
+ "Peer Cache Statistics",
+ neighborDumpPeers, 0, 1);
+
+ if (Comm::IsConnOpen(icpIncomingConn)) {
+ Mgr::RegisterAction("non_peers",
+ "List of Unknown sites sending ICP messages",
+ neighborDumpNonPeers, 0, 1);
}
}
void
neighbors_init(void)
{
- Ip::Address nul;
- struct addrinfo *AI = NULL;
struct servent *sep = NULL;
const char *me = getMyHostname();
- peer *thisPeer = NULL;
- peer *next = NULL;
- int fd = theInIcpConnection;
+ CachePeer *thisPeer = NULL;
+ CachePeer *next = NULL;
neighborsRegisterWithCacheManager();
- /* setup addrinfo for use */
- nul.InitAddrInfo(AI);
-
- if (fd >= 0) {
-
- if (getsockname(fd, AI->ai_addr, &AI->ai_addrlen) < 0)
- debugs(15, 1, "getsockname(" << fd << "," << AI->ai_addr << "," << &AI->ai_addrlen << ") failed.");
+ if (Comm::IsConnOpen(icpIncomingConn)) {
for (thisPeer = Config.peers; thisPeer; thisPeer = next) {
- http_port_list *s = NULL;
next = thisPeer->next;
if (0 != strcmp(thisPeer->host, me))
continue;
- for (s = Config.Sockaddr.http; s; s = s->next) {
+ for (AnyP::PortCfg *s = Config.Sockaddr.http; s; s = s->next) {
if (thisPeer->http_port != s->s.GetPort())
continue;
- debugs(15, 1, "WARNING: Peer looks like this host");
+ debugs(15, DBG_IMPORTANT, "WARNING: Peer looks like this host");
- debugs(15, 1, " Ignoring " <<
+ debugs(15, DBG_IMPORTANT, " Ignoring " <<
neighborTypeStr(thisPeer) << " " << thisPeer->host <<
"/" << thisPeer->http_port << "/" <<
thisPeer->icp.port);
peerRefreshDNS((void *) 1);
- if (ICP_INVALID == echo_hdr.opcode) {
- echo_hdr.opcode = ICP_SECHO;
- echo_hdr.version = ICP_VERSION_CURRENT;
- echo_hdr.length = 0;
- echo_hdr.reqnum = 0;
- echo_hdr.flags = 0;
- echo_hdr.pad = 0;
- nul = *AI;
- nul.GetInAddr( *((struct in_addr*)&echo_hdr.shostid) );
- sep = getservbyname("echo", "udp");
- echo_port = sep ? ntohs((u_short) sep->s_port) : 7;
- }
+ sep = getservbyname("echo", "udp");
+ echo_port = sep ? ntohs((unsigned short) sep->s_port) : 7;
first_ping = Config.peers;
- nul.FreeAddrInfo(AI);
}
int
{
const char *url = entry->url();
MemObject *mem = entry->mem_obj;
- peer *p = NULL;
+ CachePeer *p = NULL;
int i;
int reqnum = 0;
int flags;
debugs(15, 5, "neighborsUdpPing: Peer " << p->host);
if (!peerWouldBePinged(p, request))
- continue; /* next peer */
+ continue; /* next CachePeer */
- peers_pinged++;
+ ++peers_pinged;
debugs(15, 4, "neighborsUdpPing: pinging peer " << p->host << " for '" << url << "'");
}
debugs(15, 3, "neighborsUdpPing: sending HTCP query");
- if (htcpQuery(entry, request, p) <= 0) continue; // unable to send.
+ if (htcpQuery(entry, request, p) <= 0)
+ continue; // unable to send.
} else
#endif
{
- if (Config.Port.icp <= 0 || theOutIcpConnection <= 0) {
+ if (Config.Port.icp <= 0 || !Comm::IsConnOpen(icpOutgoingConn)) {
debugs(15, DBG_CRITICAL, "ICP is disabled! Cannot send ICP request to peer.");
continue;
} else {
if (p->type == PEER_MULTICAST)
- mcastSetTtl(theOutIcpConnection, p->mcast.ttl);
+ mcastSetTtl(icpOutgoingConn->fd, p->mcast.ttl);
if (p->icp.port == echo_port) {
debugs(15, 4, "neighborsUdpPing: Looks like a dumb cache, send DECHO ping");
- echo_hdr.reqnum = reqnum;
query = _icp_common_t::createMessage(ICP_DECHO, 0, url, reqnum, 0);
- icpUdpSend(theOutIcpConnection,p->in_addr,query,LOG_ICP_QUERY,0);
+ icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0);
} else {
flags = 0;
query = _icp_common_t::createMessage(ICP_QUERY, flags, url, reqnum, 0);
- icpUdpSend(theOutIcpConnection, p->in_addr, query, LOG_ICP_QUERY, 0);
+ icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0);
}
}
}
- queries_sent++;
+ ++queries_sent;
- p->stats.pings_sent++;
+ ++ p->stats.pings_sent;
if (p->type == PEER_MULTICAST) {
mcast_exprep += p->mcast.n_replies_expected;
/* its alive, expect a reply from it */
if (neighborType(p, request) == PEER_PARENT) {
- parent_exprep++;
+ ++parent_exprep;
parent_timeout += p->stats.rtt;
} else {
- sibling_exprep++;
+ ++sibling_exprep;
sibling_timeout += p->stats.rtt;
}
} else {
/* log it once at the threshold */
if (p->stats.logged_state == PEER_ALIVE) {
- debugs(15, 1, "Detected DEAD " << neighborTypeStr(p) << ": " << p->name);
+ debugs(15, DBG_IMPORTANT, "Detected DEAD " << neighborTypeStr(p) << ": " << p->name);
p->stats.logged_state = PEER_DEAD;
}
}
p->stats.last_query = squid_curtime;
/*
- * keep probe_start == 0 for a multicast peer,
- * so neighborUp() never says this peer is dead.
+ * keep probe_start == 0 for a multicast CachePeer,
+ * so neighborUp() never says this CachePeer is dead.
*/
if ((p->type != PEER_MULTICAST) && (p->stats.probe_start == 0))
return peers_pinged;
}
-/* lookup the digest of a given peer */
+/* lookup the digest of a given CachePeer */
lookup_t
-peerDigestLookup(peer * p, HttpRequest * request)
+peerDigestLookup(CachePeer * p, HttpRequest * request)
{
#if USE_CACHE_DIGESTS
const cache_key *key = request ? storeKeyPublicByRequest(request) : NULL;
return LOOKUP_NONE;
}
-/* select best peer based on cache digests */
-peer *
+/* select best CachePeer based on cache digests */
+CachePeer *
neighborsDigestSelect(HttpRequest * request)
{
- peer *best_p = NULL;
+ CachePeer *best_p = NULL;
#if USE_CACHE_DIGESTS
- const cache_key *key;
int best_rtt = 0;
int choice_count = 0;
int ichoice_count = 0;
- peer *p;
+ CachePeer *p;
int p_rtt;
int i;
if (!request->flags.hierarchical)
return NULL;
- key = storeKeyPublicByRequest(request);
+ storeKeyPublicByRequest(request);
for (i = 0, p = first_ping; i++ < Config.npeers; p = p->next) {
lookup_t lookup;
if (lookup == LOOKUP_NONE)
continue;
- choice_count++;
+ ++choice_count;
if (lookup == LOOKUP_MISS)
continue;
debugs(15, 5, "neighborsDigestSelect: peer " << p->host << " rtt: " << p_rtt);
- /* is this peer better than others in terms of rtt ? */
+ /* is this CachePeer better than others in terms of rtt ? */
if (!best_p || (p_rtt && p_rtt < best_rtt)) {
best_p = p;
best_rtt = p_rtt;
if (p_rtt) /* informative choice (aka educated guess) */
- ichoice_count++;
+ ++ichoice_count;
debugs(15, 4, "neighborsDigestSelect: peer " << p->host << " leads with rtt " << best_rtt);
}
}
void
-peerNoteDigestLookup(HttpRequest * request, peer * p, lookup_t lookup)
+peerNoteDigestLookup(HttpRequest * request, CachePeer * p, lookup_t lookup)
{
#if USE_CACHE_DIGESTS
if (p)
}
static void
-neighborAlive(peer * p, const MemObject * mem, const icp_common_t * header)
+neighborAlive(CachePeer * p, const MemObject * mem, const icp_common_t * header)
{
peerAlive(p);
- p->stats.pings_acked++;
+ ++ p->stats.pings_acked;
if ((icp_opcode) header->opcode <= ICP_END)
- p->icp.counts[header->opcode]++;
+ ++ p->icp.counts[header->opcode];
p->icp.version = (int) header->version;
}
static void
-neighborUpdateRtt(peer * p, MemObject * mem)
+neighborUpdateRtt(CachePeer * p, MemObject * mem)
{
int rtt, rtt_av_factor;
#if USE_HTCP
static void
-neighborAliveHtcp(peer * p, const MemObject * mem, const htcpReplyData * htcp)
+neighborAliveHtcp(CachePeer * p, const MemObject * mem, const htcpReplyData * htcp)
{
peerAlive(p);
- p->stats.pings_acked++;
- p->htcp.counts[htcp->hit ? 1 : 0]++;
+ ++ p->stats.pings_acked;
+ ++ p->htcp.counts[htcp->hit ? 1 : 0];
p->htcp.version = htcp->version;
}
#endif
static void
-neighborCountIgnored(peer * p)
+neighborCountIgnored(CachePeer * p)
{
if (p == NULL)
return;
- p->stats.ignored_replies++;
+ ++ p->stats.ignored_replies;
- NLateReplies++;
+ ++NLateReplies;
}
-static peer *non_peers = NULL;
+static CachePeer *non_peers = NULL;
static void
neighborIgnoreNonPeer(const Ip::Address &from, icp_opcode opcode)
{
- peer *np;
+ CachePeer *np;
for (np = non_peers; np; np = np->next) {
if (np->in_addr != from)
}
if (np == NULL) {
- np = (peer *)xcalloc(1, sizeof(peer));
+ np = (CachePeer *)xcalloc(1, sizeof(CachePeer));
np->in_addr = from;
np->icp.port = from.GetPort();
np->type = PEER_NONE;
non_peers = np;
}
- np->icp.counts[opcode]++;
+ ++ np->icp.counts[opcode];
if (isPowTen(++np->stats.ignored_replies))
- debugs(15, 1, "WARNING: Ignored " << np->stats.ignored_replies << " replies from non-peer " << np->host);
+ debugs(15, DBG_IMPORTANT, "WARNING: Ignored " << np->stats.ignored_replies << " replies from non-peer " << np->host);
}
/* ignoreMulticastReply
*
* * We want to ignore replies from multicast peers if the
- * * cache_host_domain rules would normally prevent the peer
+ * * cache_host_domain rules would normally prevent the CachePeer
* * from being used
*/
static int
-ignoreMulticastReply(peer * p, MemObject * mem)
+ignoreMulticastReply(CachePeer * p, MemObject * mem)
{
if (p == NULL)
return 0;
void
neighborsUdpAck(const cache_key * key, icp_common_t * header, const Ip::Address &from)
{
- peer *p = NULL;
+ CachePeer *p = NULL;
StoreEntry *entry;
MemObject *mem = NULL;
peer_t ntype = PEER_NONE;
}
if (entry->lock_count == 0) {
- debugs(12, 1, "neighborsUdpAck: '" << storeKeyText(key) << "' has no locks");
+ // TODO: many entries are unlocked; why is this reported at level 1?
+ debugs(12, DBG_IMPORTANT, "neighborsUdpAck: '" << storeKeyText(key) << "' has no locks");
neighborCountIgnored(p);
return;
}
if (p == NULL) {
neighborIgnoreNonPeer(from, opcode);
} else {
- mem->ping_reply_callback(p, ntype, PROTO_ICP, header, mem->ircb_data);
+ mem->ping_reply_callback(p, ntype, AnyP::PROTO_ICP, header, mem->ircb_data);
}
} else if (opcode == ICP_HIT) {
if (p == NULL) {
neighborIgnoreNonPeer(from, opcode);
} else {
header->opcode = ICP_HIT;
- mem->ping_reply_callback(p, ntype, PROTO_ICP, header, mem->ircb_data);
+ mem->ping_reply_callback(p, ntype, AnyP::PROTO_ICP, header, mem->ircb_data);
}
} else if (opcode == ICP_DECHO) {
if (p == NULL) {
debug_trap("neighborsUdpAck: Found non-ICP cache as SIBLING\n");
debug_trap("neighborsUdpAck: non-ICP neighbors must be a PARENT\n");
} else {
- mem->ping_reply_callback(p, ntype, PROTO_ICP, header, mem->ircb_data);
+ mem->ping_reply_callback(p, ntype, AnyP::PROTO_ICP, header, mem->ircb_data);
}
} else if (opcode == ICP_SECHO) {
if (p) {
- debugs(15, 1, "Ignoring SECHO from neighbor " << p->host);
+ debugs(15, DBG_IMPORTANT, "Ignoring SECHO from neighbor " << p->host);
neighborCountIgnored(p);
} else {
- debugs(15, 1, "Unsolicited SECHO from " << from);
+ debugs(15, DBG_IMPORTANT, "Unsolicited SECHO from " << from);
}
} else if (opcode == ICP_DENIED) {
if (p == NULL) {
neighborIgnoreNonPeer(from, opcode);
} else if (p->stats.pings_acked > 100) {
if (100 * p->icp.counts[ICP_DENIED] / p->stats.pings_acked > 95) {
- debugs(15, 0, "95%% of replies from '" << p->host << "' are UDP_DENIED");
- debugs(15, 0, "Disabling '" << p->host << "', please check your configuration.");
+ debugs(15, DBG_CRITICAL, "95%% of replies from '" << p->host << "' are UDP_DENIED");
+ debugs(15, DBG_CRITICAL, "Disabling '" << p->host << "', please check your configuration.");
neighborRemove(p);
p = NULL;
} else {
}
}
} else if (opcode == ICP_MISS_NOFETCH) {
- mem->ping_reply_callback(p, ntype, PROTO_ICP, header, mem->ircb_data);
+ mem->ping_reply_callback(p, ntype, AnyP::PROTO_ICP, header, mem->ircb_data);
} else {
- debugs(15, 0, "neighborsUdpAck: Unexpected ICP reply: " << opcode_d);
+ debugs(15, DBG_CRITICAL, "neighborsUdpAck: Unexpected ICP reply: " << opcode_d);
}
}
-peer *
+CachePeer *
peerFindByName(const char *name)
{
- peer *p = NULL;
+ CachePeer *p = NULL;
for (p = Config.peers; p; p = p->next) {
if (!strcasecmp(name, p->name))
return p;
}
-peer *
+CachePeer *
peerFindByNameAndPort(const char *name, unsigned short port)
{
- peer *p = NULL;
+ CachePeer *p = NULL;
for (p = Config.peers; p; p = p->next) {
if (strcasecmp(name, p->name))
}
int
-neighborUp(const peer * p)
+neighborUp(const CachePeer * p)
{
if (!p->tcp_up) {
- if (!peerProbeConnect((peer *) p)) {
+ if (!peerProbeConnect((CachePeer *) p)) {
debugs(15, 8, "neighborUp: DOWN (probed): " << p->host << " (" << p->in_addr << ")");
return 0;
}
}
/*
- * The peer can not be UP if we don't have any IP addresses
+ * The CachePeer can not be UP if we don't have any IP addresses
* for it.
*/
if (0 == p->n_addresses) {
void
peerDestroy(void *data)
{
- peer *p = (peer *)data;
-
- struct _domain_ping *l = NULL;
-
- struct _domain_ping *nl = NULL;
+ CachePeer *p = (CachePeer *)data;
if (p == NULL)
return;
- for (l = p->peer_domain; l; l = nl) {
+ domain_ping *nl = NULL;
+
+ for (domain_ping *l = p->peer_domain; l; l = nl) {
nl = l->next;
safe_free(l->domain);
- safe_free(l);
+ xfree(l);
}
safe_free(p->host);
}
void
-peerNoteDigestGone(peer * p)
+peerNoteDigestGone(CachePeer * p)
{
#if USE_CACHE_DIGESTS
cbdataReferenceDone(p->digest);
static void
peerDNSConfigure(const ipcache_addrs *ia, const DnsLookupDetails &, void *data)
{
- peer *p = (peer *)data;
+ CachePeer *p = (CachePeer *)data;
int j;
if (p->n_addresses == 0) {
- debugs(15, 1, "Configuring " << neighborTypeStr(p) << " " << p->host << "/" << p->http_port << "/" << p->icp.port);
+ debugs(15, DBG_IMPORTANT, "Configuring " << neighborTypeStr(p) << " " << p->host << "/" << p->http_port << "/" << p->icp.port);
if (p->type == PEER_MULTICAST)
- debugs(15, 1, " Multicast TTL = " << p->mcast.ttl);
+ debugs(15, DBG_IMPORTANT, " Multicast TTL = " << p->mcast.ttl);
}
p->n_addresses = 0;
if (ia == NULL) {
- debugs(0, 0, "WARNING: DNS lookup for '" << p->host << "' failed!");
+ debugs(0, DBG_CRITICAL, "WARNING: DNS lookup for '" << p->host << "' failed!");
return;
}
if ((int) ia->count < 1) {
- debugs(0, 0, "WARNING: No IP address found for '" << p->host << "'!");
+ 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++) {
+ 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++;
+ ++ p->n_addresses;
}
p->in_addr.SetEmpty();
static void
peerRefreshDNS(void *data)
{
- peer *p = NULL;
+ CachePeer *p = NULL;
if (eventFind(peerRefreshDNS, NULL))
eventDelete(peerRefreshDNS, NULL);
}
static void
-peerConnectFailedSilent(peer * p)
+peerConnectFailedSilent(CachePeer * p)
{
p->stats.last_connect_failure = squid_curtime;
return;
}
- p->tcp_up--;
+ -- p->tcp_up;
if (!p->tcp_up) {
- debugs(15, 1, "Detected DEAD " << neighborTypeStr(p) << ": " << p->name);
+ debugs(15, DBG_IMPORTANT, "Detected DEAD " << neighborTypeStr(p) << ": " << p->name);
p->stats.logged_state = PEER_DEAD;
}
}
void
-peerConnectFailed(peer *p)
+peerConnectFailed(CachePeer *p)
{
- debugs(15, 1, "TCP connection to " << p->host << "/" << p->http_port << " failed");
+ debugs(15, DBG_IMPORTANT, "TCP connection to " << p->host << "/" << p->http_port << " failed");
peerConnectFailedSilent(p);
}
void
-peerConnectSucceded(peer * p)
+peerConnectSucceded(CachePeer * p)
{
if (!p->tcp_up) {
debugs(15, 2, "TCP connection to " << p->host << "/" << p->http_port << " succeded");
* peerProbeConnect will be called on dead peers by neighborUp
*/
static bool
-peerProbeConnect(peer * p)
+peerProbeConnect(CachePeer * p)
{
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 (squid_curtime - p->stats.last_connect_probe == 0)
return ret;/* don't probe to often */
- /* for each IP address of this peer. find one that we can connect to and probe it. */
- for (int i = 0; i < p->n_addresses; i++) {
+ /* 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;
conn->remote = p->addresses[i];
conn->remote.SetPort(p->http_port);
getOutgoingAddress(NULL, conn);
- p->testing_now++;
+ ++ p->testing_now;
AsyncCall::Pointer call = commCbCall(15,3, "peerProbeConnectDone", CommConnectCbPtrFun(peerProbeConnectDone, p));
Comm::ConnOpener *cs = new Comm::ConnOpener(conn, call, ctimeout);
cs->setHost(p->host);
- AsyncJob::AsyncStart(cs);
+ AsyncJob::Start(cs);
}
p->stats.last_connect_probe = squid_curtime;
}
static void
-peerProbeConnectDone(Comm::ConnectionPointer &conn, comm_err_t status, int xerrno, void *data)
+peerProbeConnectDone(const Comm::ConnectionPointer &conn, comm_err_t status, int xerrno, void *data)
{
- peer *p = (peer*)data;
+ CachePeer *p = (CachePeer*)data;
if (status == COMM_OK) {
peerConnectSucceded(p);
peerConnectFailedSilent(p);
}
+ -- p->testing_now;
conn->close();
- p->testing_now--;
- return;
+ // TODO: log this traffic.
}
static void
-peerCountMcastPeersSchedule(peer * p, time_t when)
+peerCountMcastPeersSchedule(CachePeer * p, time_t when)
{
if (p->mcast.flags.count_event_pending)
return;
static void
peerCountMcastPeersStart(void *data)
{
- peer *p = (peer *)data;
+ CachePeer *p = (CachePeer *)data;
ps_state *psstate;
StoreEntry *fake;
MemObject *mem;
mem->start_ping = current_time;
mem->ping_reply_callback = peerCountHandleIcpReply;
mem->ircb_data = psstate;
- mcastSetTtl(theOutIcpConnection, p->mcast.ttl);
+ 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(theOutIcpConnection,
- p->in_addr,
- query,
- LOG_ICP_QUERY,
- 0);
+ icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0);
fake->ping_status = PING_WAITING;
eventAdd("peerCountMcastPeersDone",
peerCountMcastPeersDone,
StoreEntry *fake = psstate->entry;
if (cbdataReferenceValid(psstate->callback_data)) {
- peer *p = (peer *)psstate->callback_data;
+ CachePeer *p = (CachePeer *)psstate->callback_data;
p->mcast.flags.counting = 0;
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, 1, "Group " << p->host << ": " << psstate->ping.n_recv <<
+ debugs(15, DBG_IMPORTANT, "Group " << p->host << ": " << psstate->ping.n_recv <<
" replies, "<< std::setw(4)<< std::setprecision(2) <<
p->mcast.avg_n_members <<" average, RTT " << p->stats.rtt);
p->mcast.n_replies_expected = (int) p->mcast.avg_n_members;
cbdataReferenceDone(psstate->callback_data);
- EBIT_SET(fake->flags, ENTRY_ABORTED);
+ fake->abort(); // sets ENTRY_ABORTED and initiates releated cleanup
HTTPMSGUNLOCK(fake->mem_obj->request);
- fake->releaseRequest();
fake->unlock();
HTTPMSGUNLOCK(psstate->request);
cbdataFree(psstate);
}
static void
-peerCountHandleIcpReply(peer * p, peer_t type, protocol_t proto, void *hdrnotused, void *data)
+peerCountHandleIcpReply(CachePeer * p, peer_t type, AnyP::ProtocolType proto, void *hdrnotused, void *data)
{
int rtt_av_factor;
StoreEntry *fake = psstate->entry;
MemObject *mem = fake->mem_obj;
int rtt = tvSubMsec(mem->start_ping, current_time);
- assert(proto == PROTO_ICP);
+ assert(proto == AnyP::PROTO_ICP);
assert(fake);
assert(mem);
- psstate->ping.n_recv++;
+ ++ psstate->ping.n_recv;
rtt_av_factor = RTT_AV_FACTOR;
if (p->options.weighted_roundrobin)
}
void
-dump_peer_options(StoreEntry * sentry, peer * p)
+dump_peer_options(StoreEntry * sentry, CachePeer * p)
{
if (p->options.proxy_only)
storeAppendPrintf(sentry, " proxy-only");
if (p->options.carp)
storeAppendPrintf(sentry, " carp");
+#if USE_AUTH
if (p->options.userhash)
storeAppendPrintf(sentry, " userhash");
+#endif
- if (p->options.userhash)
+ if (p->options.sourcehash)
storeAppendPrintf(sentry, " sourcehash");
if (p->options.weighted_roundrobin)
storeAppendPrintf(sentry, " closest-only");
#if USE_HTCP
- if (p->options.htcp)
+ if (p->options.htcp) {
storeAppendPrintf(sentry, " htcp");
- if (p->options.htcp_oldsquid)
- storeAppendPrintf(sentry, " htcp-oldsquid");
- if (p->options.htcp_no_clr)
- storeAppendPrintf(sentry, " htcp-no-clr");
- if (p->options.htcp_no_purge_clr)
- storeAppendPrintf(sentry, " htcp-no-purge-clr");
- if (p->options.htcp_only_clr)
- storeAppendPrintf(sentry, " htcp-only-clr");
+ 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?",":"="));
+ }
+ }
#endif
if (p->options.no_netdb_exchange)
storeAppendPrintf(sentry, " no-netdb-exchange");
-#if DELAY_POOLS
-
+#if USE_DELAY_POOLS
if (p->options.no_delay)
storeAppendPrintf(sentry, " no-delay");
-
#endif
if (p->login)
}
static void
-dump_peers(StoreEntry * sentry, peer * peers)
+dump_peers(StoreEntry * sentry, CachePeer * peers)
{
- peer *e = NULL;
+ CachePeer *e = NULL;
char ntoabuf[MAX_IPSTRLEN];
- struct _domain_ping *d = NULL;
+ domain_ping *d = NULL;
icp_opcode op;
int i;
storeAppendPrintf(sentry, "Flags :");
dump_peer_options(sentry, e);
- for (i = 0; i < e->n_addresses; i++) {
+ for (i = 0; i < e->n_addresses; ++i) {
storeAppendPrintf(sentry, "Address[%d] : %s\n", i,
e->addresses[i].NtoA(ntoabuf,MAX_IPSTRLEN) );
}
if (e->stats.last_connect_failure) {
storeAppendPrintf(sentry, "Last failed connect() at: %s\n",
- mkhttpdlogtime(&(e->stats.last_connect_failure)));
+ Time::FormatHttpd(e->stats.last_connect_failure));
}
if (e->peer_domain != NULL) {
{
StoreEntry *e = Store::Root().get(key);
MemObject *mem = NULL;
- peer *p;
+ CachePeer *p;
peer_t ntype = PEER_NONE;
debugs(15, 6, "neighborsHtcpReply: " <<
(htcp->hit ? "HIT" : "MISS") << " " <<
}
if (e->lock_count == 0) {
- debugs(12, 1, "neighborsUdpAck: '" << storeKeyText(key) << "' has no locks");
+ // TODO: many entries are unlocked; why is this reported at level 1?
+ debugs(12, DBG_IMPORTANT, "neighborsUdpAck: '" << storeKeyText(key) << "' has no locks");
neighborCountIgnored(p);
return;
}
}
debugs(15, 3, "neighborsHtcpReply: e = " << e);
- mem->ping_reply_callback(p, ntype, PROTO_HTCP, htcp, mem->ircb_data);
+ mem->ping_reply_callback(p, ntype, AnyP::PROTO_HTCP, htcp, mem->ircb_data);
}
/*
void
neighborsHtcpClear(StoreEntry * e, const char *uri, HttpRequest * req, const HttpRequestMethod &method, htcp_clr_reason reason)
{
- peer *p;
+ CachePeer *p;
char buf[128];
for (p = Config.peers; p; p = p->next) {