]> git.ipfire.org Git - thirdparty/squid.git/blame - src/FwdState.h
Simplify appending SBuf to String (#2108)
[thirdparty/squid.git] / src / FwdState.h
CommitLineData
bbc27441 1/*
1f7b830e 2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
bbc27441
AJ
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_FWDSTATE_H
10#define SQUID_SRC_FWDSTATE_H
3cd1350a 11
55622953 12#include "base/forward.h"
2b6b1bcb 13#include "base/JobWait.h"
a70e75b7 14#include "base/RefCount.h"
f5e17947 15#include "clients/forward.h"
582c2af2
FC
16#include "comm.h"
17#include "comm/Connection.h"
83b053a0 18#include "error/forward.h"
582c2af2 19#include "fde.h"
955394ce 20#include "http/StatusCode.h"
582c2af2 21#include "ip/Address.h"
8b082ed9 22#include "ip/forward.h"
6043e368 23#include "PeerSelectState.h"
9b7992d9 24#include "ResolvedPeers.h"
fcfdf7f9 25#include "security/forward.h"
cb4f4424 26#if USE_OPENSSL
268a2e8f
CT
27#include "ssl/support.h"
28#endif
582c2af2 29
62ee09ca 30/* forward decls */
31
4bf68cfa
AR
32class AccessLogEntry;
33typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
06093389 34class HttpRequest;
55622953
CT
35class PconnPool;
36class ResolvedPeers;
37typedef RefCount<ResolvedPeers> ResolvedPeersPointer;
38
39class HappyConnOpener;
55622953 40class HappyConnOpenerAnswer;
62ee09ca 41
6ee88490 42/// Sets initial TOS value and Netfilter for the future outgoing connection.
55622953 43/// Updates the given Connection object, not the future transport connection.
6ee88490
CT
44void GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn);
45
55622953
CT
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
4a77bb4e
CT
50class HelperReply;
51
5673f482
AR
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
6043e368 86class FwdState: public RefCountable, public PeerSelectionInitiator
3cd1350a 87{
6043e368 88 CBDATA_CHILD(FwdState);
5c2f68b7 89
3cd1350a 90public:
91 typedef RefCount<FwdState> Pointer;
337b9aa4 92 ~FwdState() override;
3cd1350a 93 static void initModule();
94
4bf68cfa
AR
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.
be364179 98 static void fwdStart(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *);
0ce8e93b
EB
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);
8652f8e7
AJ
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.
3dde9e52 108 void useDestinations();
8652f8e7 109
3cd1350a 110 void fail(ErrorState *err);
00ae51e4 111 void unregister(Comm::ConnectionPointer &conn);
3cd1350a 112 void unregister(int fd);
113 void complete();
ba3fe8d9
EB
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
3e8c047e 119 void handleUnregisteredServerEnd();
3cd1350a 120 int reforward();
2b6b1bcb 121 void serverClosed();
3cd1350a 122 void connectStart();
c8407295 123 void connectDone(const Comm::ConnectionPointer & conn, Comm::Flag status, int xerrno);
3cd1350a 124 bool checkRetry();
125 bool checkRetriable();
126 void dispatch();
55622953 127
642a305c 128 void pconnPush(Comm::ConnectionPointer & conn, const char *domain);
3cd1350a 129
130 bool dontRetry() { return flags.dont_retry; }
131
132 void dontRetry(bool val) { flags.dont_retry = val; }
133
25b0ce45
CT
134 /// get rid of a to-server connection that failed to become serverConn
135 void closePendingConnection(const Comm::ConnectionPointer &conn, const char *reason);
136
5229395c 137 /** return a ConnectionPointer to the current server connection (may or may not be open) */
00ae51e4 138 Comm::ConnectionPointer const & serverConnection() const { return serverConn; };
5229395c 139
3cd1350a 140private:
7a0fb323 141 // hidden for safer management of self; use static fwdStart
4bf68cfa 142 FwdState(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *, const AccessLogEntryPointer &alp);
7a0fb323 143 void start(Pointer aSelf);
6043e368
AR
144 void stopAndDestroy(const char *reason);
145
146 /* PeerSelectionInitiator API */
337b9aa4
AR
147 void noteDestination(Comm::ConnectionPointer conn) override;
148 void noteDestinationsEnd(ErrorState *selectionError) override;
15bde30c
AR
149
150 bool transporting() const;
7a0fb323 151
55622953
CT
152 void noteConnection(HappyConnOpenerAnswer &);
153
32c32865 154#if STRICT_ORIGINAL_DST
7c75511b 155 void selectPeerForIntercepted();
32c32865 156#endif
955394ce 157 static void logReplyStatus(int tries, const Http::StatusCode status);
9d2760b6 158 void doneWithRetries();
802a8c1d 159 void completed();
3e8c047e 160 void retryOrBail();
3dde9e52
CT
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
25b0ce45
CT
168 template <typename StepStart>
169 void advanceDestination(const char *stepDescription, const Comm::ConnectionPointer &conn, const StepStart &startStep);
170
2ac4f6b5 171 ErrorState *makeConnectingError(const err_type type) const;
fcfdf7f9 172 void connectedToPeer(Security::EncryptorAnswer &answer);
6852be71 173 static void RegisterWithCacheManager(void);
3cd1350a 174
25b0ce45 175 void establishTunnelThruProxy(const Comm::ConnectionPointer &);
f5e17947 176 void tunnelEstablishmentDone(Http::TunnelerAnswer &answer);
25b0ce45
CT
177 void secureConnectionToPeerIfNeeded(const Comm::ConnectionPointer &);
178 void secureConnectionToPeer(const Comm::ConnectionPointer &);
179 void successfullyConnectedToPeer(const Comm::ConnectionPointer &);
f5e17947 180
e8dca475
CT
181 /// stops monitoring server connection for closure and updates pconn stats
182 void closeServerConnection(const char *reason);
183
55622953 184 void syncWithServerConn(const Comm::ConnectionPointer &server, const char *host, const bool reused);
7d1dac79 185 void syncHierNote(const Comm::ConnectionPointer &server, const char *host);
4b77ea6b 186
3eebd267
EB
187 /// whether we have used up all permitted forwarding attempts
188 bool exhaustedTries() const;
e7a9b7a8 189 void updateAttempts(int);
3eebd267 190
f5e17947
CT
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
2b6b1bcb 194 void cancelStep(const char *reason);
55622953
CT
195
196 void notifyConnOpener();
2b6b1bcb 197 void reactToZeroSizeObject();
55622953 198
ba3fe8d9
EB
199 void updateAleWithFinalError();
200
3cd1350a 201public:
202 StoreEntry *entry;
203 HttpRequest *request;
4bf68cfa
AR
204 AccessLogEntryPointer al; ///< info for the future access.log entry
205
7e9f330d
EB
206 /// called by Store if the entry is no longer usable
207 static void HandleStoreAbort(FwdState *);
3cd1350a 208
209private:
3cd1350a 210 Pointer self;
211 ErrorState *err;
5c336a3b 212 Comm::ConnectionPointer clientConn; ///< a possibly open connection to the client.
3cd1350a 213 time_t start_t;
3eebd267 214 int n_tries; ///< the number of forwarding attempts so far
3cd1350a 215
26ac0430 216 struct {
e857372a
FC
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;
55622953 220 bool destinationsFound; ///< at least one candidate path found
2fadd50d 221 } flags;
3cd1350a 222
2b6b1bcb
AR
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
15bde30c
AR
233 /// whether we are waiting for the last dispatch()ed activity to end
234 bool waitingForDispatched;
235
55622953 236 ResolvedPeersPointer destinations; ///< paths for forwarding the request
00ae51e4 237 Comm::ConnectionPointer serverConn; ///< a successfully opened connection to a server.
9b7992d9 238 PeerConnectionPointer destinationReceipt; ///< peer selection result (or nil)
d2bf2f90 239
398bc066
CT
240 AsyncCall::Pointer closeHandler; ///< The serverConn close handler
241
bc81ee68
AR
242 /// possible pconn race states
243 typedef enum { raceImpossible, racePossible, raceHappened } PconnRace;
244 PconnRace pconnRace; ///< current pconn race state
ba3fe8d9
EB
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_;
5673f482
AR
249
250 /// Measures time spent on selecting and communicating with peers.
251 PeeringActivityTimer peeringTimer;
3cd1350a 252};
2087dca6 253
8b082ed9
FC
254class acl_tos;
255tos_t aclMapTOS(acl_tos *, ACLChecklist *);
256
257Ip::NfMarkConfig aclFindNfMarkConfig(acl_nfmark *, ACLChecklist *);
258void getOutgoingAddress(HttpRequest *, const Comm::ConnectionPointer &);
28618087 259
55622953
CT
260/// a collection of previously used persistent Squid-to-peer HTTP(S) connections
261extern PconnPool *fwdPconnPool;
262
ff9d9458 263#endif /* SQUID_SRC_FWDSTATE_H */
f53969cc 264