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