]> git.ipfire.org Git - thirdparty/squid.git/blame_incremental - src/FwdState.h
Simplify appending SBuf to String (#2108)
[thirdparty/squid.git] / src / FwdState.h
... / ...
CommitLineData
1/*
2 * Copyright (C) 1996-2025 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#ifndef SQUID_SRC_FWDSTATE_H
10#define SQUID_SRC_FWDSTATE_H
11
12#include "base/forward.h"
13#include "base/JobWait.h"
14#include "base/RefCount.h"
15#include "clients/forward.h"
16#include "comm.h"
17#include "comm/Connection.h"
18#include "error/forward.h"
19#include "fde.h"
20#include "http/StatusCode.h"
21#include "ip/Address.h"
22#include "ip/forward.h"
23#include "PeerSelectState.h"
24#include "ResolvedPeers.h"
25#include "security/forward.h"
26#if USE_OPENSSL
27#include "ssl/support.h"
28#endif
29
30/* forward decls */
31
32class AccessLogEntry;
33typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
34class HttpRequest;
35class PconnPool;
36class ResolvedPeers;
37typedef RefCount<ResolvedPeers> ResolvedPeersPointer;
38
39class HappyConnOpener;
40class HappyConnOpenerAnswer;
41
42/// Sets initial TOS value and Netfilter for the future outgoing connection.
43/// Updates the given Connection object, not the future transport connection.
44void GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn);
45
46/// Recomputes and applies TOS value and Netfilter to the outgoing connection.
47/// Updates both the given Connection object and the transport connection.
48void ResetMarkingsToServer(HttpRequest *, Comm::Connection &);
49
50class HelperReply;
51
52/// Eliminates excessive Stopwatch pause() calls in a task with multiple code
53/// locations that pause a stopwatch. Ideally, there would be just one such
54/// location (e.g., a task class destructor), but current code idiosyncrasies
55/// necessitate this state. For simplicity sake, this class currently manages a
56/// Stopwatch at a hard-coded location: HttpRequest::hier.totalPeeringTime.
57class PeeringActivityTimer
58{
59public:
60 PeeringActivityTimer(const HttpRequestPointer &); ///< resumes timer
61 ~PeeringActivityTimer(); ///< \copydoc stop()
62
63 /// pauses timer if stop() has not been called
64 void stop()
65 {
66 if (!stopped) {
67 timer().pause();
68 stopped = true;
69 }
70 }
71
72private:
73 /// managed Stopwatch object within HierarchyLogEntry
74 Stopwatch &timer();
75
76 /// the owner of managed HierarchyLogEntry
77 HttpRequestPointer request;
78
79 // We cannot rely on timer().ran(): This class eliminates excessive calls
80 // within a single task (e.g., an AsyncJob) while the timer (and its ran()
81 // state) may be shared/affected by multiple concurrent tasks.
82 /// Whether the task is done participating in the managed activity.
83 bool stopped = false;
84};
85
86class FwdState: public RefCountable, public PeerSelectionInitiator
87{
88 CBDATA_CHILD(FwdState);
89
90public:
91 typedef RefCount<FwdState> Pointer;
92 ~FwdState() override;
93 static void initModule();
94
95 /// Initiates request forwarding to a peer or origin server.
96 static void Start(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *, const AccessLogEntryPointer &alp);
97 /// Same as Start() but no master xaction info (AccessLogEntry) available.
98 static void fwdStart(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *);
99 /// time left to finish the whole forwarding process (which started at fwdStart)
100 static time_t ForwardTimeout(const time_t fwdStart);
101 /// Whether there is still time to re-try after a previous connection failure.
102 /// \param fwdStart The start time of the peer selection/connection process.
103 static bool EnoughTimeToReForward(const time_t fwdStart);
104
105 /// This is the real beginning of server connection. Call it whenever
106 /// the forwarding server destination has changed and a new one needs to be opened.
107 /// Produces the cannot-forward error on fail if no better error exists.
108 void useDestinations();
109
110 void fail(ErrorState *err);
111 void unregister(Comm::ConnectionPointer &conn);
112 void unregister(int fd);
113 void complete();
114
115 /// Mark reply as written to Store in its entirety, including the header and
116 /// any body. If the reply has a body, the entire body has to be stored.
117 void markStoredReplyAsWhole(const char *whyWeAreSure);
118
119 void handleUnregisteredServerEnd();
120 int reforward();
121 void serverClosed();
122 void connectStart();
123 void connectDone(const Comm::ConnectionPointer & conn, Comm::Flag status, int xerrno);
124 bool checkRetry();
125 bool checkRetriable();
126 void dispatch();
127
128 void pconnPush(Comm::ConnectionPointer & conn, const char *domain);
129
130 bool dontRetry() { return flags.dont_retry; }
131
132 void dontRetry(bool val) { flags.dont_retry = val; }
133
134 /// get rid of a to-server connection that failed to become serverConn
135 void closePendingConnection(const Comm::ConnectionPointer &conn, const char *reason);
136
137 /** return a ConnectionPointer to the current server connection (may or may not be open) */
138 Comm::ConnectionPointer const & serverConnection() const { return serverConn; };
139
140private:
141 // hidden for safer management of self; use static fwdStart
142 FwdState(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *, const AccessLogEntryPointer &alp);
143 void start(Pointer aSelf);
144 void stopAndDestroy(const char *reason);
145
146 /* PeerSelectionInitiator API */
147 void noteDestination(Comm::ConnectionPointer conn) override;
148 void noteDestinationsEnd(ErrorState *selectionError) override;
149
150 bool transporting() const;
151
152 void noteConnection(HappyConnOpenerAnswer &);
153
154#if STRICT_ORIGINAL_DST
155 void selectPeerForIntercepted();
156#endif
157 static void logReplyStatus(int tries, const Http::StatusCode status);
158 void doneWithRetries();
159 void completed();
160 void retryOrBail();
161
162 void usePinned();
163
164 /// whether a pinned to-peer connection can be replaced with another one
165 /// (in order to retry or reforward a failed request)
166 bool pinnedCanRetry() const;
167
168 template <typename StepStart>
169 void advanceDestination(const char *stepDescription, const Comm::ConnectionPointer &conn, const StepStart &startStep);
170
171 ErrorState *makeConnectingError(const err_type type) const;
172 void connectedToPeer(Security::EncryptorAnswer &answer);
173 static void RegisterWithCacheManager(void);
174
175 void establishTunnelThruProxy(const Comm::ConnectionPointer &);
176 void tunnelEstablishmentDone(Http::TunnelerAnswer &answer);
177 void secureConnectionToPeerIfNeeded(const Comm::ConnectionPointer &);
178 void secureConnectionToPeer(const Comm::ConnectionPointer &);
179 void successfullyConnectedToPeer(const Comm::ConnectionPointer &);
180
181 /// stops monitoring server connection for closure and updates pconn stats
182 void closeServerConnection(const char *reason);
183
184 void syncWithServerConn(const Comm::ConnectionPointer &server, const char *host, const bool reused);
185 void syncHierNote(const Comm::ConnectionPointer &server, const char *host);
186
187 /// whether we have used up all permitted forwarding attempts
188 bool exhaustedTries() const;
189 void updateAttempts(int);
190
191 /// \returns the time left for this connection to become connected or 1 second if it is less than one second left
192 time_t connectingTimeout(const Comm::ConnectionPointer &conn) const;
193
194 void cancelStep(const char *reason);
195
196 void notifyConnOpener();
197 void reactToZeroSizeObject();
198
199 void updateAleWithFinalError();
200
201public:
202 StoreEntry *entry;
203 HttpRequest *request;
204 AccessLogEntryPointer al; ///< info for the future access.log entry
205
206 /// called by Store if the entry is no longer usable
207 static void HandleStoreAbort(FwdState *);
208
209private:
210 Pointer self;
211 ErrorState *err;
212 Comm::ConnectionPointer clientConn; ///< a possibly open connection to the client.
213 time_t start_t;
214 int n_tries; ///< the number of forwarding attempts so far
215
216 struct {
217 bool connected_okay; ///< TCP link ever opened properly. This affects retry of POST,PUT,CONNECT,etc
218 bool dont_retry;
219 bool forward_completed;
220 bool destinationsFound; ///< at least one candidate path found
221 } flags;
222
223 /// waits for a transport connection to the peer to be established/opened
224 JobWait<HappyConnOpener> transportWait;
225
226 /// waits for the established transport connection to be secured/encrypted
227 JobWait<Security::PeerConnector> encryptionWait;
228
229 /// waits for an HTTP CONNECT tunnel through a cache_peer to be negotiated
230 /// over the (encrypted, if needed) transport connection to that cache_peer
231 JobWait<Http::Tunneler> peerWait;
232
233 /// whether we are waiting for the last dispatch()ed activity to end
234 bool waitingForDispatched;
235
236 ResolvedPeersPointer destinations; ///< paths for forwarding the request
237 Comm::ConnectionPointer serverConn; ///< a successfully opened connection to a server.
238 PeerConnectionPointer destinationReceipt; ///< peer selection result (or nil)
239
240 AsyncCall::Pointer closeHandler; ///< The serverConn close handler
241
242 /// possible pconn race states
243 typedef enum { raceImpossible, racePossible, raceHappened } PconnRace;
244 PconnRace pconnRace; ///< current pconn race state
245
246 /// Whether the entire reply (including any body) was written to Store.
247 /// The string literal value is only used for debugging.
248 const char *storedWholeReply_;
249
250 /// Measures time spent on selecting and communicating with peers.
251 PeeringActivityTimer peeringTimer;
252};
253
254class acl_tos;
255tos_t aclMapTOS(acl_tos *, ACLChecklist *);
256
257Ip::NfMarkConfig aclFindNfMarkConfig(acl_nfmark *, ACLChecklist *);
258void getOutgoingAddress(HttpRequest *, const Comm::ConnectionPointer &);
259
260/// a collection of previously used persistent Squid-to-peer HTTP(S) connections
261extern PconnPool *fwdPconnPool;
262
263#endif /* SQUID_SRC_FWDSTATE_H */
264