]>
Commit | Line | Data |
---|---|---|
b24880fe | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
b24880fe | 3 | * |
bbc27441 AJ |
4 | * Squid software is distributed under GPLv2+ license and includes |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
b24880fe | 7 | */ |
8 | ||
ff9d9458 FC |
9 | #ifndef SQUID_SRC_PEERSELECTSTATE_H |
10 | #define SQUID_SRC_PEERSELECTSTATE_H | |
b24880fe | 11 | |
d4806c91 | 12 | #include "AccessLogEntry.h" |
2efeb0b7 | 13 | #include "acl/Checklist.h" |
3c670b50 | 14 | #include "base/CbcPointer.h" |
f9b72e0c AJ |
15 | #include "comm/forward.h" |
16 | #include "hier_code.h" | |
96d89ea0 | 17 | #include "ip/Address.h" |
fd9c47d1 | 18 | #include "ipcache.h" |
3c670b50 | 19 | #include "mem/forward.h" |
602d9612 | 20 | #include "PingData.h" |
55622953 | 21 | #include "typedefs.h" /* for IRCB */ |
cfd66529 | 22 | |
cb835136 AR |
23 | class ErrorState; |
24 | class HtcpReplyData; | |
cfd66529 | 25 | class HttpRequest; |
cb835136 | 26 | class icp_common_t; |
cfd66529 AJ |
27 | class StoreEntry; |
28 | ||
d9c252f2 | 29 | void peerSelectInit(void); |
cfd66529 | 30 | |
6043e368 AR |
31 | /// Interface for those who need a list of peers to forward a request to. |
32 | class PeerSelectionInitiator: public CbdataParent | |
cfd66529 AJ |
33 | { |
34 | public: | |
337b9aa4 | 35 | ~PeerSelectionInitiator() override = default; |
6043e368 AR |
36 | |
37 | /// called when a new unique destination has been found | |
38 | virtual void noteDestination(Comm::ConnectionPointer path) = 0; | |
39 | ||
40 | /// called when there will be no more noteDestination() calls | |
41 | /// \param error is a possible reason why no destinations were found; it is | |
42 | /// guaranteed to be nil if there was at least one noteDestination() call | |
43 | virtual void noteDestinationsEnd(ErrorState *error) = 0; | |
44 | ||
45 | /// whether noteDestination() and noteDestinationsEnd() calls are allowed | |
46 | bool subscribed = false; | |
47 | ||
d22511f9 | 48 | /* protected: */ |
6043e368 AR |
49 | /// Initiates asynchronous peer selection that eventually |
50 | /// results in zero or more noteDestination() calls and | |
51 | /// exactly one noteDestinationsEnd() call. | |
52 | void startSelectingDestinations(HttpRequest *request, const AccessLogEntry::Pointer &ale, StoreEntry *entry); | |
cfd66529 | 53 | }; |
b24880fe | 54 | |
6043e368 AR |
55 | class FwdServer; |
56 | ||
cb835136 AR |
57 | /// Finds peer (including origin server) IPs for forwarding a single request. |
58 | /// Gives PeerSelectionInitiator each found destination, in the right order. | |
59 | class PeerSelector: public Dns::IpReceiver | |
b24880fe | 60 | { |
cb835136 | 61 | CBDATA_CHILD(PeerSelector); |
b24880fe | 62 | |
63 | public: | |
cb835136 | 64 | explicit PeerSelector(PeerSelectionInitiator*); |
337b9aa4 | 65 | ~PeerSelector() override; |
fd9c47d1 AR |
66 | |
67 | /* Dns::IpReceiver API */ | |
337b9aa4 AR |
68 | void noteIp(const Ip::Address &ip) override; |
69 | void noteIps(const Dns::CachedIps *ips, const Dns::LookupDetails &details) override; | |
70 | void noteLookup(const Dns::LookupDetails &details) override; | |
769c64cc AJ |
71 | |
72 | // Produce a URL for display identifying the transaction we are | |
73 | // trying to locate a peer for. | |
851feda6 | 74 | const SBuf url() const; |
769c64cc | 75 | |
6043e368 AR |
76 | /// \returns valid/interested peer initiator or nil |
77 | PeerSelectionInitiator *interestedInitiator(); | |
78 | ||
79 | /// \returns whether the initiator may use more destinations | |
80 | bool wantsMoreDestinations() const; | |
81 | ||
82 | /// processes a newly discovered/finalized path | |
3dde9e52 | 83 | void handlePath(const Comm::ConnectionPointer &path, FwdServer &fs); |
6043e368 | 84 | |
cb835136 AR |
85 | /// a single selection loop iteration: attempts to add more destinations |
86 | void selectMore(); | |
87 | ||
9865de72 EB |
88 | /// switches into the PING_WAITING state (and associated timeout monitoring) |
89 | void startPingWaiting(); | |
90 | ||
91 | /// terminates ICP ping timeout monitoring | |
92 | void cancelPingTimeoutMonitoring(); | |
93 | ||
94 | /// called when the given selector should stop expecting ICP ping responses | |
95 | static void HandlePingTimeout(PeerSelector *); | |
96 | ||
b24880fe | 97 | HttpRequest *request; |
d4806c91 | 98 | AccessLogEntry::Pointer al; ///< info for the future access.log entry |
b24880fe | 99 | StoreEntry *entry; |
cb835136 AR |
100 | |
101 | void *peerCountMcastPeerXXX = nullptr; ///< a hack to help peerCountMcastPeersStart() | |
102 | ||
103 | ping_data ping; | |
104 | ||
105 | protected: | |
106 | bool selectionAborted(); | |
107 | ||
108 | void handlePingTimeout(); | |
109 | void handleIcpReply(CachePeer*, const peer_t, icp_common_t *header); | |
110 | void handleIcpParentMiss(CachePeer*, icp_common_t*); | |
111 | #if USE_HTCP | |
112 | void handleHtcpParentMiss(CachePeer*, HtcpReplyData*); | |
113 | void handleHtcpReply(CachePeer*, const peer_t, HtcpReplyData*); | |
114 | #endif | |
115 | ||
116 | int checkNetdbDirect(); | |
329c128c | 117 | void checkAlwaysDirectDone(const Acl::Answer answer); |
118 | void checkNeverDirectDone(const Acl::Answer answer); | |
cb835136 AR |
119 | |
120 | void selectSomeNeighbor(); | |
121 | void selectSomeNeighborReplies(); | |
122 | void selectSomeDirect(); | |
123 | void selectSomeParent(); | |
124 | void selectAllParents(); | |
125 | void selectPinned(); | |
126 | ||
127 | void addSelection(CachePeer*, const hier_code); | |
128 | ||
129 | void resolveSelected(); | |
130 | ||
131 | static IRCB HandlePingReply; | |
132 | static ACLCB CheckAlwaysDirectDone; | |
133 | static ACLCB CheckNeverDirectDone; | |
cb835136 AR |
134 | |
135 | private: | |
329c128c | 136 | Acl::Answer always_direct; |
137 | Acl::Answer never_direct; | |
2efeb0b7 | 138 | int direct; // TODO: fold always_direct/never_direct/prefer_direct into this now that ACL can do a multi-state result. |
6043e368 | 139 | size_t foundPaths = 0; ///< number of unique destinations identified so far |
a37fdd8a | 140 | ErrorState *lastError; |
cfd66529 | 141 | |
cb835136 | 142 | FwdServer *servers; ///< a linked list of (unresolved) selected peers |
cfd66529 | 143 | |
b24880fe | 144 | /* |
a3c6762c FC |
145 | * Why are these Ip::Address instead of CachePeer *? Because a |
146 | * CachePeer structure can become invalid during the CachePeer selection | |
b24880fe | 147 | * phase, specifically after a reconfigure. Thus we need to lookup |
a3c6762c FC |
148 | * the CachePeer * based on the address when we are finally ready to |
149 | * reference the CachePeer structure. | |
b24880fe | 150 | */ |
151 | ||
b7ac5457 | 152 | Ip::Address first_parent_miss; |
b24880fe | 153 | |
b7ac5457 | 154 | Ip::Address closest_parent_miss; |
b24880fe | 155 | /* |
a3c6762c | 156 | * ->hit can be CachePeer* because it should only be |
cc192b50 | 157 | * accessed during the thread when it is set |
b24880fe | 158 | */ |
a3c6762c | 159 | CachePeer *hit; |
b24880fe | 160 | peer_t hit_type; |
b24880fe | 161 | ACLChecklist *acl_checklist; |
6043e368 | 162 | |
6043e368 AR |
163 | typedef CbcPointer<PeerSelectionInitiator> Initiator; |
164 | Initiator initiator_; ///< recipient of the destinations we select; use interestedInitiator() to access | |
cb835136 AR |
165 | |
166 | const InstanceId<PeerSelector> id; ///< unique identification in worker log | |
b24880fe | 167 | }; |
168 | ||
ff9d9458 | 169 | #endif /* SQUID_SRC_PEERSELECTSTATE_H */ |
f53969cc | 170 |