2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_FORWARD_H
10 #define SQUID_FORWARD_H
12 #include "base/CbcPointer.h"
13 #include "base/forward.h"
14 #include "base/RefCount.h"
15 #include "clients/forward.h"
17 #include "comm/Connection.h"
18 #include "comm/ConnOpener.h"
19 #include "error/forward.h"
21 #include "http/StatusCode.h"
22 #include "ip/Address.h"
23 #include "PeerSelectState.h"
24 #include "ResolvedPeers.h"
25 #include "security/forward.h"
27 #include "ssl/support.h"
33 typedef RefCount
<AccessLogEntry
> AccessLogEntryPointer
;
38 typedef RefCount
<ResolvedPeers
> ResolvedPeersPointer
;
40 class HappyConnOpener
;
41 typedef CbcPointer
<HappyConnOpener
> HappyConnOpenerPointer
;
42 class HappyConnOpenerAnswer
;
44 /// Sets initial TOS value and Netfilter for the future outgoing connection.
45 /// Updates the given Connection object, not the future transport connection.
46 void GetMarkingsToServer(HttpRequest
* request
, Comm::Connection
&conn
);
48 /// Recomputes and applies TOS value and Netfilter to the outgoing connection.
49 /// Updates both the given Connection object and the transport connection.
50 void ResetMarkingsToServer(HttpRequest
*, Comm::Connection
&);
54 class FwdState
: public RefCountable
, public PeerSelectionInitiator
56 CBDATA_CHILD(FwdState
);
59 typedef RefCount
<FwdState
> Pointer
;
61 static void initModule();
63 /// Initiates request forwarding to a peer or origin server.
64 static void Start(const Comm::ConnectionPointer
&client
, StoreEntry
*, HttpRequest
*, const AccessLogEntryPointer
&alp
);
65 /// Same as Start() but no master xaction info (AccessLogEntry) available.
66 static void fwdStart(const Comm::ConnectionPointer
&client
, StoreEntry
*, HttpRequest
*);
67 /// time left to finish the whole forwarding process (which started at fwdStart)
68 static time_t ForwardTimeout(const time_t fwdStart
);
69 /// Whether there is still time to re-try after a previous connection failure.
70 /// \param fwdStart The start time of the peer selection/connection process.
71 static bool EnoughTimeToReForward(const time_t fwdStart
);
73 /// This is the real beginning of server connection. Call it whenever
74 /// the forwarding server destination has changed and a new one needs to be opened.
75 /// Produces the cannot-forward error on fail if no better error exists.
76 void useDestinations();
78 void fail(ErrorState
*err
);
79 void unregister(Comm::ConnectionPointer
&conn
);
80 void unregister(int fd
);
82 void handleUnregisteredServerEnd();
84 bool reforwardableStatus(const Http::StatusCode s
) const;
85 void serverClosed(int fd
);
87 void connectDone(const Comm::ConnectionPointer
& conn
, Comm::Flag status
, int xerrno
);
89 bool checkRetriable();
92 void pconnPush(Comm::ConnectionPointer
& conn
, const char *domain
);
94 bool dontRetry() { return flags
.dont_retry
; }
96 void dontRetry(bool val
) { flags
.dont_retry
= val
; }
98 /// get rid of a to-server connection that failed to become serverConn
99 void closePendingConnection(const Comm::ConnectionPointer
&conn
, const char *reason
);
101 /** return a ConnectionPointer to the current server connection (may or may not be open) */
102 Comm::ConnectionPointer
const & serverConnection() const { return serverConn
; };
105 // hidden for safer management of self; use static fwdStart
106 FwdState(const Comm::ConnectionPointer
&client
, StoreEntry
*, HttpRequest
*, const AccessLogEntryPointer
&alp
);
107 void start(Pointer aSelf
);
108 void stopAndDestroy(const char *reason
);
110 /* PeerSelectionInitiator API */
111 virtual void noteDestination(Comm::ConnectionPointer conn
) override
;
112 virtual void noteDestinationsEnd(ErrorState
*selectionError
) override
;
114 void noteConnection(HappyConnOpenerAnswer
&);
116 #if STRICT_ORIGINAL_DST
117 void selectPeerForIntercepted();
119 static void logReplyStatus(int tries
, const Http::StatusCode status
);
120 void doneWithRetries();
126 /// whether a pinned to-peer connection can be replaced with another one
127 /// (in order to retry or reforward a failed request)
128 bool pinnedCanRetry() const;
130 template <typename StepStart
>
131 void advanceDestination(const char *stepDescription
, const Comm::ConnectionPointer
&conn
, const StepStart
&startStep
);
133 ErrorState
*makeConnectingError(const err_type type
) const;
134 void connectedToPeer(Security::EncryptorAnswer
&answer
);
135 static void RegisterWithCacheManager(void);
137 void establishTunnelThruProxy(const Comm::ConnectionPointer
&);
138 void tunnelEstablishmentDone(Http::TunnelerAnswer
&answer
);
139 void secureConnectionToPeerIfNeeded(const Comm::ConnectionPointer
&);
140 void secureConnectionToPeer(const Comm::ConnectionPointer
&);
141 void successfullyConnectedToPeer(const Comm::ConnectionPointer
&);
143 /// stops monitoring server connection for closure and updates pconn stats
144 void closeServerConnection(const char *reason
);
146 void syncWithServerConn(const Comm::ConnectionPointer
&server
, const char *host
, const bool reused
);
147 void syncHierNote(const Comm::ConnectionPointer
&server
, const char *host
);
149 /// whether we have used up all permitted forwarding attempts
150 bool exhaustedTries() const;
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;
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(); }
159 void cancelOpening(const char *reason
);
161 void notifyConnOpener();
165 HttpRequest
*request
;
166 AccessLogEntryPointer al
; ///< info for the future access.log entry
168 /// called by Store if the entry is no longer usable
169 static void HandleStoreAbort(FwdState
*);
174 Comm::ConnectionPointer clientConn
; ///< a possibly open connection to the client.
176 int n_tries
; ///< the number of forwarding attempts so far
178 // AsyncCalls which we set and may need cancelling.
180 AsyncCall::Pointer connector
; ///< a call linking us to the ConnOpener producing serverConn.
184 bool connected_okay
; ///< TCP link ever opened properly. This affects retry of POST,PUT,CONNECT,etc
186 bool forward_completed
;
187 bool destinationsFound
; ///< at least one candidate path found
190 HappyConnOpenerPointer connOpener
; ///< current connection opening job
191 ResolvedPeersPointer destinations
; ///< paths for forwarding the request
192 Comm::ConnectionPointer serverConn
; ///< a successfully opened connection to a server.
193 PeerConnectionPointer destinationReceipt
; ///< peer selection result (or nil)
195 AsyncCall::Pointer closeHandler
; ///< The serverConn close handler
197 /// possible pconn race states
198 typedef enum { raceImpossible
, racePossible
, raceHappened
} PconnRace
;
199 PconnRace pconnRace
; ///< current pconn race state
202 void getOutgoingAddress(HttpRequest
* request
, const Comm::ConnectionPointer
&conn
);
204 /// a collection of previously used persistent Squid-to-peer HTTP(S) connections
205 extern PconnPool
*fwdPconnPool
;
207 #endif /* SQUID_FORWARD_H */