]> git.ipfire.org Git - thirdparty/squid.git/blob - src/FwdState.h
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / FwdState.h
1 /*
2 * Copyright (C) 1996-2020 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_FORWARD_H
10 #define SQUID_FORWARD_H
11
12 #include "base/CbcPointer.h"
13 #include "base/forward.h"
14 #include "base/RefCount.h"
15 #include "clients/forward.h"
16 #include "comm.h"
17 #include "comm/Connection.h"
18 #include "comm/ConnOpener.h"
19 #include "err_type.h"
20 #include "fde.h"
21 #include "http/StatusCode.h"
22 #include "ip/Address.h"
23 #include "PeerSelectState.h"
24 #include "security/forward.h"
25 #if USE_OPENSSL
26 #include "ssl/support.h"
27 #endif
28
29 /* forward decls */
30
31 class AccessLogEntry;
32 typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
33 class ErrorState;
34 class HttpRequest;
35 class PconnPool;
36 class ResolvedPeers;
37 typedef RefCount<ResolvedPeers> ResolvedPeersPointer;
38
39 class HappyConnOpener;
40 typedef CbcPointer<HappyConnOpener> HappyConnOpenerPointer;
41 class HappyConnOpenerAnswer;
42
43 #if USE_OPENSSL
44 namespace Ssl
45 {
46 class ErrorDetail;
47 class CertValidationResponse;
48 };
49 #endif
50
51 /// Sets initial TOS value and Netfilter for the future outgoing connection.
52 /// Updates the given Connection object, not the future transport connection.
53 void GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn);
54
55 /// Recomputes and applies TOS value and Netfilter to the outgoing connection.
56 /// Updates both the given Connection object and the transport connection.
57 void ResetMarkingsToServer(HttpRequest *, Comm::Connection &);
58
59 class HelperReply;
60
61 class FwdState: public RefCountable, public PeerSelectionInitiator
62 {
63 CBDATA_CHILD(FwdState);
64
65 public:
66 typedef RefCount<FwdState> Pointer;
67 virtual ~FwdState();
68 static void initModule();
69
70 /// Initiates request forwarding to a peer or origin server.
71 static void Start(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *, const AccessLogEntryPointer &alp);
72 /// Same as Start() but no master xaction info (AccessLogEntry) available.
73 static void fwdStart(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *);
74 /// time left to finish the whole forwarding process (which started at fwdStart)
75 static time_t ForwardTimeout(const time_t fwdStart);
76 /// Whether there is still time to re-try after a previous connection failure.
77 /// \param fwdStart The start time of the peer selection/connection process.
78 static bool EnoughTimeToReForward(const time_t fwdStart);
79
80 /// This is the real beginning of server connection. Call it whenever
81 /// the forwarding server destination has changed and a new one needs to be opened.
82 /// Produces the cannot-forward error on fail if no better error exists.
83 void useDestinations();
84
85 void fail(ErrorState *err);
86 void unregister(Comm::ConnectionPointer &conn);
87 void unregister(int fd);
88 void complete();
89 void handleUnregisteredServerEnd();
90 int reforward();
91 bool reforwardableStatus(const Http::StatusCode s) const;
92 void serverClosed(int fd);
93 void connectStart();
94 void connectDone(const Comm::ConnectionPointer & conn, Comm::Flag status, int xerrno);
95 bool checkRetry();
96 bool checkRetriable();
97 void dispatch();
98
99 void pconnPush(Comm::ConnectionPointer & conn, const char *domain);
100
101 bool dontRetry() { return flags.dont_retry; }
102
103 void dontRetry(bool val) { flags.dont_retry = val; }
104
105 /** return a ConnectionPointer to the current server connection (may or may not be open) */
106 Comm::ConnectionPointer const & serverConnection() const { return serverConn; };
107
108 private:
109 // hidden for safer management of self; use static fwdStart
110 FwdState(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *, const AccessLogEntryPointer &alp);
111 void start(Pointer aSelf);
112 void stopAndDestroy(const char *reason);
113
114 /* PeerSelectionInitiator API */
115 virtual void noteDestination(Comm::ConnectionPointer conn) override;
116 virtual void noteDestinationsEnd(ErrorState *selectionError) override;
117
118 void noteConnection(HappyConnOpenerAnswer &);
119
120 #if STRICT_ORIGINAL_DST
121 void selectPeerForIntercepted();
122 #endif
123 static void logReplyStatus(int tries, const Http::StatusCode status);
124 void doneWithRetries();
125 void completed();
126 void retryOrBail();
127
128 void usePinned();
129
130 /// whether a pinned to-peer connection can be replaced with another one
131 /// (in order to retry or reforward a failed request)
132 bool pinnedCanRetry() const;
133
134 ErrorState *makeConnectingError(const err_type type) const;
135 void connectedToPeer(Security::EncryptorAnswer &answer);
136 static void RegisterWithCacheManager(void);
137
138 void establishTunnelThruProxy();
139 void tunnelEstablishmentDone(Http::TunnelerAnswer &answer);
140 void secureConnectionToPeerIfNeeded();
141 void successfullyConnectedToPeer();
142
143 /// stops monitoring server connection for closure and updates pconn stats
144 void closeServerConnection(const char *reason);
145
146 void syncWithServerConn(const Comm::ConnectionPointer &server, const char *host, const bool reused);
147 void syncHierNote(const Comm::ConnectionPointer &server, const char *host);
148
149 /// whether we have used up all permitted forwarding attempts
150 bool exhaustedTries() const;
151
152 /// \returns the time left for this connection to become connected or 1 second if it is less than one second left
153 time_t connectingTimeout(const Comm::ConnectionPointer &conn) const;
154
155 /// whether we are waiting for HappyConnOpener
156 /// same as calls.connector but may differ from connOpener.valid()
157 bool opening() const { return connOpener.set(); }
158
159 void cancelOpening(const char *reason);
160
161 void notifyConnOpener();
162
163 public:
164 StoreEntry *entry;
165 HttpRequest *request;
166 AccessLogEntryPointer al; ///< info for the future access.log entry
167
168 static void abort(void*);
169
170 private:
171 Pointer self;
172 ErrorState *err;
173 Comm::ConnectionPointer clientConn; ///< a possibly open connection to the client.
174 time_t start_t;
175 int n_tries; ///< the number of forwarding attempts so far
176
177 // AsyncCalls which we set and may need cancelling.
178 struct {
179 AsyncCall::Pointer connector; ///< a call linking us to the ConnOpener producing serverConn.
180 } calls;
181
182 struct {
183 bool connected_okay; ///< TCP link ever opened properly. This affects retry of POST,PUT,CONNECT,etc
184 bool dont_retry;
185 bool forward_completed;
186 bool destinationsFound; ///< at least one candidate path found
187 } flags;
188
189 HappyConnOpenerPointer connOpener; ///< current connection opening job
190 ResolvedPeersPointer destinations; ///< paths for forwarding the request
191 Comm::ConnectionPointer serverConn; ///< a successfully opened connection to a server.
192
193 AsyncCall::Pointer closeHandler; ///< The serverConn close handler
194
195 /// possible pconn race states
196 typedef enum { raceImpossible, racePossible, raceHappened } PconnRace;
197 PconnRace pconnRace; ///< current pconn race state
198 };
199
200 void getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn);
201
202 /// a collection of previously used persistent Squid-to-peer HTTP(S) connections
203 extern PconnPool *fwdPconnPool;
204
205 #endif /* SQUID_FORWARD_H */
206