75#define MAX_FWD_STATS_IDX 9
90 debugs(17, 7,
"store entry aborted; no connection to close");
98 debugs(17, 3,
"because " << reason <<
"; " << conn);
101 if (IsConnOpen(conn)) {
128 waitingForDispatched(false),
130 pconnRace(raceImpossible),
131 storedWholeReply_(nullptr),
134 debugs(17, 2,
"Forwarding client request " << client <<
", url=" << e->
url());
137 flags.connected_okay =
false;
138 flags.dont_retry =
false;
139 flags.forward_completed =
false;
140 flags.destinationsFound =
false;
141 debugs(17, 3,
"FwdState constructed, this=" <<
this);
166#if STRICT_ORIGINAL_DST
172 if (isIntercepted && useOriginalDst) {
173 selectPeerForIntercepted();
186 debugs(17, 3,
"for " << reason);
208#if STRICT_ORIGINAL_DST
211FwdState::selectPeerForIntercepted()
231 debugs(17, 3,
"using client original destination: " << *p);
258 if (
flags.forward_completed) {
259 debugs(17,
DBG_IMPORTANT,
"ERROR: FwdState::completed called on a completed request! Bad!");
263 flags.forward_completed =
true;
266 debugs(17, 3,
"entry aborted");
270#if URL_CHECKSUM_DEBUG
307 debugs(17, 3,
"FwdState destructor start");
309 if (!
flags.forward_completed)
329 debugs(17, 3,
"FwdState destructed, this=" <<
this);
373#if URL_CHECKSUM_DEBUG
386 debugs(17, 2,
"calling internalStart() due to request flag");
418 return (larger > smaller) ? (larger - smaller) : 0;
443 debugs(17, 4,
"wait for more destinations to try");
460 debugs(17, 3, errorState <<
"; was: " <<
err);
481 debugs(17, 5,
"pconn race happened");
490 pinned_connection->pinning.zeroReply =
true;
491 debugs(17, 4,
"zero reply on pinned connection");
530#if URL_CHECKSUM_DEBUG
541 debugs(17, 3,
"re-forwarding " << replyStatus <<
" " <<
entry->
url());
557 debugs(17, 3,
"server (FD closed) not re-forwarding status " << replyStatus);
589 flags.destinationsFound =
true;
621 if (!
flags.destinationsFound) {
622 if (selectionError) {
623 debugs(17, 3,
"Will abort forwarding because path selection has failed.");
625 fail(selectionError);
633 Must(!selectionError);
644 debugs(17, 7,
"keep transporting");
649 debugs(17, 7,
"no more destinations to try after " <<
n_tries <<
" failed attempts");
653 finalError->detailError(d);
697 debugs(17, 5,
"not retrying because of earlier abort");
717 if (
flags.dont_retry)
724 if (!
flags.connected_okay)
758 debugs(17, 3,
"prior uses: " << uses);
818template <
typename StepStart>
850 flags.dont_retry =
true;
892 const bool originWantsEncryptedTraffic =
896 if (originWantsEncryptedTraffic &&
897 !peer->options.originserver &&
898 !peer->secure.encryptTransport)
900 establishTunnelThruProxy(answer.conn);
916 tunneler->noteFwdPconnUse =
true;
948 static int occurrences = 0;
949 const auto level = (occurrences++ < 100) ?
DBG_IMPORTANT : 2;
950 debugs(17, level,
"ERROR: Early data after CONNECT response. " <<
952 "Closing " << answer.
conn);
971 const auto p = conn->
getPeer();
974 const bool userWillTlsToPeerForUs = p && p->options.originserver &&
976 const bool needTlsToPeer = peerWantsTls && !userWillTlsToPeerForUs;
984 if (needTlsToPeer || needTlsToOrigin || needsBump) {
1028 flags.dont_retry =
true;
1067 Must(IsConnOpen(conn));
1141 cs->setRetriable(retriable);
1152 debugs(17, 7,
"connection manager: " << connManager);
1175 if (connManager->pinnedAuth())
1179 const auto reused =
true;
1210 flags.connected_okay =
true;
1243 flags.dont_retry =
true;
1251 ++peer->stats.fetches;
1290 flags.dont_retry =
true;
1313 debugs(17, 3,
"entry aborted");
1319#if URL_CHECKSUM_DEBUG
1321 e->
mem_obj->checkUrlChecksum();
1327 debugs(17, 3,
"pinned connection; cannot retry");
1332 debugs(17, 3,
"No, ENTRY_FWD_HDR_WAIT isn't set");
1343 debugs(17, 3,
"No alternative forwarding paths left");
1348 debugs(17, 3,
"status " << s);
1474 return l->markConfig;
1493#if FOLLOW_X_FORWARDED_FOR && LINUX_NETFILTER
1522 if (conn->
remote.
isIPv4() != l->addr.isIPv4())
continue;
1526 conn->
local = l->addr;
1565 debugs(17, 3,
"from " << conn.
local <<
" tos " <<
int(conn.
tos) <<
" netfilter mark " << conn.
nfmark);
#define Assure(condition)
RefCount< AsyncCallT< Dialer > > asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
#define asyncCallback(dbgSection, dbgLevel, method, object)
UnaryCbdataDialer< Argument1 > cbdataDialer(typename UnaryCbdataDialer< Argument1 >::Handler *handler, Argument1 *arg1)
#define CallJobHere(debugSection, debugLevel, job, Class, method)
#define CallJobHere1(debugSection, debugLevel, job, Class, method, arg1)
void NoteOutgoingConnectionSuccess(CachePeer *const peer)
void CLCB(const CommCloseCbParams ¶ms)
ErrorDetail::Pointer MakeNamedErrorDetail(const char *name)
PconnPool * fwdPconnPool
a collection of previously used persistent Squid-to-peer HTTP(S) connections
static int FwdReplyCodes[MAX_FWD_STATS_IDX+1][Http::scInvalidHeader+1]
static nfmark_t GetNfmarkToServer(HttpRequest *request, Comm::Connection &conn)
void getOutgoingAddress(HttpRequest *request, const Comm::ConnectionPointer &conn)
Ip::NfMarkConfig aclFindNfMarkConfig(acl_nfmark *head, ACLChecklist *ch)
Checks for a netfilter mark value to apply depending on the ACL.
void ResetMarkingsToServer(HttpRequest *request, Comm::Connection &conn)
tos_t aclMapTOS(acl_tos *head, ACLChecklist *ch)
Checks for a TOS value to apply depending on the ACL.
void GetMarkingsToServer(HttpRequest *request, Comm::Connection &conn)
static tos_t GetTosToServer(HttpRequest *request, Comm::Connection &conn)
static time_t diffOrZero(const time_t larger, const time_t smaller)
#define MAX_FWD_STATS_IDX
static CLCB fwdServerClosedWrapper
PconnPool * fwdPconnPool
a collection of previously used persistent Squid-to-peer HTTP(S) connections
void getOutgoingAddress(HttpRequest *, const Comm::ConnectionPointer &)
void ResetMarkingsToServer(HttpRequest *, Comm::Connection &)
std::ostream & CurrentException(std::ostream &os)
prints active (i.e., thrown but not yet handled) exception
err_type FindDenyInfoPage(const Acl::Answer &answer, const bool redirect_allowed)
void error(char *format,...)
squidaio_request_t * head
static char server[MAXLINE]
#define CBDATA_CLASS_INIT(type)
Acl::Answer const & fastCheck()
const Acl::Answer & currentAnswer() const
AccessLogEntry::Pointer al
info for the future access.log, and external ACL
void syncAle(HttpRequest *adaptedRequest, const char *logUri) const override
assigns uninitialized adapted_request and url ALE components
class AccessLogEntry::CacheDetails cache
void updateError(const Error &)
sets (or updates the already stored) transaction error as needed
list of address-based ACLs.
AnyP::UriScheme const & getScheme() const
void host(const char *src)
void expectNoConsumption()
there will be no more setConsumer() calls
struct CachePeer::@20 options
Security::PeerOptions secure
security settings for peer connection
Cbc * valid() const
was set and is valid
void clear()
make pointer not set; does not invalidate cbdata
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
CachePeer * getPeer() const
time_t connectTimeout(const time_t fwdStart) const
parameters for the async notePinnedConnectionBecameIdle() call
void httpsPeeked(PinnedIdleContext pic)
called by FwdState when it is done bumping the server
static Comm::ConnectionPointer BorrowPinnedConnection(HttpRequest *, const AccessLogEntryPointer &)
virtual void notePeerConnection(Comm::ConnectionPointer)
called just before a FwdState-dispatched job starts using connection
ErrorDetail::Pointer detail
void detailError(const ErrorDetail::Pointer &dCode)
set error type-specific detail code
HttpRequestPointer request
void secureConnectionToPeerIfNeeded(const Comm::ConnectionPointer &)
handles an established TCP connection to peer (including origin servers)
Comm::ConnectionPointer clientConn
a possibly open connection to the client.
void reactToZeroSizeObject()
ERR_ZERO_SIZE_OBJECT requires special adjustments.
void handleUnregisteredServerEnd()
void noteDestinationsEnd(ErrorState *selectionError) override
void connectedToPeer(Security::EncryptorAnswer &answer)
called when all negotiations with the TLS-speaking peer have been completed
void successfullyConnectedToPeer(const Comm::ConnectionPointer &)
called when all negotiations with the peer have been completed
PconnRace pconnRace
current pconn race state
const char * storedWholeReply_
FwdState(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *, const AccessLogEntryPointer &alp)
JobWait< HappyConnOpener > transportWait
waits for a transport connection to the peer to be established/opened
JobWait< Http::Tunneler > peerWait
bool transporting() const
static void Start(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *, const AccessLogEntryPointer &alp)
Initiates request forwarding to a peer or origin server.
void noteDestination(Comm::ConnectionPointer conn) override
called when a new unique destination has been found
static void HandleStoreAbort(FwdState *)
called by Store if the entry is no longer usable
time_t connectingTimeout(const Comm::ConnectionPointer &conn) const
static bool EnoughTimeToReForward(const time_t fwdStart)
void closePendingConnection(const Comm::ConnectionPointer &conn, const char *reason)
get rid of a to-server connection that failed to become serverConn
PeeringActivityTimer peeringTimer
Measures time spent on selecting and communicating with peers.
void unregister(Comm::ConnectionPointer &conn)
void start(Pointer aSelf)
Comm::ConnectionPointer const & serverConnection() const
Comm::ConnectionPointer serverConn
a successfully opened connection to a server.
void fail(ErrorState *err)
static time_t ForwardTimeout(const time_t fwdStart)
time left to finish the whole forwarding process (which started at fwdStart)
void closeServerConnection(const char *reason)
stops monitoring server connection for closure and updates pconn stats
JobWait< Security::PeerConnector > encryptionWait
waits for the established transport connection to be secured/encrypted
void updateAttempts(int)
sets n_tries to the given value (while keeping ALE, if any, in sync)
void usePinned()
send request on an existing connection dedicated to the requesting client
void tunnelEstablishmentDone(Http::TunnelerAnswer &answer)
resumes operations after the (possibly failed) HTTP CONNECT exchange
int n_tries
the number of forwarding attempts so far
AsyncCall::Pointer closeHandler
The serverConn close handler.
static void logReplyStatus(int tries, const Http::StatusCode status)
static void RegisterWithCacheManager(void)
void updateAleWithFinalError()
updates ALE when we finalize the transaction error (if any)
bool exhaustedTries() const
whether we have used up all permitted forwarding attempts
void cancelStep(const char *reason)
struct FwdState::@52 flags
void establishTunnelThruProxy(const Comm::ConnectionPointer &)
void stopAndDestroy(const char *reason)
ends forwarding; relies on refcounting so the effect may not be immediate
bool checkRetriable()
Whether we may try sending this request again after a failure.
void syncWithServerConn(const Comm::ConnectionPointer &server, const char *host, const bool reused)
commits to using the given open to-peer connection
bool waitingForDispatched
whether we are waiting for the last dispatch()ed activity to end
void noteConnection(HappyConnOpenerAnswer &)
ResolvedPeersPointer destinations
paths for forwarding the request
void notifyConnOpener()
makes sure connection opener knows that the destinations have changed
void markStoredReplyAsWhole(const char *whyWeAreSure)
PeerConnectionPointer destinationReceipt
peer selection result (or nil)
void secureConnectionToPeer(const Comm::ConnectionPointer &)
encrypts an established TCP connection to peer (including origin servers)
static void fwdStart(const Comm::ConnectionPointer &client, StoreEntry *, HttpRequest *)
Same as Start() but no master xaction info (AccessLogEntry) available.
void syncHierNote(const Comm::ConnectionPointer &server, const char *host)
AccessLogEntryPointer al
info for the future access.log entry
bool pinnedCanRetry() const
void advanceDestination(const char *stepDescription, const Comm::ConnectionPointer &conn, const StepStart &startStep)
starts a preparation step for an established connection; retries on failures
Final result (an open connection or an error) sent to the job initiator.
bool reused
whether conn was open earlier, by/for somebody else
PeerConnectionPointer conn
CbcPointer< ErrorState > error
problem details (nil on success)
Stopwatch totalPeeringTime
cumulative time spent (so far) communicating with all peers (see %<tt)
void resetPeerNotes(const Comm::ConnectionPointer &server, const char *requestedHost)
bool isIdempotent() const
CbcPointer< ConnStateData > clientConnectionManager
void clearError()
clear error details, useful for retries/repeats
void prepForDirect()
get ready to be sent directly to an origin server, excluding originserver
void prepForPeering(const CachePeer &peer)
get ready to be sent to the given cache_peer, including originserver
Ip::Address indirect_client_addr
ConnStateData * pinnedConnection()
AnyP::Uri url
the request URI
BodyPipe::Pointer body_pipe
optional pipeline to receive message body
Http::StatusCode status() const
retrieve the status code for this status line
Comm::ConnectionPointer conn
SBuf leftovers
peer-generated bytes after a positive answer (or empty)
CbcPointer< ErrorState > squidError
problem details (or nil)
unsigned short port() const
a netfilter mark/mask pair
void cancel(const char *reason)
void start(const JobPointer &aJob, const AsyncCall::Pointer &aCallback)
starts waiting for the given job to call the given callback
DelayId mostBytesAllowed() const
HttpRequestPointer request
const HttpReply & baseReply() const
bool subscribed
whether noteDestination() and noteDestinationsEnd() calls are allowed
void startSelectingDestinations(HttpRequest *request, const AccessLogEntry::Pointer &ale, StoreEntry *entry)
void stop()
pauses timer if stop() has not been called
Stopwatch & timer()
managed Stopwatch object within HierarchyLogEntry
HttpRequestPointer request
the owner of managed HierarchyLogEntry
~PeeringActivityTimer()
pauses timer if stop() has not been called
PeeringActivityTimer(const HttpRequestPointer &)
resumes timer
bool interceptTproxy
Set for requests handled by a "tproxy" port.
bool ftpNative
carries a representation of an FTP command [received on ftp_port]
void reinstatePath(const PeerConnectionPointer &)
bool notificationPending
whether HappyConnOpener::noteCandidatesChange() is scheduled to fire
bool empty() const
whether we lack any known candidate paths
bool destinationsFinalized
whether all of the available candidate paths received from DNS
void addPath(const Comm::ConnectionPointer &)
add a candidate path to try after all the existing paths
size_type length() const
Returns the number of bytes stored in SBuf.
A PeerConnector for TLS cache_peers and origin servers. 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 noteFwdPconnUse
hack: whether the connection requires fwdPconnPool->noteUses()
bool encryptTransport
whether transport encryption (TLS/SSL) is to be used on connections to the peer
int tproxy_uses_indirect_client
struct SquidConfig::@77 Timeout
Acl::Address * outgoing_address
struct SquidConfig::@90 onoff
acl_access * serverPconnForNonretriable
struct SquidConfig::@91 accessList
A PeerConnector for HTTP origin servers. Capable of SslBumping.
void completeSuccessfully(const char *whyWeAreSureWeStoredTheWholeReply)
void unregisterAbortCallback(const char *reason)
void completeTruncated(const char *whyWeConsiderTheReplyTruncated)
int unlock(const char *context)
void lock(const char *context)
void registerAbortCallback(const AsyncCall::Pointer &)
notify the StoreEntry writer of a 3rd-party initiated StoreEntry abort
ping_status_t ping_status
store_status_t store_status
unsigned int nfConnmarkFromServer
AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *handler, void *data)
void comm_remove_close_handler(int fd, CLCB *handler, void *data)
#define debugs(SECTION, LEVEL, CONTENT)
#define EBIT_SET(flag, bit)
#define EBIT_TEST(flag, bit)
@ PING_WAITING
Sent ICP queries to peers and still awaiting responses.
void fatal_dump(const char *message)
void fd_note(int fd, const char *s)
void errorAppendEntry(StoreEntry *entry, ErrorState *err)
void whoisStart(FwdState *fwd)
void HTTPMSGUNLOCK(M *&a)
void HTTPMSGLOCK(Http::Message *a)
void httpStart(FwdState *fwd)
void internalStart(const Comm::ConnectionPointer &clientConn, HttpRequest *request, StoreEntry *entry, const AccessLogEntry::Pointer &ale)
bool IsConnOpen(const Comm::ConnectionPointer &conn)
void StartGateway(FwdState *const fwdState)
A new FTP Gateway job.
void StartRelay(FwdState *const fwdState)
A new FTP Relay job.
@ scInvalidHeader
Squid header parsing error.
bool IsReforwardableStatus(StatusCode)
whether to send the request to another peer based on the current response status code
void getTosFromServer(const Comm::ConnectionPointer &server, fde *clientFde)
@ dirOpened
opened (by Squid to an origin server or peer)
Config TheConfig
Globally available instance of Qos::Config.
int setSockTos(const Comm::ConnectionPointer &conn, tos_t tos)
int setSockNfmark(const Comm::ConnectionPointer &conn, nfmark_t mark)
nfmark_t getNfConnmark(const Comm::ConnectionPointer &conn, const ConnectionDirection connDir)
void RegisterAction(char const *action, char const *desc, OBJH *handler, Protected, Atomic, Format)
time_t positiveTimeout(const time_t timeout)
void netdbPingSite(const char *hostname)
void storeAppendPrintf(StoreEntry *e, const char *fmt,...)
int storePendingNClients(const StoreEntry *e)
struct squidaio_request_t * next
void urnStart(HttpRequest *r, StoreEntry *e, const AccessLogEntryPointer &ale)