]>
Commit | Line | Data |
---|---|---|
55622953 | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
55622953 CT |
3 | * |
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. | |
7 | */ | |
8 | ||
ff9d9458 FC |
9 | #ifndef SQUID_SRC_RESOLVEDPEERS_H |
10 | #define SQUID_SRC_RESOLVEDPEERS_H | |
55622953 CT |
11 | |
12 | #include "base/RefCount.h" | |
a7b75c64 FC |
13 | #include "comm/Connection.h" |
14 | #include "mem/AllocatorProxy.h" | |
55622953 CT |
15 | |
16 | #include <iosfwd> | |
9b7992d9 | 17 | #include <limits> |
a4d576de EB |
18 | #include <utility> |
19 | ||
20 | class ResolvedPeerPath | |
21 | { | |
22 | public: | |
23 | explicit ResolvedPeerPath(const Comm::ConnectionPointer &conn) : connection(conn), available(true) {} | |
24 | ||
25 | Comm::ConnectionPointer connection; ///< (the address of) a path | |
26 | bool available; ///< whether this path may be used (i.e., has not been tried already) | |
27 | }; | |
55622953 | 28 | |
9b7992d9 EB |
29 | class PeerConnectionPointer; |
30 | ||
55622953 CT |
31 | /// cache_peer and origin server addresses (a.k.a. paths) |
32 | /// selected and resolved by the peering code | |
33 | class ResolvedPeers: public RefCountable | |
34 | { | |
35 | MEMPROXY_CLASS(ResolvedPeers); | |
36 | ||
37 | public: | |
a4d576de EB |
38 | // ResolvedPeerPaths in addPath() call order |
39 | typedef std::vector<ResolvedPeerPath> Paths; | |
40 | using size_type = Paths::size_type; | |
55622953 CT |
41 | typedef RefCount<ResolvedPeers> Pointer; |
42 | ||
43 | ResolvedPeers(); | |
44 | ||
45 | /// whether we lack any known candidate paths | |
a4d576de | 46 | bool empty() const { return !availablePaths; } |
55622953 CT |
47 | |
48 | /// add a candidate path to try after all the existing paths | |
49 | void addPath(const Comm::ConnectionPointer &); | |
50 | ||
9b7992d9 EB |
51 | /// makes the previously extracted path available for extraction at its |
52 | /// original position | |
53 | void reinstatePath(const PeerConnectionPointer &); | |
55622953 CT |
54 | |
55 | /// extracts and returns the first queued address | |
9b7992d9 | 56 | PeerConnectionPointer extractFront(); |
55622953 CT |
57 | |
58 | /// extracts and returns the first same-peer same-family address | |
59 | /// \returns nil if it cannot find the requested address | |
9b7992d9 | 60 | PeerConnectionPointer extractPrime(const Comm::Connection ¤tPeer); |
55622953 CT |
61 | |
62 | /// extracts and returns the first same-peer different-family address | |
63 | /// \returns nil if it cannot find the requested address | |
9b7992d9 | 64 | PeerConnectionPointer extractSpare(const Comm::Connection ¤tPeer); |
55622953 CT |
65 | |
66 | /// whether extractSpare() would return a non-nil path right now | |
67 | bool haveSpare(const Comm::Connection ¤tPeer); | |
68 | ||
69 | /// whether extractPrime() returns and will continue to return nil | |
a4d576de | 70 | bool doneWithPrimes(const Comm::Connection ¤tPeer); |
55622953 CT |
71 | |
72 | /// whether extractSpare() returns and will continue to return nil | |
73 | bool doneWithSpares(const Comm::Connection ¤tPeer); | |
74 | ||
75 | /// whether doneWithPrimes() and doneWithSpares() are true for currentPeer | |
a4d576de | 76 | bool doneWithPeer(const Comm::Connection ¤tPeer); |
55622953 CT |
77 | |
78 | /// the current number of candidate paths | |
a4d576de | 79 | size_type size() const { return availablePaths; } |
55622953 CT |
80 | |
81 | /// whether all of the available candidate paths received from DNS | |
82 | bool destinationsFinalized = false; | |
83 | ||
84 | /// whether HappyConnOpener::noteCandidatesChange() is scheduled to fire | |
85 | bool notificationPending = false; | |
86 | ||
87 | private: | |
a4d576de EB |
88 | /// A find*() result: An iterator of the found path (or paths_.end()) and |
89 | /// whether the "other" path was found instead. | |
90 | typedef std::pair<Paths::iterator, bool> Finding; | |
91 | ||
55622953 CT |
92 | /// The protocol family of the given path, AF_INET or AF_INET6 |
93 | static int ConnectionFamily(const Comm::Connection &conn); | |
94 | ||
a4d576de EB |
95 | Paths::iterator start(); |
96 | Finding findSpare(const Comm::Connection ¤tPeer); | |
97 | Finding findPrime(const Comm::Connection ¤tPeer); | |
98 | Finding findPeer(const Comm::Connection ¤tPeer); | |
9b7992d9 | 99 | PeerConnectionPointer extractFound(const char *description, const Paths::iterator &found); |
a4d576de EB |
100 | Finding makeFinding(const Paths::iterator &found, bool foundOther); |
101 | ||
102 | bool doneWith(const Finding &findings) const; | |
103 | ||
104 | void increaseAvailability(); | |
105 | void decreaseAvailability(); | |
106 | ||
107 | Paths paths_; ///< resolved addresses in (peer, family) order | |
108 | ||
109 | /// the number of leading paths_ elements that are all currently unavailable | |
110 | /// i.e. the size of the front paths_ segment comprised of unavailable items | |
111 | /// i.e. the position of the first available path (or paths_.size()) | |
112 | size_type pathsToSkip = 0; | |
55622953 | 113 | |
a4d576de EB |
114 | /// the total number of currently available elements in paths_ |
115 | size_type availablePaths = 0; | |
55622953 CT |
116 | }; |
117 | ||
9b7992d9 EB |
118 | /// An invasive reference-counting Comm::Connection pointer that also keeps an |
119 | /// (optional) ResolvedPeers position for the ResolvedPeers::reinstatePath() usage. | |
120 | /// Reference counting mechanism is compatible with Comm::ConnectionPointer. | |
121 | class PeerConnectionPointer | |
122 | { | |
123 | public: | |
124 | using size_type = ResolvedPeers::size_type; | |
125 | ||
126 | PeerConnectionPointer() = default; | |
127 | PeerConnectionPointer(std::nullptr_t): PeerConnectionPointer() {} ///< implicit nullptr conversion | |
128 | PeerConnectionPointer(const Comm::ConnectionPointer &conn, const size_type pos): connection_(conn), position_(pos) {} | |
129 | ||
130 | /* read-only pointer API; for Connection assignment, see finalize() */ | |
131 | explicit operator bool() const { return static_cast<bool>(connection_); } | |
132 | Comm::Connection *operator->() const { assert(connection_); return connection_.getRaw(); } | |
133 | Comm::Connection &operator *() const { assert(connection_); return *connection_; } | |
134 | ||
135 | /// convenience conversion to Comm::ConnectionPointer | |
136 | operator const Comm::ConnectionPointer&() const { return connection_; } | |
137 | ||
138 | /// upgrade stored peer selection details with a matching actual connection | |
139 | void finalize(const Comm::ConnectionPointer &conn) { connection_ = conn; } | |
140 | ||
141 | /// debugging dump | |
142 | void print(std::ostream &) const; | |
143 | ||
144 | private: | |
145 | /// non-existent position for nil connection | |
146 | static constexpr auto npos = std::numeric_limits<size_type>::max(); | |
147 | ||
148 | /// half-baked, open, failed, or closed Comm::Connection (or nil) | |
149 | Comm::ConnectionPointer connection_; | |
150 | ||
151 | /// ResolvedPeers-maintained membership index (or npos) | |
152 | size_type position_ = npos; | |
153 | friend class ResolvedPeers; | |
154 | }; | |
155 | ||
55622953 CT |
156 | /// summarized ResolvedPeers (for debugging) |
157 | std::ostream &operator <<(std::ostream &, const ResolvedPeers &); | |
158 | ||
9b7992d9 EB |
159 | inline std::ostream & |
160 | operator <<(std::ostream &os, const PeerConnectionPointer &dest) | |
161 | { | |
162 | dest.print(os); | |
163 | return os; | |
164 | } | |
165 | ||
ff9d9458 | 166 | #endif /* SQUID_SRC_RESOLVEDPEERS_H */ |
55622953 | 167 |