From: Alex Rousskov Date: Tue, 2 Jan 2018 16:16:52 +0000 (-0700) Subject: Moved peer*(ps_state) functions into ps_state renamed PeerSelector (#113) X-Git-Tag: M-staged-PR71~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cb83513675bc334c3a5807f0bd5a9ae92ba934de;p=thirdparty%2Fsquid.git Moved peer*(ps_state) functions into ps_state renamed PeerSelector (#113) No functionality changes intended (other than debug message variations). Also polished related documentation and debug messages. Also converted "struct _icp_common_t" into an icp_common_t class, to make its forward declarations simple. As a side effect, removed __cplusplus ifdefs, addressing an old TODO. --- diff --git a/src/ICP.h b/src/ICP.h index 2a4bd52518..74ce944433 100644 --- a/src/ICP.h +++ b/src/ICP.h @@ -24,13 +24,12 @@ class HttpRequest; /** - \ingroup ServerProtocolICPAPI - * - * This struct is the wire-level header. - * DO NOT add more move fields on pain of breakage. + * Wire-level ICP header. + * DO NOT add or move fields. * DO NOT add virtual methods. */ -struct _icp_common_t { +class icp_common_t { +public: /** opcode */ unsigned char opcode; /** version number */ @@ -44,21 +43,15 @@ struct _icp_common_t { /** sender host id */ uint32_t shostid; -/// \todo I don't believe this header is included in non-c++ code anywhere -/// the struct should become a public POD class and kill these ifdef. -#ifdef __cplusplus - - _icp_common_t(); - _icp_common_t(char *buf, unsigned int len); + icp_common_t(); + icp_common_t(char *buf, unsigned int len); void handleReply(char *buf, Ip::Address &from); - static _icp_common_t *createMessage(icp_opcode opcode, int flags, const char *url, int reqnum, int pad); icp_opcode getOpCode() const; -#endif -}; -typedef struct _icp_common_t icp_common_t; -#ifdef __cplusplus + /// \returns newly allocated buffer with an ICP message, including header + static icp_common_t *CreateMessage(icp_opcode opcode, int flags, const char *url, int reqnum, int pad); +}; /** \ingroup ServerProtocolICPAPI @@ -78,8 +71,6 @@ public: char *url; }; -#endif - /// \ingroup ServerProtocolICPAPI struct icpUdpData { diff --git a/src/PeerSelectState.h b/src/PeerSelectState.h index 24c544a505..c682b094c2 100644 --- a/src/PeerSelectState.h +++ b/src/PeerSelectState.h @@ -19,9 +19,11 @@ #include "mem/forward.h" #include "PingData.h" +class ErrorState; +class HtcpReplyData; class HttpRequest; +class icp_common_t; class StoreEntry; -class ErrorState; void peerSelectInit(void); @@ -51,13 +53,15 @@ public: class FwdServer; -class ps_state: public Dns::IpReceiver +/// Finds peer (including origin server) IPs for forwarding a single request. +/// Gives PeerSelectionInitiator each found destination, in the right order. +class PeerSelector: public Dns::IpReceiver { - CBDATA_CHILD(ps_state); + CBDATA_CHILD(PeerSelector); public: - explicit ps_state(PeerSelectionInitiator *initiator); - virtual ~ps_state() override; + explicit PeerSelector(PeerSelectionInitiator*); + virtual ~PeerSelector() override; /* Dns::IpReceiver API */ virtual void noteIp(const Ip::Address &ip) override; @@ -77,17 +81,56 @@ public: /// processes a newly discovered/finalized path void handlePath(Comm::ConnectionPointer &path, FwdServer &fs); + /// a single selection loop iteration: attempts to add more destinations + void selectMore(); + HttpRequest *request; AccessLogEntry::Pointer al; ///< info for the future access.log entry StoreEntry *entry; + + void *peerCountMcastPeerXXX = nullptr; ///< a hack to help peerCountMcastPeersStart() + + ping_data ping; + +protected: + bool selectionAborted(); + + void handlePingTimeout(); + void handleIcpReply(CachePeer*, const peer_t, icp_common_t *header); + void handleIcpParentMiss(CachePeer*, icp_common_t*); +#if USE_HTCP + void handleHtcpParentMiss(CachePeer*, HtcpReplyData*); + void handleHtcpReply(CachePeer*, const peer_t, HtcpReplyData*); +#endif + + int checkNetdbDirect(); + void checkAlwaysDirectDone(const allow_t answer); + void checkNeverDirectDone(const allow_t answer); + + void selectSomeNeighbor(); + void selectSomeNeighborReplies(); + void selectSomeDirect(); + void selectSomeParent(); + void selectAllParents(); + void selectPinned(); + + void addSelection(CachePeer*, const hier_code); + + void resolveSelected(); + + static IRCB HandlePingReply; + static ACLCB CheckAlwaysDirectDone; + static ACLCB CheckNeverDirectDone; + static EVH HandlePingTimeout; + +private: allow_t always_direct; allow_t never_direct; int direct; // TODO: fold always_direct/never_direct/prefer_direct into this now that ACL can do a multi-state result. size_t foundPaths = 0; ///< number of unique destinations identified so far - void *peerCountMcastPeerXXX = nullptr; ///< a hack to help peerCountMcastPeersStart() ErrorState *lastError; - FwdServer *servers; ///< temporary linked list of peers we will pass back. + FwdServer *servers; ///< a linked list of (unresolved) selected peers /* * Why are these Ip::Address instead of CachePeer *? Because a @@ -106,15 +149,12 @@ public: */ CachePeer *hit; peer_t hit_type; - ping_data ping; ACLChecklist *acl_checklist; - const InstanceId id; ///< unique identification in worker log - -private: - typedef CbcPointer Initiator; Initiator initiator_; ///< recipient of the destinations we select; use interestedInitiator() to access + + const InstanceId id; ///< unique identification in worker log }; #endif /* SQUID_PEERSELECTSTATE_H */ diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 4cb551eb58..5acf708899 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -73,15 +73,15 @@ Comm::ConnectionPointer icpIncomingConn = NULL; Comm::ConnectionPointer icpOutgoingConn = NULL; /* icp_common_t */ -_icp_common_t::_icp_common_t() : +icp_common_t::icp_common_t() : opcode(ICP_INVALID), version(0), length(0), reqnum(0), flags(0), pad(0), shostid(0) {} -_icp_common_t::_icp_common_t(char *buf, unsigned int len) : +icp_common_t::icp_common_t(char *buf, unsigned int len) : opcode(ICP_INVALID), version(0), reqnum(0), flags(0), pad(0), shostid(0) { - if (len < sizeof(_icp_common_t)) { + if (len < sizeof(icp_common_t)) { /* mark as invalid */ length = len + 1; return; @@ -98,7 +98,7 @@ _icp_common_t::_icp_common_t(char *buf, unsigned int len) : } icp_opcode -_icp_common_t::getOpCode() const +icp_common_t::getOpCode() const { if (opcode > static_cast(icp_opcode::ICP_END)) return ICP_INVALID; @@ -228,8 +228,8 @@ icpUdpSendQueue(int fd, void *) } } -_icp_common_t * -_icp_common_t::createMessage( +icp_common_t * +icp_common_t::CreateMessage( icp_opcode opcode, int flags, const char *url, @@ -387,7 +387,7 @@ icpLogFromICPCode(icp_opcode opcode) void icpCreateAndSend(icp_opcode opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from) { - icp_common_t *reply = _icp_common_t::createMessage(opcode, flags, url, reqnum, pad); + icp_common_t *reply = icp_common_t::CreateMessage(opcode, flags, url, reqnum, pad); icpUdpSend(fd, from, reply, icpLogFromICPCode(opcode), 0); } @@ -493,7 +493,7 @@ doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header) } void -_icp_common_t::handleReply(char *buf, Ip::Address &from) +icp_common_t::handleReply(char *buf, Ip::Address &from) { if (neighbors_do_private_keys && reqnum == 0) { debugs(12, DBG_CRITICAL, "icpHandleIcpV2: Neighbor " << from << " returned reqnum = 0"); diff --git a/src/neighbors.cc b/src/neighbors.cc index db5831d551..dfd16e0bbb 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -643,7 +643,7 @@ neighborsUdpPing(HttpRequest * request, 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); + query = icp_common_t::CreateMessage(ICP_DECHO, 0, url, reqnum, 0); icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0); } else { flags = 0; @@ -652,7 +652,7 @@ neighborsUdpPing(HttpRequest * request, if (p->icp.version == ICP_VERSION_2) flags |= ICP_FLAG_SRC_RTT; - query = _icp_common_t::createMessage(ICP_QUERY, flags, url, reqnum, 0); + query = icp_common_t::CreateMessage(ICP_QUERY, flags, url, reqnum, 0); icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0.0); } @@ -1375,7 +1375,6 @@ peerCountMcastPeersStart(void *data) // 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! CachePeer *p = (CachePeer *)data; - ps_state *psstate; MemObject *mem; icp_common_t *query; int reqnum; @@ -1390,7 +1389,7 @@ peerCountMcastPeersStart(void *data) HttpRequest *req = HttpRequest::FromUrl(url, mx); assert(req != nullptr); StoreEntry *fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET); - psstate = new ps_state(nullptr); + const auto psstate = new PeerSelector(nullptr); psstate->request = req; HTTPMSGLOCK(psstate->request); psstate->entry = fake; @@ -1404,7 +1403,7 @@ peerCountMcastPeersStart(void *data) 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); + 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; eventAdd("peerCountMcastPeersDone", @@ -1418,7 +1417,7 @@ peerCountMcastPeersStart(void *data) static void peerCountMcastPeersDone(void *data) { - ps_state *psstate = (ps_state *)data; + const auto psstate = static_cast(data); StoreEntry *fake = psstate->entry; if (cbdataReferenceValid(psstate->peerCountMcastPeerXXX)) { @@ -1442,7 +1441,7 @@ peerCountMcastPeersDone(void *data) static void peerCountHandleIcpReply(CachePeer * p, peer_t, AnyP::ProtocolType proto, void *, void *data) { - ps_state *psstate = (ps_state *)data; + const auto psstate = static_cast(data); StoreEntry *fake = psstate->entry; assert(fake); MemObject *mem = fake->mem_obj; diff --git a/src/peer_select.cc b/src/peer_select.cc index 99d453794a..bbe2a28cce 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -76,32 +76,15 @@ static const char *DirectStr[] = { class PeerSelectionDumper { public: - PeerSelectionDumper(const ps_state * const aPs, const CachePeer * const aPeer, const hier_code aCode): - ps(aPs), peer(aPeer), code(aCode) {} + PeerSelectionDumper(const PeerSelector * const aSelector, const CachePeer * const aPeer, const hier_code aCode): + selector(aSelector), peer(aPeer), code(aCode) {} - const ps_state * const ps; ///< selection parameters + const PeerSelector * const selector; ///< selection parameters const CachePeer * const peer; ///< successful selection info const hier_code code; ///< selection algorithm }; -static void peerSelectFoo(ps_state *); -static void peerPingTimeout(void *data); -static IRCB peerHandlePingReply; -static void peerIcpParentMiss(CachePeer *, icp_common_t *, ps_state *); -#if USE_HTCP -static void peerHtcpParentMiss(CachePeer *, HtcpReplyData *, ps_state *); -static void peerHandleHtcpReply(CachePeer *, peer_t, HtcpReplyData *, void *); -#endif -static int peerCheckNetdbDirect(ps_state * psstate); -static void peerGetSomeNeighbor(ps_state *); -static void peerGetSomeNeighborReplies(ps_state *); -static void peerGetSomeDirect(ps_state *); -static void peerGetSomeParent(ps_state *); -static void peerGetAllParents(ps_state *); -static void peerAddFwdServer(ps_state*, CachePeer*, const hier_code); -static void peerSelectPinned(ps_state * ps); - -CBDATA_CLASS_INIT(ps_state); +CBDATA_CLASS_INIT(PeerSelector); /// prints PeerSelectionDumper (for debugging) static std::ostream & @@ -111,13 +94,13 @@ operator <<(std::ostream &os, const PeerSelectionDumper &fsd) if (fsd.peer) os << '/' << fsd.peer->host; - else if (fsd.ps) // useful for DIRECT and gone PINNED destinations - os << '#' << fsd.ps->request->url.host(); + else if (fsd.selector) // useful for DIRECT and gone PINNED destinations + os << '#' << fsd.selector->request->url.host(); return os; } -ps_state::~ps_state() +PeerSelector::~PeerSelector() { while (servers) { FwdServer *next = servers->next; @@ -129,13 +112,13 @@ ps_state::~ps_state() debugs(44, 3, entry->url()); if (entry->ping_status == PING_WAITING) - eventDelete(peerPingTimeout, this); + eventDelete(HandlePingTimeout, this); entry->ping_status = PING_DONE; } if (acl_checklist) { - debugs(44, DBG_IMPORTANT, "calling aclChecklistFree() from ps_state destructor"); + debugs(44, DBG_IMPORTANT, "BUG: peer selector gone while waiting for a slow ACL"); delete acl_checklist; } @@ -157,7 +140,7 @@ peerSelectIcpPing(HttpRequest * request, int direct, StoreEntry * entry) assert(entry); assert(entry->ping_status == PING_NONE); assert(direct != DIRECT_YES); - debugs(44, 3, "peerSelectIcpPing: " << entry->url()); + debugs(44, 3, entry->url()); if (!request->flags.hierarchical && direct != DIRECT_NO) return 0; @@ -168,7 +151,7 @@ peerSelectIcpPing(HttpRequest * request, int direct, StoreEntry * entry) n = neighborsCount(request); - debugs(44, 3, "peerSelectIcpPing: counted " << n << " neighbors"); + debugs(44, 3, "counted " << n << " neighbors"); return n; } @@ -184,13 +167,13 @@ peerSelect(PeerSelectionInitiator *initiator, else debugs(44, 3, request->method); - const auto psstate = new ps_state(initiator); + const auto selector = new PeerSelector(initiator); - psstate->request = request; - HTTPMSGLOCK(psstate->request); - psstate->al = al; + selector->request = request; + HTTPMSGLOCK(selector->request); + selector->al = al; - psstate->entry = entry; + selector->entry = entry; #if USE_CACHE_DIGESTS @@ -198,10 +181,10 @@ peerSelect(PeerSelectionInitiator *initiator, #endif - if (psstate->entry) - psstate->entry->lock("peerSelect"); + if (selector->entry) + selector->entry->lock("peerSelect"); - peerSelectFoo(psstate); + selector->selectMore(); } void @@ -212,18 +195,17 @@ PeerSelectionInitiator::startSelectingDestinations(HttpRequest *request, const A // and wait for noteDestination() and/or noteDestinationsEnd() calls } -static void -peerCheckNeverDirectDone(allow_t answer, void *data) +void +PeerSelector::checkNeverDirectDone(const allow_t answer) { - ps_state *psstate = (ps_state *) data; - psstate->acl_checklist = NULL; - debugs(44, 3, "peerCheckNeverDirectDone: " << answer); - psstate->never_direct = answer; + acl_checklist = nullptr; + debugs(44, 3, answer); + never_direct = answer; switch (answer) { case ACCESS_ALLOWED: /** if never_direct says YES, do that. */ - psstate->direct = DIRECT_NO; - debugs(44, 3, HERE << "direct = " << DirectStr[psstate->direct] << " (never_direct allow)"); + direct = DIRECT_NO; + debugs(44, 3, "direct = " << DirectStr[direct] << " (never_direct allow)"); break; case ACCESS_DENIED: // not relevant. case ACCESS_DUNNO: // not relevant. @@ -232,21 +214,26 @@ peerCheckNeverDirectDone(allow_t answer, void *data) debugs(44, DBG_IMPORTANT, "WARNING: never_direct resulted in " << answer << ". Username ACLs are not reliable here."); break; } - peerSelectFoo(psstate); + selectMore(); } -static void -peerCheckAlwaysDirectDone(allow_t answer, void *data) +void +PeerSelector::CheckNeverDirectDone(allow_t answer, void *data) { - ps_state *psstate = (ps_state *)data; - psstate->acl_checklist = NULL; - debugs(44, 3, "peerCheckAlwaysDirectDone: " << answer); - psstate->always_direct = answer; + static_cast(data)->checkNeverDirectDone(answer); +} + +void +PeerSelector::checkAlwaysDirectDone(const allow_t answer) +{ + acl_checklist = nullptr; + debugs(44, 3, answer); + always_direct = answer; switch (answer) { case ACCESS_ALLOWED: /** if always_direct says YES, do that. */ - psstate->direct = DIRECT_YES; - debugs(44, 3, HERE << "direct = " << DirectStr[psstate->direct] << " (always_direct allow)"); + direct = DIRECT_YES; + debugs(44, 3, "direct = " << DirectStr[direct] << " (always_direct allow)"); break; case ACCESS_DENIED: // not relevant. case ACCESS_DUNNO: // not relevant. @@ -255,35 +242,42 @@ peerCheckAlwaysDirectDone(allow_t answer, void *data) debugs(44, DBG_IMPORTANT, "WARNING: always_direct resulted in " << answer << ". Username ACLs are not reliable here."); break; } - peerSelectFoo(psstate); + selectMore(); +} + +void +PeerSelector::CheckAlwaysDirectDone(allow_t answer, void *data) +{ + static_cast(data)->checkAlwaysDirectDone(answer); } -/// \returns true (after destroying psstate) if the peer initiator is gone +/// \returns true (after destroying "this") if the peer initiator is gone /// \returns false (without side effects) otherwise -static bool -peerSelectionAborted(ps_state *psstate) +bool +PeerSelector::selectionAborted() { - if (psstate->interestedInitiator()) + if (interestedInitiator()) return false; debugs(44, 3, "Aborting peer selection: Initiator gone or lost interest."); - delete psstate; + delete this; return true; } +/// A single DNS resolution loop iteration: Converts selected FwdServer to IPs. void -peerSelectDnsPaths(ps_state *psstate) +PeerSelector::resolveSelected() { - if (peerSelectionAborted(psstate)) + if (selectionAborted()) return; - FwdServer *fs = psstate->servers; + FwdServer *fs = servers; // Bug 3243: CVE 2009-0801 // Bypass of browser same-origin access control in intercepted communication // To resolve this we must use only the original client destination when going DIRECT // on intercepted traffic which failed Host verification - const HttpRequest *req = psstate->request; + const HttpRequest *req = request; const bool isIntercepted = !req->flags.redirected && (req->flags.intercepted || req->flags.interceptTproxy); const bool useOriginalDst = Config.onoff.client_dst_passthru || !req->flags.hostVerified; @@ -295,22 +289,22 @@ peerSelectDnsPaths(ps_state *psstate) Comm::ConnectionPointer p = new Comm::Connection(); p->remote = req->clientConnectionManager->clientConnection->local; fs->code = ORIGINAL_DST; // fs->code is DIRECT. This fixes the display. - psstate->handlePath(p, *fs); + handlePath(p, *fs); } // clear the used fs and continue - psstate->servers = fs->next; + servers = fs->next; delete fs; - peerSelectDnsPaths(psstate); + resolveSelected(); return; } // convert the list of FwdServer destinations into destinations IP addresses - if (fs && psstate->wantsMoreDestinations()) { + if (fs && wantsMoreDestinations()) { // send the next one off for DNS lookup. - const char *host = fs->_peer.valid() ? fs->_peer->host : psstate->request->url.host(); - debugs(44, 2, "Find IP destination for: " << psstate->url() << "' via " << host); - Dns::nbgethostbyname(host, psstate); + const char *host = fs->_peer.valid() ? fs->_peer->host : request->url.host(); + debugs(44, 2, "Find IP destination for: " << url() << "' via " << host); + Dns::nbgethostbyname(host, this); return; } @@ -318,43 +312,43 @@ peerSelectDnsPaths(ps_state *psstate) // due to the allocation method of fs, we must deallocate each manually. // TODO: use a std::list so we can get the size and abort adding whenever the selection loops reach Config.forward_max_tries if (fs) { - assert(fs == psstate->servers); + assert(fs == servers); while (fs) { - psstate->servers = fs->next; + servers = fs->next; delete fs; - fs = psstate->servers; + fs = servers; } } // done with DNS lookups. pass back to caller - debugs(44, 2, psstate->id << " found all " << psstate->foundPaths << " destinations for " << psstate->url()); - debugs(44, 2, " always_direct = " << psstate->always_direct); - debugs(44, 2, " never_direct = " << psstate->never_direct); - debugs(44, 2, " timedout = " << psstate->ping.timedout); + debugs(44, 2, id << " found all " << foundPaths << " destinations for " << url()); + debugs(44, 2, " always_direct = " << always_direct); + debugs(44, 2, " never_direct = " << never_direct); + debugs(44, 2, " timedout = " << ping.timedout); - psstate->ping.stop = current_time; - psstate->request->hier.ping = psstate->ping; // final result + ping.stop = current_time; + request->hier.ping = ping; // final result - if (psstate->lastError && psstate->foundPaths) { + if (lastError && foundPaths) { // nobody cares about errors if we found destinations despite them debugs(44, 3, "forgetting the last error"); - delete psstate->lastError; - psstate->lastError = nullptr; + delete lastError; + lastError = nullptr; } - if (const auto initiator = psstate->interestedInitiator()) - initiator->noteDestinationsEnd(psstate->lastError); - psstate->lastError = nullptr; // initiator owns the ErrorState object now - delete psstate; + if (const auto initiator = interestedInitiator()) + initiator->noteDestinationsEnd(lastError); + lastError = nullptr; // initiator owns the ErrorState object now + delete this; } void -ps_state::noteLookup(const Dns::LookupDetails &details) +PeerSelector::noteLookup(const Dns::LookupDetails &details) { /* ignore lookup delays that occurred after the initiator moved on */ - if (peerSelectionAborted(this)) + if (selectionAborted()) return; if (!wantsMoreDestinations()) @@ -364,9 +358,9 @@ ps_state::noteLookup(const Dns::LookupDetails &details) } void -ps_state::noteIp(const Ip::Address &ip) +PeerSelector::noteIp(const Ip::Address &ip) { - if (peerSelectionAborted(this)) + if (selectionAborted()) return; if (!wantsMoreDestinations()) @@ -387,9 +381,9 @@ ps_state::noteIp(const Ip::Address &ip) } void -ps_state::noteIps(const Dns::CachedIps *ia, const Dns::LookupDetails &details) +PeerSelector::noteIps(const Dns::CachedIps *ia, const Dns::LookupDetails &details) { - if (peerSelectionAborted(this)) + if (selectionAborted()) return; FwdServer *fs = servers; @@ -408,46 +402,46 @@ ps_state::noteIps(const Dns::CachedIps *ia, const Dns::LookupDetails &details) servers = fs->next; delete fs; - // see if more paths can be found - peerSelectDnsPaths(this); + // continue resolving selected peers + resolveSelected(); } -static int -peerCheckNetdbDirect(ps_state * psstate) +int +PeerSelector::checkNetdbDirect() { #if USE_ICMP CachePeer *p; int myrtt; int myhops; - if (psstate->direct == DIRECT_NO) + if (direct == DIRECT_NO) return 0; /* base lookup on RTT and Hops if ICMP NetDB is enabled. */ - myrtt = netdbHostRtt(psstate->request->url.host()); + myrtt = netdbHostRtt(request->url.host()); debugs(44, 3, "MY RTT = " << myrtt << " msec"); debugs(44, 3, "minimum_direct_rtt = " << Config.minDirectRtt << " msec"); if (myrtt && myrtt <= Config.minDirectRtt) return 1; - myhops = netdbHostHops(psstate->request->url.host()); + myhops = netdbHostHops(request->url.host()); - debugs(44, 3, "peerCheckNetdbDirect: MY hops = " << myhops); - debugs(44, 3, "peerCheckNetdbDirect: minimum_direct_hops = " << Config.minDirectHops); + debugs(44, 3, "MY hops = " << myhops); + debugs(44, 3, "minimum_direct_hops = " << Config.minDirectHops); if (myhops && myhops <= Config.minDirectHops) return 1; - p = whichPeer(psstate->closest_parent_miss); + p = whichPeer(closest_parent_miss); if (p == NULL) return 0; - debugs(44, 3, "peerCheckNetdbDirect: closest_parent_miss RTT = " << psstate->ping.p_rtt << " msec"); + debugs(44, 3, "closest_parent_miss RTT = " << ping.p_rtt << " msec"); - if (myrtt && myrtt <= psstate->ping.p_rtt) + if (myrtt && myrtt <= ping.p_rtt) return 1; #endif /* USE_ICMP */ @@ -455,128 +449,119 @@ peerCheckNetdbDirect(ps_state * psstate) return 0; } -static void -peerSelectFoo(ps_state * ps) +void +PeerSelector::selectMore() { - if (peerSelectionAborted(ps)) + if (selectionAborted()) return; - StoreEntry *entry = ps->entry; - HttpRequest *request = ps->request; debugs(44, 3, request->method << ' ' << request->url.host()); /** If we don't know whether DIRECT is permitted ... */ - if (ps->direct == DIRECT_UNKNOWN) { - if (ps->always_direct == ACCESS_DUNNO) { - debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct] << " (always_direct to be checked)"); + if (direct == DIRECT_UNKNOWN) { + if (always_direct == ACCESS_DUNNO) { + debugs(44, 3, "direct = " << DirectStr[direct] << " (always_direct to be checked)"); /** check always_direct; */ ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, NULL); - ch->al = ps->al; - ps->acl_checklist = ch; - ps->acl_checklist->nonBlockingCheck(peerCheckAlwaysDirectDone, ps); + ch->al = al; + acl_checklist = ch; + acl_checklist->nonBlockingCheck(CheckAlwaysDirectDone, this); return; - } else if (ps->never_direct == ACCESS_DUNNO) { - debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct] << " (never_direct to be checked)"); + } else if (never_direct == ACCESS_DUNNO) { + debugs(44, 3, "direct = " << DirectStr[direct] << " (never_direct to be checked)"); /** check never_direct; */ ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.NeverDirect, request, NULL); - ch->al = ps->al; - ps->acl_checklist = ch; - ps->acl_checklist->nonBlockingCheck(peerCheckNeverDirectDone, ps); + ch->al = al; + acl_checklist = ch; + acl_checklist->nonBlockingCheck(CheckNeverDirectDone, this); return; } else if (request->flags.noDirect) { /** if we are accelerating, direct is not an option. */ - ps->direct = DIRECT_NO; - debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct] << " (forced non-direct)"); + direct = DIRECT_NO; + debugs(44, 3, "direct = " << DirectStr[direct] << " (forced non-direct)"); } else if (request->flags.loopDetected) { /** if we are in a forwarding-loop, direct is not an option. */ - ps->direct = DIRECT_YES; - debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct] << " (forwarding loop detected)"); - } else if (peerCheckNetdbDirect(ps)) { - ps->direct = DIRECT_YES; - debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct] << " (checkNetdbDirect)"); + direct = DIRECT_YES; + debugs(44, 3, "direct = " << DirectStr[direct] << " (forwarding loop detected)"); + } else if (checkNetdbDirect()) { + direct = DIRECT_YES; + debugs(44, 3, "direct = " << DirectStr[direct] << " (checkNetdbDirect)"); } else { - ps->direct = DIRECT_MAYBE; - debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct] << " (default)"); + direct = DIRECT_MAYBE; + debugs(44, 3, "direct = " << DirectStr[direct] << " (default)"); } - debugs(44, 3, "peerSelectFoo: direct = " << DirectStr[ps->direct]); + debugs(44, 3, "direct = " << DirectStr[direct]); } if (!entry || entry->ping_status == PING_NONE) - peerSelectPinned(ps); + selectPinned(); if (entry == NULL) { (void) 0; } else if (entry->ping_status == PING_NONE) { - peerGetSomeNeighbor(ps); + selectSomeNeighbor(); if (entry->ping_status == PING_WAITING) return; } else if (entry->ping_status == PING_WAITING) { - peerGetSomeNeighborReplies(ps); + selectSomeNeighborReplies(); entry->ping_status = PING_DONE; } - switch (ps->direct) { + switch (direct) { case DIRECT_YES: - peerGetSomeDirect(ps); + selectSomeDirect(); break; case DIRECT_NO: - peerGetSomeParent(ps); - peerGetAllParents(ps); + selectSomeParent(); + selectAllParents(); break; default: if (Config.onoff.prefer_direct) - peerGetSomeDirect(ps); + selectSomeDirect(); if (request->flags.hierarchical || !Config.onoff.nonhierarchical_direct) { - peerGetSomeParent(ps); - peerGetAllParents(ps); + selectSomeParent(); + selectAllParents(); } if (!Config.onoff.prefer_direct) - peerGetSomeDirect(ps); + selectSomeDirect(); break; } - // resolve the possible peers - peerSelectDnsPaths(ps); + // end peer selection; start resolving selected peers + resolveSelected(); } bool peerAllowedToUse(const CachePeer * p, HttpRequest * request); -/** - * peerSelectPinned - * - * Selects a pinned connection. - */ -static void -peerSelectPinned(ps_state * ps) +/// Selects a pinned connection if it exists, is valid, and is allowed. +void +PeerSelector::selectPinned() { - HttpRequest *request = ps->request; + // TODO: Avoid all repeated calls. Relying on PING_DONE is not enough. if (!request->pinnedConnection()) return; CachePeer *pear = request->pinnedConnection()->pinnedPeer(); if (Comm::IsConnOpen(request->pinnedConnection()->validatePinnedConnection(request, pear))) { - if (pear && peerAllowedToUse(pear, request)) { - peerAddFwdServer(ps, pear, PINNED); - if (ps->entry) - ps->entry->ping_status = PING_DONE; /* Skip ICP */ - } else if (!pear && ps->direct != DIRECT_NO) { - peerAddFwdServer(ps, nullptr, PINNED); - if (ps->entry) - ps->entry->ping_status = PING_DONE; /* Skip ICP */ + const bool usePinned = pear ? peerAllowedToUse(pear, request) : (direct != DIRECT_NO); + if (usePinned) { + addSelection(pear, PINNED); + if (entry) + entry->ping_status = PING_DONE; // skip ICP } } + // If the pinned connection is prohibited (for this request) or gone, then + // the initiator must decide whether it is OK to open a new one instead. } /** - * peerGetSomeNeighbor - * * Selects a neighbor (parent or sibling) based on one of the * following methods: * Cache Digests @@ -584,16 +569,14 @@ peerSelectPinned(ps_state * ps) * ICMP Netdb RTT estimates * ICP/HTCP queries */ -static void -peerGetSomeNeighbor(ps_state * ps) +void +PeerSelector::selectSomeNeighbor() { - StoreEntry *entry = ps->entry; - HttpRequest *request = ps->request; CachePeer *p; hier_code code = HIER_NONE; assert(entry->ping_status == PING_NONE); - if (ps->direct == DIRECT_YES) { + if (direct == DIRECT_YES) { entry->ping_status = PING_DONE; return; } @@ -608,28 +591,28 @@ peerGetSomeNeighbor(ps_state * ps) #endif if ((p = netdbClosestParent(request))) { code = CLOSEST_PARENT; - } else if (peerSelectIcpPing(request, ps->direct, entry)) { - debugs(44, 3, "peerSelect: Doing ICP pings"); - ps->ping.start = current_time; - ps->ping.n_sent = neighborsUdpPing(request, - entry, - peerHandlePingReply, - ps, - &ps->ping.n_replies_expected, - &ps->ping.timeout); - - if (ps->ping.n_sent == 0) + } else if (peerSelectIcpPing(request, direct, entry)) { + debugs(44, 3, "Doing ICP pings"); + ping.start = current_time; + ping.n_sent = neighborsUdpPing(request, + entry, + HandlePingReply, + this, + &ping.n_replies_expected, + &ping.timeout); + + if (ping.n_sent == 0) debugs(44, DBG_CRITICAL, "WARNING: neighborsUdpPing returned 0"); - debugs(44, 3, "peerSelect: " << ps->ping.n_replies_expected << - " ICP replies expected, RTT " << ps->ping.timeout << + debugs(44, 3, ping.n_replies_expected << + " ICP replies expected, RTT " << ping.timeout << " msec"); - if (ps->ping.n_replies_expected > 0) { + if (ping.n_replies_expected > 0) { entry->ping_status = PING_WAITING; - eventAdd("peerPingTimeout", - peerPingTimeout, - ps, - 0.001 * ps->ping.timeout, + eventAdd("PeerSelector::HandlePingTimeout", + HandlePingTimeout, + this, + 0.001 * ping.timeout, 0); return; } @@ -637,75 +620,65 @@ peerGetSomeNeighbor(ps_state * ps) if (code != HIER_NONE) { assert(p); - peerAddFwdServer(ps, p, code); + addSelection(p, code); } entry->ping_status = PING_DONE; } -/* - * peerGetSomeNeighborReplies - * - * Selects a neighbor (parent or sibling) based on ICP/HTCP replies. - */ -static void -peerGetSomeNeighborReplies(ps_state * ps) +/// Selects a neighbor (parent or sibling) based on ICP/HTCP replies. +void +PeerSelector::selectSomeNeighborReplies() { CachePeer *p = NULL; hier_code code = HIER_NONE; - assert(ps->entry->ping_status == PING_WAITING); - assert(ps->direct != DIRECT_YES); + assert(entry->ping_status == PING_WAITING); + assert(direct != DIRECT_YES); - if (peerCheckNetdbDirect(ps)) { + if (checkNetdbDirect()) { code = CLOSEST_DIRECT; - peerAddFwdServer(ps, nullptr, code); + addSelection(nullptr, code); return; } - if ((p = ps->hit)) { - code = ps->hit_type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT; + if ((p = hit)) { + code = hit_type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT; } else { - if (!ps->closest_parent_miss.isAnyAddr()) { - p = whichPeer(ps->closest_parent_miss); + if (!closest_parent_miss.isAnyAddr()) { + p = whichPeer(closest_parent_miss); code = CLOSEST_PARENT_MISS; - } else if (!ps->first_parent_miss.isAnyAddr()) { - p = whichPeer(ps->first_parent_miss); + } else if (!first_parent_miss.isAnyAddr()) { + p = whichPeer(first_parent_miss); code = FIRST_PARENT_MISS; } } if (p && code != HIER_NONE) { - peerAddFwdServer(ps, p, code); + addSelection(p, code); } } -/* - * peerGetSomeDirect - * - * Simply adds a 'direct' entry to the FwdServers list if this - * request can be forwarded directly to the origin server - */ -static void -peerGetSomeDirect(ps_state * ps) +/// Adds a "direct" entry if the request can be forwarded to the origin server. +void +PeerSelector::selectSomeDirect() { - if (ps->direct == DIRECT_NO) + if (direct == DIRECT_NO) return; /* WAIS is not implemented natively */ - if (ps->request->url.getScheme() == AnyP::PROTO_WAIS) + if (request->url.getScheme() == AnyP::PROTO_WAIS) return; - peerAddFwdServer(ps, nullptr, HIER_DIRECT); + addSelection(nullptr, HIER_DIRECT); } -static void -peerGetSomeParent(ps_state * ps) +void +PeerSelector::selectSomeParent() { CachePeer *p; - HttpRequest *request = ps->request; hier_code code = HIER_NONE; debugs(44, 3, request->method << ' ' << request->url.host()); - if (ps->direct == DIRECT_YES) + if (direct == DIRECT_YES) return; if ((p = peerSourceHashSelectParent(request))) { @@ -727,17 +700,15 @@ peerGetSomeParent(ps_state * ps) } if (code != HIER_NONE) { - peerAddFwdServer(ps, p, code); + addSelection(p, code); } } -/* Adds alive parents. Used as a last resort for never_direct. - */ -static void -peerGetAllParents(ps_state * ps) +/// Adds alive parents. Used as a last resort for never_direct. +void +PeerSelector::selectAllParents() { CachePeer *p; - HttpRequest *request = ps->request; /* Add all alive parents */ for (p = Config.peers; p; p = p->next) { @@ -751,7 +722,7 @@ peerGetAllParents(ps_state * ps) if (!peerHTTPOkay(p, request)) continue; - peerAddFwdServer(ps, p, ANY_OLD_PARENT); + addSelection(p, ANY_OLD_PARENT); } /* XXX: should add dead parents here, but it is currently @@ -760,25 +731,30 @@ peerGetAllParents(ps_state * ps) */ /* Add default parent as a last resort */ if ((p = getDefaultParent(request))) { - peerAddFwdServer(ps, p, DEFAULT_PARENT); + addSelection(p, DEFAULT_PARENT); } } -static void -peerPingTimeout(void *data) +void +PeerSelector::handlePingTimeout() { - ps_state *psstate = (ps_state *)data; - debugs(44, 3, psstate->url()); + debugs(44, 3, url()); - if (StoreEntry *entry = psstate->entry) + if (entry) entry->ping_status = PING_DONE; - if (peerSelectionAborted(psstate)) + if (selectionAborted()) return; ++PeerStats.timeouts; - psstate->ping.timedout = 1; - peerSelectFoo(psstate); + ping.timedout = 1; + selectMore(); +} + +void +PeerSelector::HandlePingTimeout(void *data) +{ + static_cast(data)->handlePingTimeout(); } void @@ -787,8 +763,8 @@ peerSelectInit(void) memset(&PeerStats, '\0', sizeof(PeerStats)); } -static void -peerIcpParentMiss(CachePeer * p, icp_common_t * header, ps_state * ps) +void +PeerSelector::handleIcpParentMiss(CachePeer *p, icp_common_t *header) { int rtt; @@ -799,11 +775,11 @@ peerIcpParentMiss(CachePeer * p, icp_common_t * header, ps_state * ps) int hops = (header->pad >> 16) & 0xFFFF; if (rtt > 0 && rtt < 0xFFFF) - netdbUpdatePeer(ps->request->url, p, rtt, hops); + netdbUpdatePeer(request->url, p, rtt, hops); - if (rtt && (ps->ping.p_rtt == 0 || rtt < ps->ping.p_rtt)) { - ps->closest_parent_miss = p->in_addr; - ps->ping.p_rtt = rtt; + if (rtt && (ping.p_rtt == 0 || rtt < ping.p_rtt)) { + closest_parent_miss = p->in_addr; + ping.p_rtt = rtt; } } } @@ -814,79 +790,77 @@ peerIcpParentMiss(CachePeer * p, icp_common_t * header, ps_state * ps) return; /* set FIRST_MISS if there is no CLOSEST parent */ - if (!ps->closest_parent_miss.isAnyAddr()) + if (!closest_parent_miss.isAnyAddr()) return; - rtt = (tvSubMsec(ps->ping.start, current_time) - p->basetime) / p->weight; + rtt = (tvSubMsec(ping.start, current_time) - p->basetime) / p->weight; if (rtt < 1) rtt = 1; - if (ps->first_parent_miss.isAnyAddr() || rtt < ps->ping.w_rtt) { - ps->first_parent_miss = p->in_addr; - ps->ping.w_rtt = rtt; + if (first_parent_miss.isAnyAddr() || rtt < ping.w_rtt) { + first_parent_miss = p->in_addr; + ping.w_rtt = rtt; } } -static void -peerHandleIcpReply(CachePeer * p, peer_t type, icp_common_t * header, void *data) +void +PeerSelector::handleIcpReply(CachePeer *p, const peer_t type, icp_common_t *header) { - ps_state *psstate = (ps_state *)data; icp_opcode op = header->getOpCode(); - debugs(44, 3, "peerHandleIcpReply: " << icp_opcode_str[op] << " " << psstate->url() ); + debugs(44, 3, icp_opcode_str[op] << ' ' << url()); #if USE_CACHE_DIGESTS && 0 /* do cd lookup to count false misses */ if (p && request) peerNoteDigestLookup(request, p, - peerDigestLookup(p, request, psstate->entry)); + peerDigestLookup(p, request, entry)); #endif - ++ psstate->ping.n_recv; + ++ping.n_recv; if (op == ICP_MISS || op == ICP_DECHO) { if (type == PEER_PARENT) - peerIcpParentMiss(p, header, psstate); + handleIcpParentMiss(p, header); } else if (op == ICP_HIT) { - psstate->hit = p; - psstate->hit_type = type; - peerSelectFoo(psstate); + hit = p; + hit_type = type; + selectMore(); return; } - if (psstate->ping.n_recv < psstate->ping.n_replies_expected) + if (ping.n_recv < ping.n_replies_expected) return; - peerSelectFoo(psstate); + selectMore(); } #if USE_HTCP -static void -peerHandleHtcpReply(CachePeer * p, peer_t type, HtcpReplyData * htcp, void *data) +void +PeerSelector::handleHtcpReply(CachePeer *p, const peer_t type, HtcpReplyData *htcp) { - ps_state *psstate = (ps_state *)data; - debugs(44, 3, "" << (htcp->hit ? "HIT" : "MISS") << " " << psstate->url()); - ++ psstate->ping.n_recv; + debugs(44, 3, (htcp->hit ? "HIT" : "MISS") << ' ' << url()); + ++ping.n_recv; if (htcp->hit) { - psstate->hit = p; - psstate->hit_type = type; - peerSelectFoo(psstate); + hit = p; + hit_type = type; + selectMore(); return; } if (type == PEER_PARENT) - peerHtcpParentMiss(p, htcp, psstate); + handleHtcpParentMiss(p, htcp); - if (psstate->ping.n_recv < psstate->ping.n_replies_expected) + if (ping.n_recv < ping.n_replies_expected) return; - peerSelectFoo(psstate); + selectMore(); } -static void -peerHtcpParentMiss(CachePeer * p, HtcpReplyData * htcp, ps_state * ps) +void +PeerSelector::handleHtcpParentMiss(CachePeer *p, HtcpReplyData *htcp) { int rtt; @@ -895,11 +869,11 @@ peerHtcpParentMiss(CachePeer * p, HtcpReplyData * htcp, ps_state * ps) if (htcp->cto.rtt > 0) { rtt = (int) htcp->cto.rtt * 1000; int hops = (int) htcp->cto.hops * 1000; - netdbUpdatePeer(ps->request->url, p, rtt, hops); + netdbUpdatePeer(request->url, p, rtt, hops); - if (rtt && (ps->ping.p_rtt == 0 || rtt < ps->ping.p_rtt)) { - ps->closest_parent_miss = p->in_addr; - ps->ping.p_rtt = rtt; + if (rtt && (ping.p_rtt == 0 || rtt < ping.p_rtt)) { + closest_parent_miss = p->in_addr; + ping.p_rtt = rtt; } } } @@ -910,65 +884,63 @@ peerHtcpParentMiss(CachePeer * p, HtcpReplyData * htcp, ps_state * ps) return; /* set FIRST_MISS if there is no CLOSEST parent */ - if (!ps->closest_parent_miss.isAnyAddr()) + if (!closest_parent_miss.isAnyAddr()) return; - rtt = (tvSubMsec(ps->ping.start, current_time) - p->basetime) / p->weight; + rtt = (tvSubMsec(ping.start, current_time) - p->basetime) / p->weight; if (rtt < 1) rtt = 1; - if (ps->first_parent_miss.isAnyAddr() || rtt < ps->ping.w_rtt) { - ps->first_parent_miss = p->in_addr; - ps->ping.w_rtt = rtt; + if (first_parent_miss.isAnyAddr() || rtt < ping.w_rtt) { + first_parent_miss = p->in_addr; + ping.w_rtt = rtt; } } #endif -static void -peerHandlePingReply(CachePeer * p, peer_t type, AnyP::ProtocolType proto, void *pingdata, void *data) +void +PeerSelector::HandlePingReply(CachePeer * p, peer_t type, AnyP::ProtocolType proto, void *pingdata, void *data) { if (proto == AnyP::PROTO_ICP) - peerHandleIcpReply(p, type, (icp_common_t *)pingdata, data); + static_cast(data)->handleIcpReply(p, type, static_cast(pingdata)); #if USE_HTCP else if (proto == AnyP::PROTO_HTCP) - peerHandleHtcpReply(p, type, (HtcpReplyData *)pingdata, data); + static_cast(data)->handleHtcpReply(p, type, static_cast(pingdata)); #endif else - debugs(44, DBG_IMPORTANT, "peerHandlePingReply: unknown protocol " << proto); + debugs(44, DBG_IMPORTANT, "ERROR: ignoring an ICP reply with unknown protocol " << proto); } -static void -peerAddFwdServer(ps_state *ps, CachePeer *peer, const hier_code code) +void +PeerSelector::addSelection(CachePeer *peer, const hier_code code) { // Find the end of the servers list. Bail on a duplicate destination. - assert(ps); - FwdServer **FSVR = &ps->servers; - while (const auto server = *FSVR) { + auto **serversTail = &servers; + while (const auto server = *serversTail) { // There can be at most one PINNED destination. // Non-PINNED destinations are uniquely identified by their CachePeer // (even though a DIRECT destination might match a cache_peer address). const bool duplicate = (server->code == PINNED) ? - (code == PINNED) : (server->_peer == peer); + (code == PINNED) : (server->_peer == peer); if (duplicate) { - debugs(44, 3, "skipping " << PeerSelectionDumper(ps, peer, code) << - "; have " << PeerSelectionDumper(ps, server->_peer.get(), server->code)); + debugs(44, 3, "skipping " << PeerSelectionDumper(this, peer, code) << + "; have " << PeerSelectionDumper(this, server->_peer.get(), server->code)); return; } - FSVR = &server->next; + serversTail = &server->next; } - debugs(44, 3, "adding " << PeerSelectionDumper(ps, peer, code)); - FwdServer *fs = new FwdServer(peer, code); - *FSVR = fs; + debugs(44, 3, "adding " << PeerSelectionDumper(this, peer, code)); + *serversTail = new FwdServer(peer, code); } -ps_state::ps_state(PeerSelectionInitiator *initiator): +PeerSelector::PeerSelector(PeerSelectionInitiator *initiator): request(nullptr), entry (NULL), always_direct(Config.accessList.AlwaysDirect?ACCESS_DUNNO:ACCESS_DENIED), @@ -987,7 +959,7 @@ ps_state::ps_state(PeerSelectionInitiator *initiator): } const SBuf -ps_state::url() const +PeerSelector::url() const { if (entry) return SBuf(entry->url()); @@ -1001,7 +973,7 @@ ps_state::url() const /// \returns valid/interested peer initiator or nil PeerSelectionInitiator * -ps_state::interestedInitiator() +PeerSelector::interestedInitiator() { const auto initiator = initiator_.valid(); @@ -1020,14 +992,14 @@ ps_state::interestedInitiator() } bool -ps_state::wantsMoreDestinations() const { +PeerSelector::wantsMoreDestinations() const { const auto maxCount = Config.forward_max_tries; return maxCount >= 0 && foundPaths < static_cast::type>(maxCount); } void -ps_state::handlePath(Comm::ConnectionPointer &path, FwdServer &fs) +PeerSelector::handlePath(Comm::ConnectionPointer &path, FwdServer &fs) { ++foundPaths; @@ -1048,7 +1020,7 @@ ps_state::handlePath(Comm::ConnectionPointer &path, FwdServer &fs) initiator->noteDestination(path); } -InstanceIdDefinitions(ps_state, "PeerSelector"); +InstanceIdDefinitions(PeerSelector, "PeerSelector"); ping_data::ping_data() : n_sent(0), diff --git a/src/tests/stub_icp.cc b/src/tests/stub_icp.cc index d451392f1b..477c642e90 100644 --- a/src/tests/stub_icp.cc +++ b/src/tests/stub_icp.cc @@ -13,15 +13,13 @@ #define STUB_API "icp_*.cc" #include "tests/STUB.h" -#ifdef __cplusplus -_icp_common_t::_icp_common_t() STUB -_icp_common_t::_icp_common_t(char *buf, unsigned int len) STUB -void _icp_common_t::handleReply(char *buf, Ip::Address &from) STUB -_icp_common_t *_icp_common_t::createMessage(icp_opcode opcode, int flags, const char *url, int reqnum, int pad) STUB_RETVAL(NULL) -icp_opcode _icp_common_t::getOpCode() const STUB_RETVAL(ICP_INVALID) +icp_common_t::icp_common_t() STUB +icp_common_t::icp_common_t(char *buf, unsigned int len) STUB +void icp_common_t::handleReply(char *buf, Ip::Address &from) STUB +icp_common_t *icp_common_t::CreateMessage(icp_opcode opcode, int flags, const char *url, int reqnum, int pad) STUB_RETVAL(nullptr) +icp_opcode icp_common_t::getOpCode() const STUB_RETVAL(ICP_INVALID) ICPState::ICPState(icp_common_t &aHeader, HttpRequest *aRequest) STUB ICPState::~ICPState() STUB -#endif Comm::ConnectionPointer icpIncomingConn; Comm::ConnectionPointer icpOutgoingConn;