PeerPoolMgr.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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#include "squid.h"
10#include "AccessLogEntry.h"
11#include "base/AsyncCallbacks.h"
13#include "CachePeer.h"
14#include "comm/Connection.h"
15#include "comm/ConnOpener.h"
16#include "debug/Stream.h"
17#include "fd.h"
18#include "FwdState.h"
19#include "globals.h"
20#include "HttpRequest.h"
21#include "MasterXaction.h"
22#include "neighbors.h"
23#include "pconn.h"
24#include "PeerPoolMgr.h"
26#include "SquidConfig.h"
27
29
31 peer(cbdataReference(aPeer)),
32 request(),
33 transportWait(),
34 encryptionWait(),
35 addrUsed(0)
36{
37}
38
40{
42}
43
44void
46{
48
49 const auto mx = MasterXaction::MakePortless<XactionInitiator::initPeerPool>();
50 // ErrorState, getOutgoingAddress(), and other APIs may require a request.
51 // We fake one. TODO: Optionally send this request to peers?
54
55 checkpoint("peer initialized");
56}
57
58void
60{
62}
63
64bool
66{
68}
69
70bool
72{
73 return !(validPeer() && peer->standby.limit) && AsyncJob::doneAll();
74}
75
76void
78{
80
81 if (!validPeer()) {
82 debugs(48, 3, "peer gone");
83 if (params.conn != nullptr)
84 params.conn->close();
85 return;
86 }
87
88 if (params.flag != Comm::OK) {
90 checkpoint("conn opening failure"); // may retry
91 return;
92 }
93
94 Must(params.conn != nullptr);
95
96 // Handle TLS peers.
98 // XXX: Exceptions orphan params.conn
99 const auto callback = asyncCallback(48, 4, PeerPoolMgr::handleSecuredPeer, this);
100
101 const auto peerTimeout = peer->connectTimeout();
102 const int timeUsed = squid_curtime - params.conn->startTime();
103 // Use positive timeout when less than one second is left for conn.
104 const int timeLeft = positiveTimeout(peerTimeout - timeUsed);
105 const auto connector = new Security::BlindPeerConnector(request, params.conn, callback, nullptr, timeLeft);
106 encryptionWait.start(connector, callback);
107 return;
108 }
109
110 pushNewConnection(params.conn);
111}
112
113void
115{
116 Must(validPeer());
118 peer->standby.pool->push(conn, nullptr /* domain */);
119 // push() will trigger a checkpoint()
120}
121
122void
124{
126
127 if (!validPeer()) {
128 debugs(48, 3, "peer gone");
129 if (answer.conn != nullptr)
130 answer.conn->close();
131 return;
132 }
133
134 assert(!answer.tunneled);
135 if (answer.error.get()) {
136 assert(!answer.conn);
137 // PeerConnector calls NoteOutgoingConnectionFailure() for us
138 checkpoint("conn securing failure"); // may retry
139 return;
140 }
141
142 assert(answer.conn);
143
144 // The socket could get closed while our callback was queued. Sync
145 // Connection. XXX: Connection::fd may already be stale/invalid here.
146 if (answer.conn->isOpen() && fd_table[answer.conn->fd].closing()) {
147 answer.conn->noteClosure();
148 checkpoint("external connection closure"); // may retry
149 return;
150 }
151
152 pushNewConnection(answer.conn);
153}
154
155void
157{
158 // KISS: Do nothing else when we are already doing something.
160 debugs(48, 7, "busy: " << transportWait << '|' << encryptionWait << '|' << shutting_down);
161 return; // there will be another checkpoint when we are done opening/securing
162 }
163
164 // Do not talk to a peer until it is ready.
165 if (!neighborUp(peer)) // provides debugging
166 return; // there will be another checkpoint when peer is up
167
168 // Do not violate peer limits.
169 if (!peerCanOpenMore(peer)) { // provides debugging
170 peer->standby.waitingForClose = true; // may already be true
171 return; // there will be another checkpoint when a peer conn closes
172 }
173
174 // Do not violate global restrictions.
175 if (fdUsageHigh()) {
176 debugs(48, 7, "overwhelmed");
177 peer->standby.waitingForClose = true; // may already be true
178 // There will be another checkpoint when a peer conn closes OR when
179 // a future pop() fails due to an empty pool. See PconnPool::pop().
180 return;
181 }
182
184
186 Must(peer->n_addresses); // guaranteed by neighborUp() above
187 // cycle through all available IP addresses
188 conn->remote = peer->addresses[addrUsed++ % peer->n_addresses];
189 conn->remote.port(peer->http_port);
190 conn->peerType = STANDBY_POOL; // should be reset by peerSelect()
191 conn->setPeer(peer);
194
195 const auto ctimeout = peer->connectTimeout();
198 const auto cs = new Comm::ConnOpener(conn, callback, ctimeout);
199 transportWait.start(cs, callback);
200}
201
202void
204{
205 debugs(48, 8, howMany);
206 peer->standby.pool->closeN(howMany);
207}
208
209void
210PeerPoolMgr::checkpoint(const char *reason)
211{
212 if (!validPeer()) {
213 debugs(48, 3, reason << " and peer gone");
214 return; // nothing to do after our owner dies; the job will quit
215 }
216
217 const int count = peer->standby.pool->count();
218 const int limit = peer->standby.limit;
219 debugs(48, 7, reason << " with " << count << " ? " << limit);
220
221 if (count < limit)
223 else if (count > limit)
224 closeOldConnections(count - limit);
225}
226
227void
228PeerPoolMgr::Checkpoint(const Pointer &mgr, const char *reason)
229{
230 CallJobHere1(48, 5, mgr, PeerPoolMgr, checkpoint, reason);
231}
232
235{
236public:
237 /* RegisteredRunner API */
238 void useConfig() override { syncConfig(); }
239 void syncConfig() override;
240};
241
243
244void
246{
247 for (CachePeer *p = Config.peers; p; p = p->next) {
248 // On reconfigure, Squid deletes the old config (and old peers in it),
249 // so should always be dealing with a brand new configuration.
250 assert(!p->standby.mgr);
251 assert(!p->standby.pool);
252 if (p->standby.limit) {
253 p->standby.mgr = new PeerPoolMgr(p);
254 p->standby.pool = new PconnPool(p->name, p->standby.mgr);
255 AsyncJob::Start(p->standby.mgr.get());
256 }
257 }
258}
259
#define asyncCallback(dbgSection, dbgLevel, method, object)
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
Definition: AsyncJobCalls.h:69
#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1)
Definition: AsyncJobCalls.h:63
void NoteOutgoingConnectionFailure(CachePeer *const peer, const Http::StatusCode code)
Definition: CachePeer.h:245
void getOutgoingAddress(HttpRequest *request, const Comm::ConnectionPointer &conn)
Definition: FwdState.cc:1484
void GetMarkingsToServer(HttpRequest *request, Comm::Connection &conn)
Definition: FwdState.cc:1563
RunnerRegistrationEntry(PeerPoolMgrsRr)
time_t squid_curtime
Definition: stub_libtime.cc:20
class SquidConfig Config
Definition: SquidConfig.cc:12
#define Must(condition)
Definition: TextException.h:71
int conn
the current server connection FD
Definition: Transport.cc:26
#define assert(EX)
Definition: assert.h:17
int cbdataReferenceValid(const void *p)
Definition: cbdata.cc:265
#define cbdataReferenceDone(var)
Definition: cbdata.h:352
#define cbdataReference(var)
Definition: cbdata.h:343
#define CBDATA_CLASS_INIT(type)
Definition: cbdata.h:320
void host(const char *src)
Definition: Uri.cc:99
static void Start(const Pointer &job)
Definition: AsyncJob.cc:24
virtual bool doneAll() const
whether positive goal has been reached
Definition: AsyncJob.cc:97
virtual void start()
called by AsyncStart; do not call directly
Definition: AsyncJob.cc:44
virtual void swanSong()
Definition: AsyncJob.h:59
int n_addresses
Definition: CachePeer.h:182
unsigned short http_port
Definition: CachePeer.h:104
char * host
Definition: CachePeer.h:66
Security::PeerOptions secure
security settings for peer connection
Definition: CachePeer.h:221
int limit
the limit itself
Definition: CachePeer.h:214
CachePeer * next
Definition: CachePeer.h:184
PconnPool * pool
idle connection pool for this peer
Definition: CachePeer.h:212
bool waitingForClose
a conn must close before we open a standby conn
Definition: CachePeer.h:215
time_t connectTimeout() const
Definition: CachePeer.cc:118
Ip::Address addresses[10]
Definition: CachePeer.h:181
struct CachePeer::@34 standby
optional "cache_peer standby=limit" feature
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:159
Comm::Flag flag
comm layer result status.
Definition: CommCalls.h:82
Comm::ConnectionPointer conn
Definition: CommCalls.h:80
bool isOpen() const
Definition: Connection.h:101
time_t startTime() const
Definition: Connection.h:120
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
void finish()
Definition: JobWait.cc:44
void start(const JobPointer &aJob, const AsyncCall::Pointer &aCallback)
starts waiting for the given job to call the given callback
Definition: JobWait.h:69
void closeN(int n)
closes any n connections, regardless of their destination
Definition: pconn.cc:507
void count(int uses)
void push(const Comm::ConnectionPointer &serverConn, const char *domain)
Definition: pconn.cc:412
Maintains an fixed-size "standby" PconnPool for a single CachePeer.
Definition: PeerPoolMgr.h:23
JobWait< Security::BlindPeerConnector > encryptionWait
waits for the established transport connection to be secured/encrypted
Definition: PeerPoolMgr.h:69
void checkpoint(const char *reason)
Definition: PeerPoolMgr.cc:210
void handleSecuredPeer(Security::EncryptorAnswer &answer)
Security::PeerConnector callback.
Definition: PeerPoolMgr.cc:123
unsigned int addrUsed
counter for cycling through peer addresses
Definition: PeerPoolMgr.h:71
void openNewConnection()
starts the process of opening a new standby connection (if possible)
Definition: PeerPoolMgr.cc:156
void swanSong() override
Definition: PeerPoolMgr.cc:59
void start() override
called by AsyncStart; do not call directly
Definition: PeerPoolMgr.cc:45
~PeerPoolMgr() override
Definition: PeerPoolMgr.cc:39
RefCount< HttpRequest > request
fake HTTP request for conn opening code
Definition: PeerPoolMgr.h:63
void handleOpenedConnection(const CommConnectCbParams &params)
Comm::ConnOpener calls this when done opening a connection for us.
Definition: PeerPoolMgr.cc:77
void closeOldConnections(const int howMany)
closes 'howMany' standby connections
Definition: PeerPoolMgr.cc:203
static void Checkpoint(const Pointer &mgr, const char *reason)
Definition: PeerPoolMgr.cc:228
bool doneAll() const override
whether positive goal has been reached
Definition: PeerPoolMgr.cc:71
CachePeer * peer
the owner of the pool we manage
Definition: PeerPoolMgr.h:62
JobWait< Comm::ConnOpener > transportWait
waits for a transport connection to the peer to be established/opened
Definition: PeerPoolMgr.h:66
void pushNewConnection(const Comm::ConnectionPointer &conn)
the final step in connection opening (and, optionally, securing) sequence
Definition: PeerPoolMgr.cc:114
bool validPeer() const
whether the peer is still out there and in a valid state we can safely use
Definition: PeerPoolMgr.cc:65
PeerPoolMgr(CachePeer *aPeer)
Definition: PeerPoolMgr.cc:30
launches PeerPoolMgrs for peers configured with standby.limit
Definition: PeerPoolMgr.cc:235
void syncConfig() override
Definition: PeerPoolMgr.cc:245
void useConfig() override
Definition: PeerPoolMgr.cc:238
C * getRaw() const
Definition: RefCount.h:80
A simple PeerConnector for SSL/TLS cache_peers. No SslBump capabilities.
CbcPointer< ErrorState > error
problem details (nil on success)
Comm::ConnectionPointer conn
peer connection (secured on success)
bool tunneled
whether we spliced the connections instead of negotiating encryption
bool encryptTransport
whether transport encryption (TLS/SSL) is to be used on connections to the peer
Definition: PeerOptions.h:145
CachePeer * peers
Definition: SquidConfig.h:245
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
int fdUsageHigh(void)
Definition: fd.cc:271
#define fd_table
Definition: fde.h:189
int shutting_down
@ STANDBY_POOL
Definition: hier_code.h:37
@ PROTO_HTTP
Definition: ProtocolType.h:25
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
@ OK
Definition: Flag.h:16
@ scNone
Definition: StatusCode.h:21
@ METHOD_OPTIONS
Definition: MethodType.h:31
SSL Connection
Definition: Session.h:45
int neighborUp(const CachePeer *p)
Definition: neighbors.cc:1142
time_t positiveTimeout(const time_t timeout)
Definition: neighbors.cc:1177
bool peerCanOpenMore(const CachePeer *p)
Whether we can open new connections to the peer (e.g., despite max-conn)
Definition: neighbors.cc:224

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors