]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ResolvedPeers.h
Maintenance: automate header guards 2/3 (#1655)
[thirdparty/squid.git] / src / ResolvedPeers.h
CommitLineData
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
20class ResolvedPeerPath
21{
22public:
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
29class PeerConnectionPointer;
30
55622953
CT
31/// cache_peer and origin server addresses (a.k.a. paths)
32/// selected and resolved by the peering code
33class ResolvedPeers: public RefCountable
34{
35 MEMPROXY_CLASS(ResolvedPeers);
36
37public:
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 &currentPeer);
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 &currentPeer);
55622953
CT
65
66 /// whether extractSpare() would return a non-nil path right now
67 bool haveSpare(const Comm::Connection &currentPeer);
68
69 /// whether extractPrime() returns and will continue to return nil
a4d576de 70 bool doneWithPrimes(const Comm::Connection &currentPeer);
55622953
CT
71
72 /// whether extractSpare() returns and will continue to return nil
73 bool doneWithSpares(const Comm::Connection &currentPeer);
74
75 /// whether doneWithPrimes() and doneWithSpares() are true for currentPeer
a4d576de 76 bool doneWithPeer(const Comm::Connection &currentPeer);
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
87private:
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 &currentPeer);
97 Finding findPrime(const Comm::Connection &currentPeer);
98 Finding findPeer(const Comm::Connection &currentPeer);
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.
121class PeerConnectionPointer
122{
123public:
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
144private:
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)
157std::ostream &operator <<(std::ostream &, const ResolvedPeers &);
158
9b7992d9
EB
159inline std::ostream &
160operator <<(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