From 13413105a09f78d31d83d72c4d472624f507669f Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Feb 2019 17:18:59 +0300 Subject: [PATCH 01/66] HttpRequest: fetch addresses from master transaction's connection ... instead of using duplicated client_addr and my_addr fields. --- src/AccessLogEntry.cc | 2 +- src/DelayId.cc | 11 ++--- src/Downloader.cc | 12 +----- src/FwdState.cc | 11 ++--- src/HttpRequest.cc | 68 +++++++++++++++++++++++++++---- src/HttpRequest.h | 21 +++++++++- src/acl/FilledChecklist.cc | 9 +--- src/adaptation/ecap/XactionRep.cc | 8 +--- src/adaptation/icap/ModXact.cc | 9 +--- src/auth/digest/UserRequest.cc | 4 +- src/client_side_request.cc | 27 ++++-------- src/errorpage.cc | 2 +- src/format/Format.cc | 2 +- src/http.cc | 12 +++--- src/peer_select.cc | 2 +- src/peer_sourcehash.cc | 2 +- src/tunnel.cc | 6 +-- 17 files changed, 119 insertions(+), 89 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index 09de0a22c6c..2fdb80a0436 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -21,7 +21,7 @@ AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.log_uses_indirect_client && request) - log_ip = request->indirect_client_addr; + log_ip = request->indirectClientAddr(); else #endif if (tcpClient) diff --git a/src/DelayId.cc b/src/DelayId.cc index 2be80690509..cd7ff8b1fc6 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -71,7 +71,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) assert(http); r = http->request; - if (r->client_addr.isNoAddr()) { + if (r->clientAddr().isNoAddr()) { debugs(77, 2, "delayClient: WARNING: Called with 'NO_ADDR' address, ignoring"); return DelayId(); } @@ -90,13 +90,8 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) ch.reply = reply; HTTPMSGLOCK(reply); } -#if FOLLOW_X_FORWARDED_FOR - if (Config.onoff.delay_pool_uses_indirect_client) - ch.src_addr = r->indirect_client_addr; - else -#endif /* FOLLOW_X_FORWARDED_FOR */ - ch.src_addr = r->client_addr; - ch.my_addr = r->my_addr; + ch.src_addr = r->effectiveClientAddr(); + ch.my_addr = r->myAddr(); if (http->getConn() != NULL) ch.conn(http->getConn()); diff --git a/src/Downloader.cc b/src/Downloader.cc index 7f7a8d612d8..2da530661ce 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -130,20 +130,12 @@ Downloader::buildRequest() const MasterXaction::Pointer mx = new MasterXaction(initiator_); HttpRequest *const request = HttpRequest::FromUrl(url_.c_str(), mx, method); + if (!request) { debugs(33, 5, "Invalid URI: " << url_); return false; //earlyError(...) } - request->http_ver = Http::ProtocolVersion(); - request->header.putStr(Http::HdrType::HOST, request->url.host()); - request->header.putTime(Http::HdrType::DATE, squid_curtime); - request->client_addr.setNoAddr(); -#if FOLLOW_X_FORWARDED_FOR - request->indirect_client_addr.setNoAddr(); -#endif /* FOLLOW_X_FORWARDED_FOR */ - request->my_addr.setNoAddr(); /* undefined for internal requests */ - request->my_addr.port(0); - request->downloader = this; + request->setDownloader(this); debugs(11, 2, "HTTP Client Downloader " << this << "/" << id); debugs(11, 2, "HTTP Client REQUEST:\n---------\n" << diff --git a/src/FwdState.cc b/src/FwdState.cc index 301da5a4a65..f03f84745b5 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -315,7 +315,7 @@ FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, Ht * be allowed. yuck, I know. */ - if ( Config.accessList.miss && !request->client_addr.isNoAddr() && + if ( Config.accessList.miss && !request->clientAddr().isNoAddr() && !request->flags.internal && request->url.getScheme() != AnyP::PROTO_CACHE_OBJECT) { /** * Check if this host is allowed to fetch MISSES from us (miss_access). @@ -324,7 +324,7 @@ FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, Ht */ ACLFilledChecklist ch(Config.accessList.miss, request, NULL); ch.al = al; - ch.src_addr = request->client_addr; + ch.src_addr = request->clientAddr(); ch.syncAle(request, nullptr); if (ch.fastCheck().denied()) { err_type page_id; @@ -1357,12 +1357,7 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) // maybe use TPROXY client address if (request && request->flags.spoofClientIp) { if (!conn->getPeer() || !conn->getPeer()->options.no_tproxy) { -#if FOLLOW_X_FORWARDED_FOR && LINUX_NETFILTER - if (Config.onoff.tproxy_uses_indirect_client) - conn->local = request->indirect_client_addr; - else -#endif - conn->local = request->client_addr; + conn->local = request->effectiveClientAddr(); conn->local.port(0); // let OS pick the source port to prevent address clashes // some flags need setting on the socket to use this address conn->flags |= COMM_DOBIND; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 80f77768738..b39488c317b 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -85,8 +85,6 @@ HttpRequest::init() ims = -1; imslen = 0; lastmod = -1; - client_addr.setEmpty(); - my_addr.setEmpty(); body_pipe = NULL; // hier dnsWait = -1; @@ -116,6 +114,7 @@ HttpRequest::init() #endif rangeOffsetLimit = -2; //a value of -2 means not checked yet forcedBodyContinuation = false; + internal = false; } void @@ -218,11 +217,9 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) if (!aReq) return false; - client_addr = aReq->client_addr; #if FOLLOW_X_FORWARDED_FOR indirect_client_addr = aReq->indirect_client_addr; #endif - my_addr = aReq->my_addr; dnsWait = aReq->dnsWait; @@ -257,6 +254,9 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) theNotes = aReq->theNotes; sources = aReq->sources; + + internal = aReq->internal; + return true; } @@ -609,7 +609,7 @@ HttpRequest::getRangeOffsetLimit() rangeOffsetLimit = 0; // default value for rangeOffsetLimit ACLFilledChecklist ch(NULL, this, NULL); - ch.src_addr = client_addr; + ch.src_addr = clientAddr(); ch.my_addr = my_addr; for (AclSizeLimit *l = Config.rangeOffsetLimit; l; l = l -> next) { @@ -713,6 +713,62 @@ UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &he request.notes()->replaceOrAdd(&helperNotes); } +void +HttpRequest::setDownloader(Downloader *d) +{ + http_ver = Http::ProtocolVersion(); + header.putStr(Http::HdrType::HOST, url.host()); + header.putTime(Http::HdrType::DATE, squid_curtime); + downloader = d; + internal = true; +} + +const Ip::Address& +HttpRequest::effectiveClientAddr() const +{ +#if FOLLOW_X_FORWARDED_FOR && LINUX_NETFILTER + if (Config.onoff.tproxy_uses_indirect_client) + return indirectClientAddr(); + else +#endif + return clientAddr(); +} + +static const Ip::Address& +NoAddr() +{ + static Ip::Address addr; + addr.setNoAddr(); + return addr; +} + +const Ip::Address& +HttpRequest::clientAddr() const +{ + return internal ? NoAddr() : masterXaction->tcpClient->remote; +} + +const Ip::Address& +HttpRequest::myAddr() const +{ + return internal ? NoAddr() : masterXaction->tcpClient->local; +} + +#if FOLLOW_X_FORWARDED_FOR +const Ip::Address& +HttpRequest::indirectClientAddr() const +{ + return internal ? NoAddr() : indirect_client_addr; +} + +void +HttpRequest::resetIndirectClientAddr() +{ + indirect_client_addr = clientAddr(); + indirect_client_addr.port(0); +} +#endif /* FOLLOW_X_FORWARDED_FOR */ + void HttpRequest::manager(const CbcPointer &aMgr, const AccessLogEntryPointer &al) { @@ -728,13 +784,11 @@ HttpRequest::manager(const CbcPointer &aMgr, const AccessLogEntry } if (auto clientConnection = clientConnectionManager->clientConnection) { - client_addr = clientConnection->remote; // XXX: remove request->client_addr member. #if FOLLOW_X_FORWARDED_FOR // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) // not details about the TCP connection itself indirect_client_addr = clientConnection->remote; #endif /* FOLLOW_X_FORWARDED_FOR */ - my_addr = clientConnection->local; flags.intercepted = ((clientConnection->flags & COMM_INTERCEPTION) != 0); flags.interceptTproxy = ((clientConnection->flags & COMM_TRANSPARENT) != 0 ) ; diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 909a17ef642..5a10c97d1a8 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -140,8 +140,20 @@ class HttpRequest: public Http::Message Ip::Address client_addr; + void setInternal(const bool val) { internal = val; } + + void setDownloader(Downloader *); + + const Ip::Address& clientAddr() const; + + const Ip::Address& myAddr() const; + + const Ip::Address& effectiveClientAddr() const; + #if FOLLOW_X_FORWARDED_FOR - Ip::Address indirect_client_addr; + const Ip::Address& indirectClientAddr() const; + void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } + void resetIndirectClientAddr(); #endif /* FOLLOW_X_FORWARDED_FOR */ Ip::Address my_addr; @@ -251,6 +263,13 @@ class HttpRequest: public Http::Message /// annotations added by the note directive and helpers /// and(or) by annotate_transaction/annotate_client ACLs. NotePairs::Pointer theNotes; + +#if FOLLOW_X_FORWARDED_FOR + Ip::Address indirect_client_addr; +#endif /* FOLLOW_X_FORWARDED_FOR */ + + bool internal; + protected: virtual void packFirstLineInto(Packable * p, bool full_uri) const; diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index cc0c2b5ee15..24488b7cf96 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -245,13 +245,8 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) if (httpRequest) { request = httpRequest; HTTPMSGLOCK(request); -#if FOLLOW_X_FORWARDED_FOR - if (Config.onoff.acl_uses_indirect_client) - src_addr = request->indirect_client_addr; - else -#endif /* FOLLOW_X_FORWARDED_FOR */ - src_addr = request->client_addr; - my_addr = request->my_addr; + src_addr = request->effectiveClientAddr(); + my_addr = request->myAddr(); if (request->clientConnectionManager.valid()) conn(request->clientConnectionManager.get()); diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index 431b20b2afb..d4242d7c2cd 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -128,13 +128,7 @@ Adaptation::Ecap::XactionRep::clientIpValue() const // TODO: move this logic into HttpRequest::clientIp(bool) and // HttpRequest::clientIpString(bool) and reuse everywhere if (TheConfig.send_client_ip && request) { - Ip::Address client_addr; -#if FOLLOW_X_FORWARDED_FOR - if (TheConfig.use_indirect_client) { - client_addr = request->indirect_client_addr; - } else -#endif - client_addr = request->client_addr; + Ip::Address client_addr = request->effectiveClientAddr(); if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) { char ntoabuf[MAX_IPSTRLEN] = ""; client_addr.toStr(ntoabuf,MAX_IPSTRLEN); diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index 3a095a0bb29..23cf903593c 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1327,7 +1327,7 @@ void Adaptation::Icap::ModXact::finalizeLogInfo() const Adaptation::Icap::ServiceRep &s = service(); al.icap.reqMethod = s.cfg().method; - al.cache.caddr = virgin_request_->client_addr; + al.cache.caddr = virgin_request_->clientAddr(); al.request = virgin_request_; HTTPMSGLOCK(al.request); @@ -1473,12 +1473,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) if (TheConfig.send_client_ip && request) { Ip::Address client_addr; -#if FOLLOW_X_FORWARDED_FOR - if (TheConfig.use_indirect_client) { - client_addr = request->indirect_client_addr; - } else -#endif - client_addr = request->client_addr; + client_addr = request->effectiveClientAddr(); if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) buf.appendf("X-Client-IP: %s\r\n", client_addr.toStr(ntoabuf,MAX_IPSTRLEN)); } diff --git a/src/auth/digest/UserRequest.cc b/src/auth/digest/UserRequest.cc index 7aac1970486..fecdce689cb 100644 --- a/src/auth/digest/UserRequest.cc +++ b/src/auth/digest/UserRequest.cc @@ -155,13 +155,13 @@ Auth::Digest::UserRequest::authenticate(HttpRequest * request, ConnStateData *, seen_broken_client = 1; } - if (last_broken_addr != request->client_addr) { + if (last_broken_addr != request->clientAddr()) { debugs(29, DBG_IMPORTANT, "Digest POST bug detected from " << request->client_addr << " using '" << (useragent ? useragent : "-") << "'. Please upgrade browser. See Bug #630 for details."); - last_broken_addr = request->client_addr; + last_broken_addr = request->clientAddr(); } } } else { diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 07f0db61d83..2775ac92534 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -378,15 +378,7 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre /* Internally created requests cannot have bodies today */ request->content_length = 0; - request->client_addr.setNoAddr(); - -#if FOLLOW_X_FORWARDED_FOR - request->indirect_client_addr.setNoAddr(); -#endif /* FOLLOW_X_FORWARDED_FOR */ - - request->my_addr.setNoAddr(); /* undefined for internal requests */ - - request->my_addr.port(0); + request->setInternal(true); request->http_ver = Http::ProtocolVersion(); @@ -479,12 +471,12 @@ clientFollowXForwardedForCheck(allow_t answer, void *data) --l; asciiaddr = p+l; if ((addr = asciiaddr)) { - request->indirect_client_addr = addr; + request->indirectClientAddr(addr); request->x_forwarded_for_iterator.cut(l); calloutContext->acl_checklist = clientAclChecklistCreate(Config.accessList.followXFF, http); if (!Config.onoff.acl_uses_indirect_client) { /* override the default src_addr tested if we have to go deeper than one level into XFF */ - Filled(calloutContext->acl_checklist)->src_addr = request->indirect_client_addr; + Filled(calloutContext->acl_checklist)->src_addr = request->indirectClientAddr(); } calloutContext->acl_checklist->nonBlockingCheck(clientFollowXForwardedForCheck, data); return; @@ -497,15 +489,15 @@ clientFollowXForwardedForCheck(allow_t answer, void *data) * Ensure that the access log shows the indirect client * instead of the direct client. */ - http->al->cache.caddr = request->indirect_client_addr; + http->al->cache.caddr = request->indirectClientAddr(); if (ConnStateData *conn = http->getConn()) - conn->log_addr = request->indirect_client_addr; + conn->log_addr = request->indirectClientAddr(); } request->x_forwarded_for_iterator.clean(); request->flags.done_follow_x_forwarded_for = true; if (answer.conflicted()) { - debugs(28, DBG_CRITICAL, "ERROR: Processing X-Forwarded-For. Stopping at IP address: " << request->indirect_client_addr ); + debugs(28, DBG_CRITICAL, "ERROR: Processing X-Forwarded-For. Stopping at IP address: " << request->indirectClientAddr() ); } /* process actual access ACL as normal. */ @@ -687,8 +679,7 @@ ClientRequestContext::clientAccessCheck() http->request->header.has(Http::HdrType::X_FORWARDED_FOR)) { /* we always trust the direct client address for actual use */ - http->request->indirect_client_addr = http->request->client_addr; - http->request->indirect_client_addr.port(0); + http->request->resetIndirectClientAddr(); /* setup the XFF iterator for processing */ http->request->x_forwarded_for_iterator = http->request->header.getList(Http::HdrType::X_FORWARDED_FOR); @@ -1807,8 +1798,8 @@ ClientHttpRequest::doCallouts() if (getConn() && Comm::IsConnOpen(getConn()->clientConnection)) { ACLFilledChecklist ch(nullptr, request, nullptr); ch.al = calloutContext->http->al; - ch.src_addr = request->client_addr; - ch.my_addr = request->my_addr; + ch.src_addr = request->clientAddr(); + ch.my_addr = request->myAddr(); ch.syncAle(request, log_uri); if (!calloutContext->toClientMarkingDone) { diff --git a/src/errorpage.cc b/src/errorpage.cc index 1535f6387f8..b7cc7138dc3 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -567,7 +567,7 @@ ErrorState::ErrorState(err_type t, Http::StatusCode status, HttpRequest * req) : if (req) { request = req; - src_addr = req->client_addr; + src_addr = req->clientAddr(); } } diff --git a/src/format/Format.cc b/src/format/Format.cc index b0e79639c7f..dea2de4cc72 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -410,7 +410,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_CLIENT_PORT: if (al->request) { - outint = al->request->client_addr.port(); + outint = al->request->clientAddr().port(); doint = 1; } else if (al->tcpClient) { outint = al->tcpClient->remote.port(); diff --git a/src/http.cc b/src/http.cc index fecdaf2d69a..bef5f8e7a7d 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1461,7 +1461,7 @@ HttpStateData::processReplyBody() Ip::Address client_addr; // XXX: Remove as unused. Why was it added? if (request->flags.spoofClientIp) - client_addr = request->client_addr; + client_addr = request->clientAddr(); auto serverConnectionSaved = serverConnection; fwd->unregister(serverConnection); @@ -1833,10 +1833,10 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, if (strcmp(opt_forwarded_for, "on") == 0) { /** If set to ON - append client IP or 'unknown'. */ - if ( request->client_addr.isNoAddr() ) + if ( request->clientAddr().isNoAddr() ) strListAdd(&strFwd, "unknown", ','); else - strListAdd(&strFwd, request->client_addr.toStr(ntoabuf, MAX_IPSTRLEN), ','); + strListAdd(&strFwd, request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN), ','); } else if (strcmp(opt_forwarded_for, "off") == 0) { /** If set to OFF - append 'unknown'. */ strListAdd(&strFwd, "unknown", ','); @@ -1844,10 +1844,10 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, /** If set to TRANSPARENT - pass through unchanged. */ } else if (strcmp(opt_forwarded_for, "truncate") == 0) { /** If set to TRUNCATE - drop existing list and replace with client IP or 'unknown'. */ - if ( request->client_addr.isNoAddr() ) + if ( request->clientAddr().isNoAddr() ) strFwd = "unknown"; else - strFwd = request->client_addr.toStr(ntoabuf, MAX_IPSTRLEN); + strFwd = request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN); } if (strFwd.size() > 0) hdr_out->putStr(Http::HdrType::X_FORWARDED_FOR, strFwd.termedBuf()); @@ -2411,7 +2411,7 @@ HttpStateData::handleMoreRequestBodyAvailable() if (flags.headers_parsed && !flags.abuse_detected) { flags.abuse_detected = true; - debugs(11, DBG_IMPORTANT, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << request->client_addr << "' -> '" << entry->url() << "'" ); + debugs(11, DBG_IMPORTANT, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << request->clientAddr() << "' -> '" << entry->url() << "'" ); if (virginReply()->sline.status() == Http::scInvalidHeader) { closeServer(); diff --git a/src/peer_select.cc b/src/peer_select.cc index 298c785c6d6..b5d70a8a3a5 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -383,7 +383,7 @@ PeerSelector::noteIp(const Ip::Address &ip) // for TPROXY spoofing, we must skip unusable addresses if (request->flags.spoofClientIp && !(peer && peer->options.no_tproxy) ) { - if (ip.isIPv4() != request->client_addr.isIPv4()) + if (ip.isIPv4() != request->clientAddr().isIPv4()) return; // cannot spoof the client address on this link } diff --git a/src/peer_sourcehash.cc b/src/peer_sourcehash.cc index 852c8f4f490..bb75e1e0a84 100644 --- a/src/peer_sourcehash.cc +++ b/src/peer_sourcehash.cc @@ -161,7 +161,7 @@ peerSourceHashSelectParent(PeerSelector *ps) assert(ps); HttpRequest *request = ps->request; - key = request->client_addr.toStr(ntoabuf, sizeof(ntoabuf)); + key = request->clientAddr().toStr(ntoabuf, sizeof(ntoabuf)); /* calculate hash key */ debugs(39, 2, "peerSourceHashSelectParent: Calculating hash for " << key); diff --git a/src/tunnel.cc b/src/tunnel.cc index 5af4a5665d5..65c94fb03cc 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1101,15 +1101,15 @@ tunnelStart(ClientHttpRequest * http) * be allowed. yuck, I know. */ - if (Config.accessList.miss && !request->client_addr.isNoAddr()) { + if (Config.accessList.miss && !request->clientAddr().isNoAddr()) { /* * Check if this host is allowed to fetch MISSES from us (miss_access) * default is to allow. */ ACLFilledChecklist ch(Config.accessList.miss, request, NULL); ch.al = http->al; - ch.src_addr = request->client_addr; - ch.my_addr = request->my_addr; + ch.src_addr = request->clientAddr(); + ch.my_addr = request->myAddr(); ch.syncAle(request, http->log_uri); if (ch.fastCheck().denied()) { debugs(26, 4, HERE << "MISS access forbidden."); From da33d45232e795ca30dd634a6f0840b61639f6df Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Feb 2019 17:22:34 +0300 Subject: [PATCH 02/66] Renamed ACLFilledChecklist::conn() into clientConnectionManager() --- src/DelayId.cc | 2 +- src/acl/AnnotateClient.cc | 2 +- src/acl/AtStep.cc | 2 +- src/acl/ConnMark.cc | 2 +- src/acl/DestinationIp.cc | 2 +- src/acl/FilledChecklist.cc | 18 +++++++++--------- src/acl/FilledChecklist.h | 4 ++-- src/acl/MyPortName.cc | 4 ++-- src/acl/ServerCertificate.cc | 4 ++-- src/acl/ServerName.cc | 2 +- src/auth/Acl.cc | 4 ++-- src/auth/AclProxyAuth.cc | 6 +++--- src/client_side.cc | 4 ++-- src/ident/AclIdent.cc | 14 +++++++------- 14 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index cd7ff8b1fc6..0e84dfa64b4 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -94,7 +94,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) ch.my_addr = r->myAddr(); if (http->getConn() != NULL) - ch.conn(http->getConn()); + ch.clientConnectionManager(http->getConn()); if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck().allowed()) { diff --git a/src/acl/AnnotateClient.cc b/src/acl/AnnotateClient.cc index c1073c13bd7..359b83fc8b8 100644 --- a/src/acl/AnnotateClient.cc +++ b/src/acl/AnnotateClient.cc @@ -17,7 +17,7 @@ int ACLAnnotateClientStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { - if (const auto conn = checklist->conn()) { + if (const auto conn = checklist->clientConnectionManager()) { ACLAnnotationData *tdata = dynamic_cast(data); assert(tdata); tdata->annotate(conn->notes(), &delimiters.value, checklist->al); diff --git a/src/acl/AtStep.cc b/src/acl/AtStep.cc index fc94af6958e..33e4b29a66b 100644 --- a/src/acl/AtStep.cc +++ b/src/acl/AtStep.cc @@ -21,7 +21,7 @@ int ACLAtStepStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { Ssl::ServerBump *bump = NULL; - if (checklist->conn() != NULL && (bump = checklist->conn()->serverBump())) + if (checklist->clientConnectionManager() != NULL && (bump = checklist->clientConnectionManager()->serverBump())) return data->match(bump->step); else return data->match(Ssl::bumpStep1); diff --git a/src/acl/ConnMark.cc b/src/acl/ConnMark.cc index 90a8f6b4953..67b5d7d3bf7 100644 --- a/src/acl/ConnMark.cc +++ b/src/acl/ConnMark.cc @@ -42,7 +42,7 @@ int Acl::ConnMark::match(ACLChecklist *cl) { const auto *checklist = Filled(cl); - const auto conn = checklist->conn(); + const auto conn = checklist->clientConnectionManager(); if (conn && conn->clientConnection) { const auto connmark = conn->clientConnection->nfConnmark; diff --git a/src/acl/DestinationIp.cc b/src/acl/DestinationIp.cc index c0ce440c312..c6ac6c03a73 100644 --- a/src/acl/DestinationIp.cc +++ b/src/acl/DestinationIp.cc @@ -46,7 +46,7 @@ ACLDestinationIP::match(ACLChecklist *cl) // To resolve this we will force DIRECT and only to the original client destination. // In which case, we also need this ACL to accurately match the destination if (Config.onoff.client_dst_passthru && (checklist->request->flags.intercepted || checklist->request->flags.interceptTproxy)) { - const auto conn = checklist->conn(); + const auto conn = checklist->clientConnectionManager(); return (conn && conn->clientConnection) ? ACLIP::match(conn->clientConnection->local) : -1; } diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 24488b7cf96..a6f680666cd 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -85,9 +85,9 @@ ACLFilledChecklist::verifyAle() const // fill the old external_acl_type codes are set if any // data on them exists in the Checklist - if (!al->cache.port && conn()) { + if (!al->cache.port && clientConnectionManager()) { showDebugWarning("listening port"); - al->cache.port = conn()->port; + al->cache.port = clientConnectionManager()->port; } if (request) { @@ -141,31 +141,31 @@ ACLFilledChecklist::syncAle(HttpRequest *adaptedRequest, const char *logUri) con } ConnStateData * -ACLFilledChecklist::conn() const +ACLFilledChecklist::clientConnectionManager() const { return cbdataReferenceValid(conn_) ? conn_ : nullptr; } void -ACLFilledChecklist::conn(ConnStateData *aConn) +ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) { - if (conn() == aConn) + if (clientConnectionManager() == aConn) return; - assert (conn() == NULL); + assert (clientConnectionManager() == NULL); conn_ = cbdataReference(aConn); } int ACLFilledChecklist::fd() const { - const auto c = conn(); + const auto c = clientConnectionManager(); return (c && c->clientConnection) ? c->clientConnection->fd : fd_; } void ACLFilledChecklist::fd(int aDescriptor) { - const auto c = conn(); + const auto c = clientConnectionManager(); assert(!c || !c->clientConnection || c->clientConnection->fd == aDescriptor); fd_ = aDescriptor; } @@ -249,7 +249,7 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) my_addr = request->myAddr(); if (request->clientConnectionManager.valid()) - conn(request->clientConnectionManager.get()); + clientConnectionManager(request->clientConnectionManager.get()); } } diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index f9bb7b67fb4..4f37fd0516d 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -45,13 +45,13 @@ class ACLFilledChecklist: public ACLChecklist public: /// The client connection manager - ConnStateData * conn() const; + ConnStateData * clientConnectionManager() const; /// The client side fd. It uses conn() if available int fd() const; /// set either conn - void conn(ConnStateData *); + void clientConnectionManager(ConnStateData *); /// set the client side FD void fd(int aDescriptor); diff --git a/src/acl/MyPortName.cc b/src/acl/MyPortName.cc index 3d6f90dbd08..710e6ff8a11 100644 --- a/src/acl/MyPortName.cc +++ b/src/acl/MyPortName.cc @@ -18,8 +18,8 @@ int ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { - if (checklist->conn() != NULL && checklist->conn()->port != NULL) - return data->match(checklist->conn()->port->name); + if (checklist->clientConnectionManager() != NULL && checklist->clientConnectionManager()->port != NULL) + return data->match(checklist->clientConnectionManager()->port->name); if (checklist->request != NULL) return data->match(checklist->request->myportname.termedBuf()); return 0; diff --git a/src/acl/ServerCertificate.cc b/src/acl/ServerCertificate.cc index 1246306d37d..3070aa2492f 100644 --- a/src/acl/ServerCertificate.cc +++ b/src/acl/ServerCertificate.cc @@ -24,8 +24,8 @@ ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledCheckli Security::CertPointer cert; if (checklist->serverCert) cert = checklist->serverCert; - else if (checklist->conn() != NULL && checklist->conn()->serverBump()) - cert = checklist->conn()->serverBump()->serverCert; + else if (checklist->clientConnectionManager() != NULL && checklist->clientConnectionManager()->serverBump()) + cert = checklist->clientConnectionManager()->serverBump()->serverCert; if (!cert) return 0; diff --git a/src/acl/ServerName.cc b/src/acl/ServerName.cc index d4a63a79802..d8d9a205af3 100644 --- a/src/acl/ServerName.cc +++ b/src/acl/ServerName.cc @@ -92,7 +92,7 @@ ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *ch const char *serverName = nullptr; SBuf clientSniKeeper; // because c_str() is not constant - if (ConnStateData *conn = checklist->conn()) { + if (ConnStateData *conn = checklist->clientConnectionManager()) { const char *clientRequestedServerName = nullptr; clientSniKeeper = conn->tlsClientSni(); if (clientSniKeeper.isEmpty()) { diff --git a/src/auth/Acl.cc b/src/auth/Acl.cc index 25f1fd3d9ae..1129bd5ddf5 100644 --- a/src/auth/Acl.cc +++ b/src/auth/Acl.cc @@ -36,7 +36,7 @@ AuthenticateAcl(ACLChecklist *ch) return ACCESS_DENIED; } else if (request->flags.sslBumped) { debugs(28, 5, "SslBumped request: It is an encapsulated request do not authenticate"); - checklist->auth_user_request = checklist->conn() != NULL ? checklist->conn()->getAuth() : request->auth_user_request; + checklist->auth_user_request = checklist->clientConnectionManager() != NULL ? checklist->clientConnectionManager()->getAuth() : request->auth_user_request; if (checklist->auth_user_request != NULL) return ACCESS_ALLOWED; else @@ -56,7 +56,7 @@ AuthenticateAcl(ACLChecklist *ch) /* Note: this fills in auth_user_request when applicable */ const AuthAclState result = Auth::UserRequest::tryToAuthenticateAndSetAuthUser( &checklist->auth_user_request, headertype, request, - checklist->conn(), checklist->src_addr, checklist->al); + checklist->clientConnectionManager(), checklist->src_addr, checklist->al); switch (result) { case AUTH_ACL_CANNOT_AUTHENTICATE: diff --git a/src/auth/AclProxyAuth.cc b/src/auth/AclProxyAuth.cc index 14c52ffec39..f4873e2c914 100644 --- a/src/auth/AclProxyAuth.cc +++ b/src/auth/AclProxyAuth.cc @@ -141,14 +141,14 @@ ProxyAuthLookup::LookupDone(void *data) { ACLFilledChecklist *checklist = Filled(static_cast(data)); - if (checklist->auth_user_request == NULL || !checklist->auth_user_request->valid() || checklist->conn() == NULL) { + if (checklist->auth_user_request == NULL || !checklist->auth_user_request->valid() || checklist->clientConnectionManager() == NULL) { /* credentials could not be checked either way * restart the whole process */ /* OR the connection was closed, there's no way to continue */ checklist->auth_user_request = NULL; - if (checklist->conn() != NULL) { - checklist->conn()->setAuth(NULL, "proxy_auth ACL failure"); + if (checklist->clientConnectionManager() != NULL) { + checklist->clientConnectionManager()->setAuth(NULL, "proxy_auth ACL failure"); } } diff --git a/src/client_side.cc b/src/client_side.cc index 2ee7518c13c..6b81a1287e1 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1562,7 +1562,7 @@ clientTunnelOnError(ConnStateData *conn, Http::StreamPointer &context, HttpReque checklist.requestErrorType = requestError; checklist.src_addr = conn->clientConnection->remote; checklist.my_addr = conn->clientConnection->local; - checklist.conn(conn); + checklist.clientConnectionManager(conn); ClientHttpRequest *http = context ? context->http : nullptr; const char *log_uri = http ? http->log_uri : nullptr; checklist.syncAle(request.getRaw(), log_uri); @@ -1810,7 +1810,7 @@ ConnStateData::proxyProtocolValidateClient() ACLFilledChecklist ch(Config.accessList.proxyProtocol, NULL, clientConnection->rfc931); ch.src_addr = clientConnection->remote; ch.my_addr = clientConnection->local; - ch.conn(this); + ch.clientConnectionManager(this); if (!ch.fastCheck().allowed()) return proxyProtocolError("PROXY client not permitted by ACLs"); diff --git a/src/ident/AclIdent.cc b/src/ident/AclIdent.cc index 67d3c92cb9d..8e2f1dbd9c7 100644 --- a/src/ident/AclIdent.cc +++ b/src/ident/AclIdent.cc @@ -69,9 +69,9 @@ ACLIdent::match(ACLChecklist *cl) ACLFilledChecklist *checklist = Filled(cl); if (checklist->rfc931[0]) { return data->match(checklist->rfc931); - } else if (checklist->conn() != NULL && checklist->conn()->clientConnection != NULL && checklist->conn()->clientConnection->rfc931[0]) { - return data->match(checklist->conn()->clientConnection->rfc931); - } else if (checklist->conn() != NULL && Comm::IsConnOpen(checklist->conn()->clientConnection)) { + } else if (checklist->clientConnectionManager() != NULL && checklist->clientConnectionManager()->clientConnection != NULL && checklist->clientConnectionManager()->clientConnection->rfc931[0]) { + return data->match(checklist->clientConnectionManager()->clientConnection->rfc931); + } else if (checklist->clientConnectionManager() != NULL && Comm::IsConnOpen(checklist->clientConnectionManager()->clientConnection)) { if (checklist->goAsync(IdentLookup::Instance())) { debugs(28, 3, "switching to ident lookup state"); return -1; @@ -116,11 +116,11 @@ void IdentLookup::checkForAsync(ACLChecklist *cl)const { ACLFilledChecklist *checklist = Filled(cl); - const ConnStateData *conn = checklist->conn(); + const ConnStateData *conn = checklist->clientConnectionManager(); // check that ACLIdent::match() tested this lookup precondition assert(conn && Comm::IsConnOpen(conn->clientConnection)); debugs(28, 3, HERE << "Doing ident lookup" ); - Ident::Start(checklist->conn()->clientConnection, LookupDone, checklist); + Ident::Start(checklist->clientConnectionManager()->clientConnection, LookupDone, checklist); } void @@ -138,8 +138,8 @@ IdentLookup::LookupDone(const char *ident, void *data) * Cache the ident result in the connection, to avoid redoing ident lookup * over and over on persistent connections */ - if (checklist->conn() != NULL && checklist->conn()->clientConnection != NULL && !checklist->conn()->clientConnection->rfc931[0]) - xstrncpy(checklist->conn()->clientConnection->rfc931, checklist->rfc931, USER_IDENT_SZ); + if (checklist->clientConnectionManager() != NULL && checklist->clientConnectionManager()->clientConnection != NULL && !checklist->clientConnectionManager()->clientConnection->rfc931[0]) + xstrncpy(checklist->clientConnectionManager()->clientConnection->rfc931, checklist->rfc931, USER_IDENT_SZ); checklist->resumeNonBlockingCheck(IdentLookup::Instance()); } From 83039d27cd91c057317f7307b00b44e8acb04cc9 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Feb 2019 17:23:40 +0300 Subject: [PATCH 03/66] Moved HttpRequest::clientConnectionManager into MasterXaction --- src/Downloader.cc | 2 +- src/FwdState.cc | 8 +++--- src/HttpRequest.cc | 22 +++++++++------- src/HttpRequest.h | 12 ++++----- src/MasterXaction.cc | 6 +++++ src/MasterXaction.h | 12 ++++++++- src/PeerPoolMgr.cc | 2 +- src/acl/Asn.cc | 2 +- src/acl/FilledChecklist.cc | 4 +-- src/adaptation/ecap/Host.cc | 2 +- src/adaptation/icap/Xaction.cc | 2 +- src/client_side.cc | 4 +-- src/client_side_reply.cc | 6 ++--- src/client_side_request.cc | 4 +-- src/clients/FtpRelay.cc | 14 +++++----- src/comm/TcpAcceptor.cc | 2 +- src/esi/Include.cc | 2 +- src/external_acl.cc | 2 +- src/format/Format.cc | 46 ++++++++++++++++----------------- src/htcp.cc | 2 +- src/http.cc | 6 ++--- src/icmp/net_db.cc | 2 +- src/icp_v2.cc | 2 +- src/mgr/Inquirer.cc | 2 +- src/mime.cc | 2 +- src/neighbors.cc | 2 +- src/peer_select.cc | 4 +-- src/servers/FtpServer.cc | 2 +- src/servers/Http1Server.cc | 2 +- src/ssl/PeekingPeerConnector.cc | 24 ++++++++--------- src/tests/testHttpRequest.cc | 6 ++--- src/tunnel.cc | 2 +- 32 files changed, 115 insertions(+), 97 deletions(-) diff --git a/src/Downloader.cc b/src/Downloader.cc index 2da530661ce..396658f2313 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -128,7 +128,7 @@ Downloader::buildRequest() { const HttpRequestMethod method = Http::METHOD_GET; - const MasterXaction::Pointer mx = new MasterXaction(initiator_); + const MasterXaction::Pointer mx = new MasterXaction(initiator_, nullptr); HttpRequest *const request = HttpRequest::FromUrl(url_.c_str(), mx, method); if (!request) { diff --git a/src/FwdState.cc b/src/FwdState.cc index f03f84745b5..da1bc9595da 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -253,8 +253,8 @@ FwdState::completed() errorAppendEntry(entry, err); err = NULL; #if USE_OPENSSL - if (request->flags.sslPeek && request->clientConnectionManager.valid()) { - CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, + if (request->flags.sslPeek && request->clientConnectionManager().valid()) { + CallJobHere1(17, 4, request->clientConnectionManager(), ConnStateData, ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(Comm::ConnectionPointer(nullptr), request)); } #endif @@ -791,7 +791,7 @@ FwdState::connectedToPeer(Security::EncryptorAnswer &answer) } // should reach ConnStateData before the dispatched Client job starts - CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, + CallJobHere1(17, 4, request->clientConnectionManager(), ConnStateData, ConnStateData::notePeerConnection, serverConnection()); if (serverConnection()->getPeer()) @@ -1032,7 +1032,7 @@ FwdState::dispatch() #if USE_OPENSSL if (request->flags.sslPeek) { - CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, + CallJobHere1(17, 4, request->clientConnectionManager(), ConnStateData, ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(serverConnection(), request)); unregister(serverConn); // async call owns it now complete(); // destroys us diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index b39488c317b..89c28a85a85 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -246,9 +246,6 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) forcedBodyContinuation = aReq->forcedBodyContinuation; - // main property is which connection the request was received on (if any) - clientConnectionManager = aReq->clientConnectionManager; - downloader = aReq->downloader; theNotes = aReq->theNotes; @@ -667,8 +664,8 @@ HttpRequest::parseHeader(const char *buffer, const size_t size) ConnStateData * HttpRequest::pinnedConnection() { - if (clientConnectionManager.valid() && clientConnectionManager->pinning.pinned) - return clientConnectionManager.get(); + if (clientConnectionManager().valid() && clientConnectionManager()->pinning.pinned) + return clientConnectionManager().get(); return NULL; } @@ -772,18 +769,18 @@ HttpRequest::resetIndirectClientAddr() void HttpRequest::manager(const CbcPointer &aMgr, const AccessLogEntryPointer &al) { - clientConnectionManager = aMgr; + masterXaction->clientConnectionManager = aMgr; - if (!clientConnectionManager.valid()) + if (!clientConnectionManager().valid()) return; - AnyP::PortCfgPointer port = clientConnectionManager->port; + AnyP::PortCfgPointer port = clientConnectionManager()->port; if (port) { myportname = port->name; flags.ignoreCc = port->ignore_cc; } - if (auto clientConnection = clientConnectionManager->clientConnection) { + if (auto clientConnection = clientConnectionManager()->clientConnection) { #if FOLLOW_X_FORWARDED_FOR // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) // not details about the TCP connection itself @@ -862,3 +859,10 @@ FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry return ip; // may still be nil } +Comm::ConnectionPointer +HttpRequest::clientConnection() const +{ + if (hasClientConnectionManager()) + return masterXaction->clientConnectionManager->clientConnection; + return nullptr; +} diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 5a10c97d1a8..df0951a51bb 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -150,6 +150,11 @@ class HttpRequest: public Http::Message const Ip::Address& effectiveClientAddr() const; + CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager; } + bool hasClientConnectionManager() const { return masterXaction->clientConnectionManager.valid(); } + + Comm::ConnectionPointer clientConnection() const; + #if FOLLOW_X_FORWARDED_FOR const Ip::Address& indirectClientAddr() const; void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } @@ -226,13 +231,6 @@ class HttpRequest: public Http::Message */ const SBuf storeId(); - /** - * The client connection manager, if known; - * Used for any response actions needed directly to the client. - * ie 1xx forwarding or connection pinning state changes - */ - CbcPointer clientConnectionManager; - /// The Downloader object which initiated the HTTP request if any CbcPointer downloader; diff --git a/src/MasterXaction.cc b/src/MasterXaction.cc index 20107c97022..7188809f2be 100644 --- a/src/MasterXaction.cc +++ b/src/MasterXaction.cc @@ -7,7 +7,13 @@ */ #include "squid.h" +#include "client_side.h" +#include "http/Stream.h" #include "MasterXaction.h" InstanceIdDefinitions(MasterXaction, "MXID_"); +MasterXaction::MasterXaction(const XactionInitiator anInitiator, ConnStateData *connManager) : + initiator(anInitiator), + clientConnectionManager(connManager) +{}; diff --git a/src/MasterXaction.h b/src/MasterXaction.h index f1d16df887b..189948ca2eb 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -10,13 +10,17 @@ #define SQUID_SRC_MASTERXACTION_H #include "anyp/forward.h" +#include "base/CbcPointer.h" #include "anyp/PortCfg.h" #include "base/InstanceId.h" #include "base/Lock.h" #include "base/RefCount.h" +//#include "client_side.h" #include "comm/forward.h" #include "XactionInitiator.h" +class ConnStateData; + /** Master transaction details. * * Aggregates historical data from individual related protocol-specific @@ -41,7 +45,7 @@ class MasterXaction : public RefCountable public: typedef RefCount Pointer; - explicit MasterXaction(const XactionInitiator anInitiator) : initiator(anInitiator) {}; + explicit MasterXaction(const XactionInitiator anInitiator, ConnStateData *connManager); /// transaction ID. InstanceId id; @@ -55,6 +59,12 @@ class MasterXaction : public RefCountable /// the initiator of this transaction XactionInitiator initiator; + /** + * The client connection manager, if known; + * Used for any response actions needed directly to the client. + * ie 1xx forwarding or connection pinning state changes + */ + CbcPointer clientConnectionManager; // TODO: add state from other Jobs in the transaction }; diff --git a/src/PeerPoolMgr.cc b/src/PeerPoolMgr.cc index 3c5d0799ae2..70ee922243d 100644 --- a/src/PeerPoolMgr.cc +++ b/src/PeerPoolMgr.cc @@ -60,7 +60,7 @@ PeerPoolMgr::start() { AsyncJob::start(); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerPool); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerPool, nullptr); // ErrorState, getOutgoingAddress(), and other APIs may require a request. // We fake one. TODO: Optionally send this request to peers? request = new HttpRequest(Http::METHOD_OPTIONS, AnyP::PROTO_HTTP, "http", "*", mx); diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index dc2dd07a6bf..af0c2d31a02 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -237,7 +237,7 @@ asnCacheStart(int as) debugs(53, 3, "AS " << as); ASState *asState = new ASState; asState->as_number = as; - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAsn); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAsn, nullptr); asState->request = new HttpRequest(mx); asState->request->url = whoisUrl; asState->request->method = Http::METHOD_GET; diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index a6f680666cd..017334e0cb7 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -248,8 +248,8 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) src_addr = request->effectiveClientAddr(); my_addr = request->myAddr(); - if (request->clientConnectionManager.valid()) - clientConnectionManager(request->clientConnectionManager.get()); + if (request->clientConnectionManager().valid()) + clientConnectionManager(request->clientConnectionManager().get()); } } diff --git a/src/adaptation/ecap/Host.cc b/src/adaptation/ecap/Host.cc index b69e82658d7..203e6c77b51 100644 --- a/src/adaptation/ecap/Host.cc +++ b/src/adaptation/ecap/Host.cc @@ -163,7 +163,7 @@ Adaptation::Ecap::Host::closeDebug(std::ostream *debug) Adaptation::Ecap::Host::MessagePtr Adaptation::Ecap::Host::newRequest() const { - static const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptationOrphan_); + static const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptationOrphan_, nullptr); return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest(mx))); } diff --git a/src/adaptation/icap/Xaction.cc b/src/adaptation/icap/Xaction.cc index c91e7e1021b..1f71a6b2f9e 100644 --- a/src/adaptation/icap/Xaction.cc +++ b/src/adaptation/icap/Xaction.cc @@ -97,7 +97,7 @@ Adaptation::Icap::Xaction::Xaction(const char *aTypeName, Adaptation::Icap::Serv { debugs(93,3, typeName << " constructed, this=" << this << " [icapx" << id << ']'); // we should not call virtual status() here - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptation); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptation, nullptr); icapRequest = new HttpRequest(mx); HTTPMSGLOCK(icapRequest); icap_tr_start = current_time; diff --git a/src/client_side.cc b/src/client_side.cc index 6b81a1287e1..a1212485102 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2609,7 +2609,7 @@ ConnStateData::postHttpsAccept() return; } - MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); mx->tcpClient = clientConnection; // Create a fake HTTP request for ssl_bump ACL check, // using tproxy/intercept provided destination IP and port. @@ -3262,7 +3262,7 @@ ConnStateData::buildFakeRequest(Http::MethodType const method, SBuf &useHost, un stream->registerWithConn(); - MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); mx->tcpClient = clientConnection; // Setup Http::Request object. Maybe should be replaced by a call to (modified) // clientProcessRequest diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 755f73a1cdd..04a77c73663 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -350,7 +350,7 @@ clientReplyContext::processExpired() debugs(88, 5, "lastmod " << entry->lastModified()); http->storeEntry(entry); assert(http->out.offset == 0); - assert(http->request->clientConnectionManager == http->getConn()); + assert(http->request->clientConnectionManager() == http->getConn()); if (collapsedRevalidation != crSlave) { /* @@ -787,7 +787,7 @@ clientReplyContext::processMiss() return; } - assert(r->clientConnectionManager == http->getConn()); + assert(r->clientConnectionManager() == http->getConn()); /** Start forwarding to get the new object from network */ FwdState::Start(conn, http->storeEntry(), r, http->al); @@ -2286,7 +2286,7 @@ clientReplyContext::createStoreEntry(const HttpRequestMethod& m, RequestFlags re */ if (http->request == NULL) { - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, http->getConn()); // XXX: These fake URI parameters shadow the real (or error:...) URI. // TODO: Either always set the request earlier and assert here OR use // http->uri (converted to Anyp::Uri) to create this catch-all request. diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 2775ac92534..a61e5a03441 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -983,7 +983,7 @@ clientCheckPinning(ClientHttpRequest * http) request->flags.connectionProxyAuth = true; } // These should already be linked correctly. - assert(request->clientConnectionManager == http_conn); + assert(request->clientConnectionManager() == http_conn); } } @@ -1017,7 +1017,7 @@ clientCheckPinning(ClientHttpRequest * http) } if (may_pin && !request->pinnedConnection()) { // These should already be linked correctly. Just need the ServerConnection to pinn. - assert(request->clientConnectionManager == http_conn); + assert(request->clientConnectionManager() == http_conn); } } } diff --git a/src/clients/FtpRelay.cc b/src/clients/FtpRelay.cc index 2f5134ff041..87935049d13 100644 --- a/src/clients/FtpRelay.cc +++ b/src/clients/FtpRelay.cc @@ -201,7 +201,7 @@ Ftp::Relay::serverComplete() { stopOriginWait(ctrl.replycode); - CbcPointer &mgr = fwd->request->clientConnectionManager; + CbcPointer &mgr = fwd->request->clientConnectionManager(); if (mgr.valid()) { if (Comm::IsConnOpen(ctrl.conn)) { debugs(9, 7, "completing FTP server " << ctrl.conn << @@ -227,7 +227,7 @@ Ftp::Relay::serverComplete() Ftp::MasterState & Ftp::Relay::updateMaster() { - CbcPointer &mgr = fwd->request->clientConnectionManager; + CbcPointer &mgr = fwd->request->clientConnectionManager(); if (mgr.valid()) { if (Ftp::Server *srv = dynamic_cast(mgr.get())) return *srv->master; @@ -340,7 +340,7 @@ Ftp::Relay::processReplyBody() void Ftp::Relay::handleControlReply() { - if (!request->clientConnectionManager.valid()) { + if (!request->clientConnectionManager().valid()) { debugs(9, 5, "client connection gone"); closeServer(); return; @@ -400,7 +400,7 @@ Ftp::Relay::forwardPreliminaryReply(const PreliminaryCb cb) const AsyncCall::Pointer call = JobCallback(11, 3, CbDialer, this, Ftp::Relay::proceedAfterPreliminaryReply); - CallJobHere1(9, 4, request->clientConnectionManager, ConnStateData, + CallJobHere1(9, 4, request->clientConnectionManager(), ConnStateData, ConnStateData::sendControlMsg, HttpControlMsg(reply, call)); } @@ -548,7 +548,7 @@ Ftp::Relay::sendCommand() SENT_COMMAND; if (state == SENT_DATA_REQUEST) { - CbcPointer &mgr = fwd->request->clientConnectionManager; + CbcPointer &mgr = fwd->request->clientConnectionManager(); if (mgr.valid()) { if (Ftp::Server *srv = dynamic_cast(mgr.get())) { typedef NullaryMemFunT CbDialer; @@ -633,7 +633,7 @@ Ftp::Relay::readDataReply() bool Ftp::Relay::startDirTracking() { - if (!fwd->request->clientConnectionManager->port->ftp_track_dirs) + if (!fwd->request->clientConnectionManager()->port->ftp_track_dirs) return false; debugs(9, 5, "start directory tracking"); @@ -770,7 +770,7 @@ void Ftp::Relay::stopOriginWait(int code) { if (originWaitInProgress) { - CbcPointer &mgr = fwd->request->clientConnectionManager; + CbcPointer &mgr = fwd->request->clientConnectionManager(); if (mgr.valid()) { if (Ftp::Server *srv = dynamic_cast(mgr.get())) { typedef UnaryMemFunT CbDialer; diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index 015fbe6beb8..ee9756382a7 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -330,7 +330,7 @@ Comm::TcpAcceptor::notify(const Comm::Flag flag, const Comm::ConnectionPointer & if (theCallSub != NULL) { AsyncCall::Pointer call = theCallSub->callback(); CommAcceptCbParams ¶ms = GetCommParams(call); - params.xaction = new MasterXaction(XactionInitiator::initClient); + params.xaction = new MasterXaction(XactionInitiator::initClient, nullptr); params.xaction->squidPort = listenPort_; params.fd = conn->fd; params.conn = params.xaction->tcpClient = newConnDetails; diff --git a/src/esi/Include.cc b/src/esi/Include.cc index ef50fc8a897..e4f51e14360 100644 --- a/src/esi/Include.cc +++ b/src/esi/Include.cc @@ -299,7 +299,7 @@ ESIInclude::Start (ESIStreamContext::Pointer stream, char const *url, ESIVarStat char const *tempUrl = vars->extractChar (); debugs(86, 5, "ESIIncludeStart: Starting subrequest with url '" << tempUrl << "'"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initEsi); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initEsi, nullptr); if (clientBeginRequest(Http::METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ, mx)) { debugs(86, DBG_CRITICAL, "starting new ESI subrequest failed"); } diff --git a/src/external_acl.cc b/src/external_acl.cc index 5799c0fc631..0e6d1e4b08b 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -590,7 +590,7 @@ copyResultsFromEntry(HttpRequest *req, const ExternalACLEntryPointer &entry) req->extacl_message = entry->message; // attach the helper kv-pair to the transaction - UpdateRequestNotes(req->clientConnectionManager.get(), *req, entry->notes); + UpdateRequestNotes(req->clientConnectionManager().get(), *req, entry->notes); } } diff --git a/src/format/Format.cc b/src/format/Format.cc index dea2de4cc72..c9216a30e2e 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -421,9 +421,9 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_CLIENT_EUI: #if USE_SQUID_EUI // TODO make the ACL checklist have a direct link to any TCP details. - if (al->request && al->request->clientConnectionManager.valid() && - al->request->clientConnectionManager->clientConnection) { - const auto &conn = al->request->clientConnectionManager->clientConnection; + if (al->request && al->request->clientConnectionManager().valid() && + al->request->clientConnectionManager()->clientConnection) { + const auto &conn = al->request->clientConnectionManager()->clientConnection; if (conn->remote.isIPv4()) conn->remoteEui48.encode(tmp, sizeof(tmp)); else @@ -435,10 +435,10 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_CLIENT_EUI48: #if USE_SQUID_EUI - if (al->request && al->request->clientConnectionManager.valid() && - al->request->clientConnectionManager->clientConnection && - al->request->clientConnectionManager->clientConnection->remote.isIPv4()) { - al->request->clientConnectionManager->clientConnection->remoteEui48.encode(tmp, sizeof(tmp)); + if (al->request && al->request->clientConnectionManager().valid() && + al->request->clientConnectionManager()->clientConnection && + al->request->clientConnectionManager()->clientConnection->remote.isIPv4()) { + al->request->clientConnectionManager()->clientConnection->remoteEui48.encode(tmp, sizeof(tmp)); out = tmp; } #endif @@ -446,10 +446,10 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_CLIENT_EUI64: #if USE_SQUID_EUI - if (al->request && al->request->clientConnectionManager.valid() && - al->request->clientConnectionManager->clientConnection && - !al->request->clientConnectionManager->clientConnection->remote.isIPv4()) { - al->request->clientConnectionManager->clientConnection->remoteEui64.encode(tmp, sizeof(tmp)); + if (al->request && al->request->clientConnectionManager().valid() && + al->request->clientConnectionManager()->clientConnection && + !al->request->clientConnectionManager()->clientConnection->remote.isIPv4()) { + al->request->clientConnectionManager()->clientConnection->remoteEui64.encode(tmp, sizeof(tmp)); out = tmp; } #endif @@ -537,8 +537,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_CLIENT_HANDSHAKE: - if (al->request && al->request->clientConnectionManager.valid()) { - const auto &handshake = al->request->clientConnectionManager->preservedClientData; + if (al->request && al->request->clientConnectionManager().valid()) { + const auto &handshake = al->request->clientConnectionManager()->preservedClientData; if (const auto rawLength = handshake.length()) { // add 1 byte to optimize the c_str() conversion below char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1); @@ -1201,7 +1201,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CERT_RAW: if (al->request) { - ConnStateData *conn = al->request->clientConnectionManager.get(); + ConnStateData *conn = al->request->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) { sb = sslGetUserCertificatePEM(ssl); @@ -1213,7 +1213,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CERTCHAIN_RAW: if (al->request) { - ConnStateData *conn = al->request->clientConnectionManager.get(); + ConnStateData *conn = al->request->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) { sb = sslGetUserCertificatePEM(ssl); @@ -1225,7 +1225,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CERT: if (al->request) { - ConnStateData *conn = al->request->clientConnectionManager.get(); + ConnStateData *conn = al->request->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) out = sslGetUserAttribute(ssl, fmt->data.header.header); @@ -1235,7 +1235,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CA_CERT: if (al->request) { - ConnStateData *conn = al->request->clientConnectionManager.get(); + ConnStateData *conn = al->request->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) out = sslGetCAAttribute(ssl, fmt->data.header.header); @@ -1262,8 +1262,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_SSL_CLIENT_SNI: - if (al->request && al->request->clientConnectionManager.valid()) { - if (const ConnStateData *conn = al->request->clientConnectionManager.get()) { + if (al->request && al->request->clientConnectionManager().valid()) { + if (const ConnStateData *conn = al->request->clientConnectionManager().get()) { if (!conn->tlsClientSni().isEmpty()) { sb = conn->tlsClientSni(); out = sb.c_str(); @@ -1273,8 +1273,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_SSL_SERVER_CERT_ERRORS: - if (al->request && al->request->clientConnectionManager.valid()) { - if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) { + if (al->request && al->request->clientConnectionManager().valid()) { + if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager()->serverBump()) { const char *separator = fmt->data.string ? fmt->data.string : ":"; for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) { if (!sb.isEmpty()) @@ -1295,8 +1295,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_SERVER_CERT_ISSUER: case LFT_SSL_SERVER_CERT_SUBJECT: case LFT_SSL_SERVER_CERT_WHOLE: - if (al->request && al->request->clientConnectionManager.valid()) { - if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) { + if (al->request && al->request->clientConnectionManager().valid()) { + if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager()->serverBump()) { if (X509 *serverCert = srvBump->serverCert.get()) { if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT) out = Ssl::GetX509UserAttribute(serverCert, "DN"); diff --git a/src/htcp.cc b/src/htcp.cc index 26f4179805c..66bf7a5f079 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -694,7 +694,7 @@ htcpUnpackSpecifier(char *buf, int sz) // Parse the request method.HttpRequestMethodXXX(s->method); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp, nullptr); s->request = HttpRequest::FromUrl(s->uri, mx, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method); if (!s->request) { debugs(31, 3, "failed to create request. Invalid URI?"); diff --git a/src/http.cc b/src/http.cc index bef5f8e7a7d..2dbde983f5c 100644 --- a/src/http.cc +++ b/src/http.cc @@ -818,7 +818,7 @@ HttpStateData::handle1xx(HttpReply *reply) typedef NullaryMemFunT CbDialer; const AsyncCall::Pointer cb = JobCallback(11, 3, CbDialer, this, HttpStateData::proceedAfter1xx); - CallJobHere1(11, 4, request->clientConnectionManager, ConnStateData, + CallJobHere1(11, 4, request->clientConnectionManager(), ConnStateData, ConnStateData::sendControlMsg, HttpControlMsg(msg, cb)); // If the call is not fired, then the Sink is gone, and HttpStateData // will terminate due to an aborted store entry or another similar error. @@ -1475,8 +1475,8 @@ HttpStateData::processReplyBody() } if (ispinned) { - if (request->clientConnectionManager.valid()) { - CallJobHere1(11, 4, request->clientConnectionManager, + if (request->clientConnectionManager().valid()) { + CallJobHere1(11, 4, request->clientConnectionManager(), ConnStateData, notePinnedConnectionBecameIdle, ConnStateData::PinnedIdleContext(serverConnectionSaved, request)); diff --git a/src/icmp/net_db.cc b/src/icmp/net_db.cc index 69cecafc2ca..82b21d343f9 100644 --- a/src/icmp/net_db.cc +++ b/src/icmp/net_db.cc @@ -1274,7 +1274,7 @@ netdbExchangeStart(void *data) static const SBuf netDB("netdb"); char *uri = internalRemoteUri(p->secure.encryptTransport, p->host, p->http_port, "/squid-internal-dynamic/", netDB); debugs(38, 3, "Requesting '" << uri << "'"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp, nullptr); HttpRequestPointer req(HttpRequest::FromUrl(uri, mx)); if (!req) { diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 76651de86ab..ce913e8b394 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -496,7 +496,7 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) } HttpRequest *result; - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp, nullptr); if ((result = HttpRequest::FromUrl(url, mx)) == NULL) icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); diff --git a/src/mgr/Inquirer.cc b/src/mgr/Inquirer.cc index 71706a4b79c..b680060cd81 100644 --- a/src/mgr/Inquirer.cc +++ b/src/mgr/Inquirer.cc @@ -75,7 +75,7 @@ Mgr::Inquirer::start() std::unique_ptr replyBuf; if (strands.empty()) { const char *url = aggrAction->command().params.httpUri.termedBuf(); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc, nullptr); HttpRequest *req = HttpRequest::FromUrl(url, mx); ErrorState err(ERR_INVALID_URL, Http::scNotFound, req); std::unique_ptr reply(err.BuildHttpReply()); diff --git a/src/mime.cc b/src/mime.cc index d732bdf3100..49f184fa7a0 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -403,7 +403,7 @@ MimeIcon::created(StoreEntry *newEntry) /* fill `e` with a canned 2xx response object */ - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon, nullptr); HttpRequestPointer r(HttpRequest::FromUrl(url_, mx)); if (!r) fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_); diff --git a/src/neighbors.cc b/src/neighbors.cc index 1a0d3e2bc9a..284df5e78ab 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1402,7 +1402,7 @@ peerCountMcastPeersStart(void *data) snprintf(url, MAX_URL, "http://"); p->in_addr.toUrl(url+7, MAX_URL -8 ); strcat(url, "/"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast, nullptr); HttpRequest *req = HttpRequest::FromUrl(url, mx); assert(req != nullptr); StoreEntry *fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET); diff --git a/src/peer_select.cc b/src/peer_select.cc index b5d70a8a3a5..5bb242bbcff 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -286,10 +286,10 @@ PeerSelector::resolveSelected() const bool choseDirect = fs && fs->code == HIER_DIRECT; if (isIntercepted && useOriginalDst && choseDirect) { // check the client is still around before using any of its details - if (req->clientConnectionManager.valid()) { + if (req->hasClientConnectionManager()) { // construct a "result" adding the ORIGINAL_DST to the set instead of DIRECT Comm::ConnectionPointer p = new Comm::Connection(); - p->remote = req->clientConnectionManager->clientConnection->local; + p->remote = req->clientConnection()->local; fs->code = ORIGINAL_DST; // fs->code is DIRECT. This fixes the display. handlePath(p, *fs); } diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index d63dc84e529..ed7c7988a5f 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -724,7 +724,7 @@ Ftp::Server::parseOneRequest() const SBuf *path = (params.length() && CommandHasPathParameter(cmd)) ? ¶ms : NULL; calcUri(path); - MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); mx->tcpClient = clientConnection; HttpRequest *const request = HttpRequest::FromUrl(uri.c_str(), mx, method); if (!request) { diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index 7bb6190f7f4..66031733c84 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -133,7 +133,7 @@ Http::One::Server::buildHttpRequest(Http::StreamPointer &context) } // TODO: move URL parse into Http Parser and INVALID_URL into the above parse error handling - MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); mx->tcpClient = clientConnection; if ((request = HttpRequest::FromUrl(http->uri, mx, parser_->method())) == NULL) { debugs(33, 5, "Invalid URL: " << http->uri); diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index 8531398e539..94a6e69162e 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -46,8 +46,8 @@ void Ssl::PeekingPeerConnector::checkForPeekAndSplice() { // Mark Step3 of bumping - if (request->clientConnectionManager.valid()) { - if (Ssl::ServerBump *serverBump = request->clientConnectionManager->serverBump()) { + if (request->clientConnectionManager().valid()) { + if (Ssl::ServerBump *serverBump = request->clientConnectionManager()->serverBump()) { serverBump->step = Ssl::bumpStep3; } } @@ -85,9 +85,9 @@ Ssl::PeekingPeerConnector::checkForPeekAndSpliceMatched(const Ssl::BumpMode acti Ssl::BumpMode finalAction = action; Must(finalAction == Ssl::bumpSplice || finalAction == Ssl::bumpBump || finalAction == Ssl::bumpTerminate); // Record final decision - if (request->clientConnectionManager.valid()) { - request->clientConnectionManager->sslBumpMode = finalAction; - request->clientConnectionManager->serverBump()->act.step3 = finalAction; + if (request->clientConnectionManager().valid()) { + request->clientConnectionManager()->sslBumpMode = finalAction; + request->clientConnectionManager()->serverBump()->act.step3 = finalAction; } al->ssl.bumpMode = finalAction; @@ -114,7 +114,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSpliceMatched(const Ssl::BumpMode acti Ssl::BumpMode Ssl::PeekingPeerConnector::checkForPeekAndSpliceGuess() const { - if (const ConnStateData *csd = request->clientConnectionManager.valid()) { + if (const ConnStateData *csd = request->clientConnectionManager().valid()) { const Ssl::BumpMode currentMode = csd->sslBumpMode; if (currentMode == Ssl::bumpStare) { debugs(83,5, "default to bumping after staring"); @@ -140,7 +140,7 @@ Ssl::PeekingPeerConnector::initialize(Security::SessionPointer &serverSession) if (!Security::PeerConnector::initialize(serverSession)) return false; - if (ConnStateData *csd = request->clientConnectionManager.valid()) { + if (ConnStateData *csd = request->clientConnectionManager().valid()) { // client connection is required in the case we need to splice // or terminate client and server connections @@ -212,11 +212,11 @@ void Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error) { // Check the list error with - if (!request->clientConnectionManager.valid() || !fd_table[serverConnection()->fd].ssl) + if (!request->clientConnectionManager().valid() || !fd_table[serverConnection()->fd].ssl) return; // remember the server certificate from the ErrorDetail object - if (Ssl::ServerBump *serverBump = request->clientConnectionManager->serverBump()) { + if (Ssl::ServerBump *serverBump = request->clientConnectionManager()->serverBump()) { if (!serverBump->serverCert.get()) { // remember the server certificate from the ErrorDetail object if (error && error->detail && error->detail->peerCert()) @@ -230,7 +230,7 @@ Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error) // For intercepted connections, set the host name to the server // certificate CN. Otherwise, we just hope that CONNECT is using // a user-entered address (a host name or a user-entered IP). - const bool isConnectRequest = !request->clientConnectionManager->port->flags.isIntercepted(); + const bool isConnectRequest = !request->clientConnectionManager()->port->flags.isIntercepted(); if (request->flags.sslPeek && !isConnectRequest) { if (X509 *srvX509 = serverBump->serverCert.get()) { if (const char *name = Ssl::CommonHostName(srvX509)) { @@ -319,7 +319,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() if (serverCertificateHandled) return; - if (ConnStateData *csd = request->clientConnectionManager.valid()) { + if (ConnStateData *csd = request->clientConnectionManager().valid()) { const int fd = serverConnection()->fd; Security::SessionPointer session(fd_table[fd].ssl); Security::CertPointer serverCert(SSL_get_peer_certificate(session.get())); @@ -338,7 +338,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() void Ssl::PeekingPeerConnector::serverCertificateVerified() { - if (ConnStateData *csd = request->clientConnectionManager.valid()) { + if (ConnStateData *csd = request->clientConnectionManager().valid()) { Security::CertPointer serverCert; if(Ssl::ServerBump *serverBump = csd->serverBump()) serverCert.resetAndLock(serverBump->serverCert.get()); diff --git a/src/tests/testHttpRequest.cc b/src/tests/testHttpRequest.cc index c4d743efe32..2f36790835f 100644 --- a/src/tests/testHttpRequest.cc +++ b/src/tests/testHttpRequest.cc @@ -46,7 +46,7 @@ testHttpRequest::testCreateFromUrl() /* vanilla url, implict method */ unsigned short expected_port; char * url = xstrdup("http://foo:90/bar"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, nullptr); HttpRequest *aRequest = HttpRequest::FromUrl(url, mx); expected_port = 90; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); @@ -115,7 +115,7 @@ testHttpRequest::testIPv6HostColonBug() /* valid IPv6 address without port */ url = xstrdup("http://[2000:800::45]/foo"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, nullptr); aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET); expected_port = 80; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); @@ -155,7 +155,7 @@ void testHttpRequest::testSanityCheckStartLine() { MemBuf input; - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, nullptr); PrivateHttpRequest engine(mx); Http::StatusCode error = Http::scNone; size_t hdr_len; diff --git a/src/tunnel.cc b/src/tunnel.cc index 65c94fb03cc..2afd81c51fd 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1360,7 +1360,7 @@ switchToTunnel(HttpRequest *request, Comm::ConnectionPointer &clientConn, Comm:: ++statCounter.server.all.requests; ++statCounter.server.other.requests; - auto conn = request->clientConnectionManager.get(); + auto conn = request->clientConnectionManager().get(); Must(conn); Http::StreamPointer context = conn->pipeline.front(); Must(context && context->http); From 0f9d7ded5f40a6436a30e2ddda065f145cb1f4dc Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Feb 2019 17:26:55 +0300 Subject: [PATCH 04/66] ACLFilledChecklist: do not overwrite addresses with the same values ... since src_addr and my_addr fields are initialized by means of HttpRequest in the constructor. --- src/DelayId.cc | 5 ----- src/FwdState.cc | 1 - src/HttpRequest.cc | 2 -- src/client_side.cc | 10 +++++----- src/client_side_request.cc | 2 -- src/tunnel.cc | 2 -- 6 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 0e84dfa64b4..82890ac9e77 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -90,11 +90,6 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) ch.reply = reply; HTTPMSGLOCK(reply); } - ch.src_addr = r->effectiveClientAddr(); - ch.my_addr = r->myAddr(); - - if (http->getConn() != NULL) - ch.clientConnectionManager(http->getConn()); if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck().allowed()) { diff --git a/src/FwdState.cc b/src/FwdState.cc index da1bc9595da..c7d9da1cbdf 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -324,7 +324,6 @@ FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, Ht */ ACLFilledChecklist ch(Config.accessList.miss, request, NULL); ch.al = al; - ch.src_addr = request->clientAddr(); ch.syncAle(request, nullptr); if (ch.fastCheck().denied()) { err_type page_id; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 89c28a85a85..33f252dd337 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -606,8 +606,6 @@ HttpRequest::getRangeOffsetLimit() rangeOffsetLimit = 0; // default value for rangeOffsetLimit ACLFilledChecklist ch(NULL, this, NULL); - ch.src_addr = clientAddr(); - ch.my_addr = my_addr; for (AclSizeLimit *l = Config.rangeOffsetLimit; l; l = l -> next) { /* if there is no ACL list or if the ACLs listed match use this limit value */ diff --git a/src/client_side.cc b/src/client_side.cc index a1212485102..30206ced825 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1560,9 +1560,11 @@ clientTunnelOnError(ConnStateData *conn, Http::StreamPointer &context, HttpReque ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request.getRaw(), nullptr); checklist.al = (context && context->http) ? context->http->al : nullptr; checklist.requestErrorType = requestError; - checklist.src_addr = conn->clientConnection->remote; - checklist.my_addr = conn->clientConnection->local; - checklist.clientConnectionManager(conn); + if (!request) { + checklist.src_addr = conn->clientConnection->remote; + checklist.my_addr = conn->clientConnection->local; + checklist.clientConnectionManager(conn); + } ClientHttpRequest *http = context ? context->http : nullptr; const char *log_uri = http ? http->log_uri : nullptr; checklist.syncAle(request.getRaw(), log_uri); @@ -2621,8 +2623,6 @@ ConnStateData::postHttpsAccept() request->myportname = port->name; ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL); - acl_checklist->src_addr = clientConnection->remote; - acl_checklist->my_addr = port->s; // Build a local AccessLogEntry to allow requiresAle() acls work acl_checklist->al = new AccessLogEntry; acl_checklist->al->cache.start_time = current_time; diff --git a/src/client_side_request.cc b/src/client_side_request.cc index a61e5a03441..d43000247e7 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1798,8 +1798,6 @@ ClientHttpRequest::doCallouts() if (getConn() && Comm::IsConnOpen(getConn()->clientConnection)) { ACLFilledChecklist ch(nullptr, request, nullptr); ch.al = calloutContext->http->al; - ch.src_addr = request->clientAddr(); - ch.my_addr = request->myAddr(); ch.syncAle(request, log_uri); if (!calloutContext->toClientMarkingDone) { diff --git a/src/tunnel.cc b/src/tunnel.cc index 2afd81c51fd..f973f72e90f 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1108,8 +1108,6 @@ tunnelStart(ClientHttpRequest * http) */ ACLFilledChecklist ch(Config.accessList.miss, request, NULL); ch.al = http->al; - ch.src_addr = request->clientAddr(); - ch.my_addr = request->myAddr(); ch.syncAle(request, http->log_uri); if (ch.fastCheck().denied()) { debugs(26, 4, HERE << "MISS access forbidden."); From bbad6bb27c5262a650b5251bdafd41c86ac57ea7 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Feb 2019 17:41:32 +0300 Subject: [PATCH 05/66] Removed HttpRequest client_addr and my_addr, not needed after 1341310 --- src/HttpRequest.h | 4 ---- src/auth/digest/UserRequest.cc | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/HttpRequest.h b/src/HttpRequest.h index df0951a51bb..1a42e370965 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -138,8 +138,6 @@ class HttpRequest: public Http::Message int imslen; - Ip::Address client_addr; - void setInternal(const bool val) { internal = val; } void setDownloader(Downloader *); @@ -161,8 +159,6 @@ class HttpRequest: public Http::Message void resetIndirectClientAddr(); #endif /* FOLLOW_X_FORWARDED_FOR */ - Ip::Address my_addr; - HierarchyLogEntry hier; int dnsWait; ///< sum of DNS lookup delays in milliseconds, for %dt diff --git a/src/auth/digest/UserRequest.cc b/src/auth/digest/UserRequest.cc index fecdce689cb..b11aa34a466 100644 --- a/src/auth/digest/UserRequest.cc +++ b/src/auth/digest/UserRequest.cc @@ -157,7 +157,7 @@ Auth::Digest::UserRequest::authenticate(HttpRequest * request, ConnStateData *, if (last_broken_addr != request->clientAddr()) { debugs(29, DBG_IMPORTANT, "Digest POST bug detected from " << - request->client_addr << " using '" << + request->clientAddr() << " using '" << (useragent ? useragent : "-") << "'. Please upgrade browser. See Bug #630 for details."); From 7dd8f677ef9a747b45dd8613ac59d43b95b1d73d Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Feb 2019 17:55:11 +0300 Subject: [PATCH 06/66] Fill addresses using ConnStateData in FilledChecklist --- src/acl/FilledChecklist.cc | 12 ++++++++++++ src/acl/FilledChecklist.h | 2 ++ src/client_side.cc | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 017334e0cb7..b2bb26ca2ad 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -253,6 +253,18 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) } } +void ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) +{ + if (!aConn) + return; + const auto clientConn = aConn->clientConnection; + if (clientConn) { + src_addr = clientConn->remote; + my_addr = clientConn->local; + } + clientConnectionManager(aConn); +} + void ACLFilledChecklist::setIdent(const char *ident) { diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 4f37fd0516d..13f20d05daf 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -52,6 +52,8 @@ class ACLFilledChecklist: public ACLChecklist /// set either conn void clientConnectionManager(ConnStateData *); + + void setClientConnectionManager(ConnStateData *); /// set the client side FD void fd(int aDescriptor); diff --git a/src/client_side.cc b/src/client_side.cc index 30206ced825..aef35517663 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -437,6 +437,10 @@ ClientHttpRequest::logRequest() } ACLFilledChecklist checklist(NULL, request, NULL); + + if (!request) + checklist.setClientConnectionManager(getConn()); + if (al->reply) { checklist.reply = al->reply; HTTPMSGLOCK(checklist.reply); From 26569e2dce764585e8def0f69cb4a23d2ef7ab4f Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Feb 2019 21:58:46 +0300 Subject: [PATCH 07/66] Simplified and renamed HttpRequest::manager() ... partially moving its functionality into the constructor. It is possible to initialize early since clientConnectionManager is available there. --- src/HttpRequest.cc | 41 +++++++++++++++++++---------------------- src/HttpRequest.h | 4 ++-- src/client_side.cc | 4 ++-- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 33f252dd337..0087a1ded63 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -115,6 +115,19 @@ HttpRequest::init() rangeOffsetLimit = -2; //a value of -2 means not checked yet forcedBodyContinuation = false; internal = false; + + if (hasClientConnectionManager()) { + if (const auto port = clientConnectionManager()->port) { + myportname = port->name; + flags.ignoreCc = port->ignore_cc; + } +#if FOLLOW_X_FORWARDED_FOR + // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) + // not details about the TCP connection itself + if (clientConnection()) + indirect_client_addr = clientConnection()->remote; +#endif /* FOLLOW_X_FORWARDED_FOR */ + } } void @@ -765,32 +778,16 @@ HttpRequest::resetIndirectClientAddr() #endif /* FOLLOW_X_FORWARDED_FOR */ void -HttpRequest::manager(const CbcPointer &aMgr, const AccessLogEntryPointer &al) +HttpRequest::setInterceptionFlags(const AccessLogEntryPointer &al) { - masterXaction->clientConnectionManager = aMgr; - - if (!clientConnectionManager().valid()) - return; - - AnyP::PortCfgPointer port = clientConnectionManager()->port; - if (port) { - myportname = port->name; - flags.ignoreCc = port->ignore_cc; - } - - if (auto clientConnection = clientConnectionManager()->clientConnection) { -#if FOLLOW_X_FORWARDED_FOR - // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) - // not details about the TCP connection itself - indirect_client_addr = clientConnection->remote; -#endif /* FOLLOW_X_FORWARDED_FOR */ - - flags.intercepted = ((clientConnection->flags & COMM_INTERCEPTION) != 0); - flags.interceptTproxy = ((clientConnection->flags & COMM_TRANSPARENT) != 0 ) ; + if (const auto connection = clientConnection()) { + flags.intercepted = ((connection->flags & COMM_INTERCEPTION) != 0); + flags.interceptTproxy = ((connection->flags & COMM_TRANSPARENT) != 0 ) ; + const auto port = clientConnectionManager()->port; const bool proxyProtocolPort = port ? port->flags.proxySurrogate : false; if (flags.interceptTproxy && !proxyProtocolPort) { if (Config.accessList.spoof_client_ip) { - ACLFilledChecklist *checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, clientConnection->rfc931); + ACLFilledChecklist *checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, connection->rfc931); checklist->al = al; checklist->syncAle(this, nullptr); flags.spoofClientIp = checklist->fastCheck().allowed(); diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 1a42e370965..7ff087cde2a 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -94,8 +94,8 @@ class HttpRequest: public Http::Message /// clear error details, useful for retries/repeats void clearError(); - /// associates the request with a from-client connection manager - void manager(const CbcPointer &aMgr, const AccessLogEntryPointer &al); + /// sets TPROXY-related flags + void setInterceptionFlags(const AccessLogEntryPointer &al); protected: void clean(); diff --git a/src/client_side.cc b/src/client_side.cc index aef35517663..480a0b29f13 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1626,7 +1626,7 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp, // this entire function to remove them from the FTP code path. Connection // setup and body_pipe preparation blobs are needed for FTP. - request->manager(conn, http->al); + request->setInterceptionFlags(http->al); request->flags.accelerated = http->flags.accel; request->flags.sslBumped=conn->switchedToHttps(); @@ -3278,7 +3278,7 @@ ConnStateData::buildFakeRequest(Http::MethodType const method, SBuf &useHost, un request->url.port(usePort); http->initRequest(request.getRaw()); - request->manager(this, http->al); + request->setInterceptionFlags(http->al); if (proto == AnyP::PROTO_HTTP) request->header.putStr(Http::HOST, useHost.c_str()); From 9364706afae33be758a3b7efaa513494e2e4823d Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 7 Mar 2019 17:32:38 +0300 Subject: [PATCH 08/66] Assign ACLFilledChecklist addresses with a new API This work was started at 7dd8f6. Now addresses (and the connection manager itself) are assigned by means of clientConnectionManager() and clientConnection() methods. --- src/acl/FilledChecklist.cc | 24 +++++++++++++++++------- src/acl/FilledChecklist.h | 11 +++++++---- src/client_side.cc | 24 ++++++++++-------------- src/client_side_request.cc | 1 + src/comm/TcpAcceptor.cc | 3 +-- src/servers/FtpServer.cc | 1 + src/servers/Http1Server.cc | 1 + 7 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index b2bb26ca2ad..477b7366bd3 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -147,7 +147,7 @@ ACLFilledChecklist::clientConnectionManager() const } void -ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) +ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) { if (clientConnectionManager() == aConn) return; @@ -249,22 +249,32 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) my_addr = request->myAddr(); if (request->clientConnectionManager().valid()) - clientConnectionManager(request->clientConnectionManager().get()); + setClientConnectionManager(request->clientConnectionManager().get()); } } -void ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) +void ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) { - if (!aConn) + if (!(aConn && cbdataReferenceValid(aConn)) || request) return; - const auto clientConn = aConn->clientConnection; - if (clientConn) { + + setClientConnectionManager(aConn); + + if (const auto clientConn = aConn->clientConnection) { src_addr = clientConn->remote; my_addr = clientConn->local; } - clientConnectionManager(aConn); } +void ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) +{ + if(!conn) + return; + src_addr = conn->remote; + my_addr = conn->local; +} + + void ACLFilledChecklist::setIdent(const char *ident) { diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 13f20d05daf..b5693db3167 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -13,6 +13,7 @@ #include "acl/Checklist.h" #include "acl/forward.h" #include "base/CbcPointer.h" +#include "comm/forward.h" #include "err_type.h" #include "ip/Address.h" #if USE_AUTH @@ -47,13 +48,13 @@ class ACLFilledChecklist: public ACLChecklist /// The client connection manager ConnStateData * clientConnectionManager() const; + void clientConnectionManager(ConnStateData *); + + void clientConnection(Comm::ConnectionPointer); + /// The client side fd. It uses conn() if available int fd() const; - /// set either conn - void clientConnectionManager(ConnStateData *); - - void setClientConnectionManager(ConnStateData *); /// set the client side FD void fd(int aDescriptor); @@ -101,6 +102,8 @@ class ACLFilledChecklist: public ACLChecklist err_type requestErrorType; private: + void setClientConnectionManager(ConnStateData *); + ConnStateData * conn_; /**< hack for ident and NTLM */ int fd_; /**< may be available when conn_ is not */ bool destinationDomainChecked_; diff --git a/src/client_side.cc b/src/client_side.cc index 480a0b29f13..d38f04554be 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -437,9 +437,7 @@ ClientHttpRequest::logRequest() } ACLFilledChecklist checklist(NULL, request, NULL); - - if (!request) - checklist.setClientConnectionManager(getConn()); + checklist.clientConnectionManager(getConn()); if (al->reply) { checklist.reply = al->reply; @@ -458,6 +456,7 @@ ClientHttpRequest::logRequest() bool updatePerformanceCounters = true; if (Config.accessList.stats_collection) { ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, NULL); + statsCheck.clientConnectionManager(getConn()); statsCheck.al = al; if (al->reply) { statsCheck.reply = al->reply; @@ -1517,6 +1516,7 @@ bool ConnStateData::serveDelayedError(Http::Stream *context) bool allowDomainMismatch = false; if (Config.ssl_client.cert_error) { ACLFilledChecklist check(Config.ssl_client.cert_error, request, dash_str); + check.clientConnectionManager(this); check.al = http->al; check.sslErrors = new Security::CertErrors(Security::CertError(SQUID_X509_V_ERR_DOMAIN_MISMATCH, srvCert)); check.syncAle(request, http->log_uri); @@ -1564,11 +1564,7 @@ clientTunnelOnError(ConnStateData *conn, Http::StreamPointer &context, HttpReque ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request.getRaw(), nullptr); checklist.al = (context && context->http) ? context->http->al : nullptr; checklist.requestErrorType = requestError; - if (!request) { - checklist.src_addr = conn->clientConnection->remote; - checklist.my_addr = conn->clientConnection->local; - checklist.clientConnectionManager(conn); - } + checklist.clientConnectionManager(conn); ClientHttpRequest *http = context ? context->http : nullptr; const char *log_uri = http ? http->log_uri : nullptr; checklist.syncAle(request.getRaw(), log_uri); @@ -1814,8 +1810,6 @@ ConnStateData::proxyProtocolValidateClient() return proxyProtocolError("PROXY client not permitted by default ACL"); ACLFilledChecklist ch(Config.accessList.proxyProtocol, NULL, clientConnection->rfc931); - ch.src_addr = clientConnection->remote; - ch.my_addr = clientConnection->local; ch.clientConnectionManager(this); if (!ch.fastCheck().allowed()) @@ -2259,8 +2253,7 @@ ConnStateData::whenClientIpKnown() #if USE_IDENT if (Ident::TheConfig.identLookup) { ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, NULL, NULL); - identChecklist.src_addr = clientConnection->remote; - identChecklist.my_addr = clientConnection->local; + identChecklist.clientConnectionManager(this); if (identChecklist.fastCheck().allowed()) Ident::Start(clientConnection, clientIdentDone, this); } @@ -2277,12 +2270,11 @@ ConnStateData::whenClientIpKnown() const auto &pools = ClientDelayPools::Instance()->pools; if (pools.size()) { ACLFilledChecklist ch(NULL, NULL, NULL); + ch.clientConnectionManager(this); // TODO: we check early to limit error response bandwith but we // should recheck when we can honor delay_pool_uses_indirect // TODO: we should also pass the port details for myportname here. - ch.src_addr = clientConnection->remote; - ch.my_addr = clientConnection->local; for (unsigned int pool = 0; pool < pools.size(); ++pool) { @@ -2627,6 +2619,7 @@ ConnStateData::postHttpsAccept() request->myportname = port->name; ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL); + acl_checklist->clientConnectionManager(this); // Build a local AccessLogEntry to allow requiresAle() acls work acl_checklist->al = new AccessLogEntry; acl_checklist->al->cache.start_time = current_time; @@ -2714,6 +2707,7 @@ void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &cer ACLFilledChecklist checklist(NULL, sslServerBump->request.getRaw(), clientConnection != NULL ? clientConnection->rfc931 : dash_str); + checklist.clientConnectionManager(this); checklist.sslErrors = cbdataReference(sslServerBump->sslErrors()); for (sslproxy_cert_adapt *ca = Config.ssl_client.cert_adapt; ca != NULL; ca = ca->next) { @@ -3100,6 +3094,7 @@ ConnStateData::startPeekAndSplice() // Run a accessList check to check if want to splice or continue bumping ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, sslServerBump->request.getRaw(), nullptr); + acl_checklist->clientConnectionManager(this); acl_checklist->al = http ? http->al : nullptr; //acl_checklist->src_addr = params.conn->remote; //acl_checklist->my_addr = s->s; @@ -3557,6 +3552,7 @@ clientAclChecklistFill(ACLFilledChecklist &checklist, ClientHttpRequest *http) // then call setIdent() inside checklist.setRequest(). Otherwise, restore // USE_IDENT lost in commit 94439e4. ConnStateData * conn = http->getConn(); + checklist.clientConnectionManager(conn); const char *ident = (cbdataReferenceValid(conn) && conn && conn->clientConnection) ? conn->clientConnection->rfc931 : dash_str; diff --git a/src/client_side_request.cc b/src/client_side_request.cc index d43000247e7..08ca38920f2 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1797,6 +1797,7 @@ ClientHttpRequest::doCallouts() // Set appropriate MARKs and CONNMARKs if needed. if (getConn() && Comm::IsConnOpen(getConn()->clientConnection)) { ACLFilledChecklist ch(nullptr, request, nullptr); + ch.clientConnectionManager(getConn()); ch.al = calloutContext->http->al; ch.syncAle(request, log_uri); diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index ee9756382a7..e1b270e8f23 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -263,8 +263,7 @@ logAcceptError(const Comm::ConnectionPointer &conn) al->url = "error:accept-client-connection"; al->setVirginUrlForMissingRequest(al->url); ACLFilledChecklist ch(nullptr, nullptr, nullptr); - ch.src_addr = conn->remote; - ch.my_addr = conn->local; + ch.clientConnection(conn); ch.al = al; accessLogLog(al, &ch); } diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index ed7c7988a5f..113f93357ea 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1544,6 +1544,7 @@ Ftp::Server::handleUploadRequest(String &, String &) ClientHttpRequest *http = pipeline.front()->http; HttpRequest *request = http->request; ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, NULL); + bodyContinuationCheck.clientConnectionManager(this); bodyContinuationCheck.al = http->al; bodyContinuationCheck.syncAle(request, http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index 66031733c84..f9a1960c812 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -257,6 +257,7 @@ Http::One::Server::processParsedRequest(Http::StreamPointer &context) if (Config.accessList.forceRequestBodyContinuation) { ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), NULL); + bodyContinuationCheck.clientConnectionManager(this); bodyContinuationCheck.al = http->al; bodyContinuationCheck.syncAle(request.getRaw(), http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { From c6272934698922169f6bc3da3fe440b136038087 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 11 Mar 2019 14:10:54 +0300 Subject: [PATCH 09/66] Polished ACLFilledChecklist's clientConnection* methods --- src/acl/FilledChecklist.cc | 26 +++++++++++++++----------- src/acl/FilledChecklist.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 477b7366bd3..cf87af09206 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -149,9 +149,9 @@ ACLFilledChecklist::clientConnectionManager() const void ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) { - if (clientConnectionManager() == aConn) + if (!(aConn && cbdataReferenceValid(aConn))) return; - assert (clientConnectionManager() == NULL); + assert(!clientConnectionManager()); conn_ = cbdataReference(aConn); } @@ -247,34 +247,38 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) HTTPMSGLOCK(request); src_addr = request->effectiveClientAddr(); my_addr = request->myAddr(); - - if (request->clientConnectionManager().valid()) - setClientConnectionManager(request->clientConnectionManager().get()); + setClientConnectionManager(request->clientConnectionManager().get()); } } void ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) { - if (!(aConn && cbdataReferenceValid(aConn)) || request) + if (request) return; setClientConnectionManager(aConn); - if (const auto clientConn = aConn->clientConnection) { - src_addr = clientConn->remote; - my_addr = clientConn->local; - } + if (clientConnectionManager()) + setClientConnection(clientConnectionManager()->clientConnection); } void ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) +{ + if (request || clientConnectionManager()) + return; + + setClientConnection(conn); +} + +void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) { if(!conn) return; + src_addr = conn->remote; my_addr = conn->local; } - void ACLFilledChecklist::setIdent(const char *ident) { diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index b5693db3167..20bed51a8f1 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -103,6 +103,7 @@ class ACLFilledChecklist: public ACLChecklist private: void setClientConnectionManager(ConnStateData *); + void setClientConnection(Comm::ConnectionPointer); ConnStateData * conn_; /**< hack for ident and NTLM */ int fd_; /**< may be available when conn_ is not */ From b4fa893c2af6f08ad0affb6bf4e62c44b52b26c6 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 11 Mar 2019 15:45:13 +0300 Subject: [PATCH 10/66] Simplified, removing HttpRequest::hasClientConnectionManager() --- src/Downloader.cc | 1 + src/HttpRequest.cc | 8 +++----- src/HttpRequest.h | 7 +++++-- src/client_side_request.cc | 2 +- src/peer_select.cc | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Downloader.cc b/src/Downloader.cc index 396658f2313..75a98d5f6a4 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -136,6 +136,7 @@ Downloader::buildRequest() return false; //earlyError(...) } request->setDownloader(this); + request->setInternal(); debugs(11, 2, "HTTP Client Downloader " << this << "/" << id); debugs(11, 2, "HTTP Client REQUEST:\n---------\n" << diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 0087a1ded63..fca60c6ba58 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -116,7 +116,7 @@ HttpRequest::init() forcedBodyContinuation = false; internal = false; - if (hasClientConnectionManager()) { + if (clientConnectionManager().valid()) { if (const auto port = clientConnectionManager()->port) { myportname = port->name; flags.ignoreCc = port->ignore_cc; @@ -728,7 +728,6 @@ HttpRequest::setDownloader(Downloader *d) header.putStr(Http::HdrType::HOST, url.host()); header.putTime(Http::HdrType::DATE, squid_curtime); downloader = d; - internal = true; } const Ip::Address& @@ -857,7 +856,6 @@ FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry Comm::ConnectionPointer HttpRequest::clientConnection() const { - if (hasClientConnectionManager()) - return masterXaction->clientConnectionManager->clientConnection; - return nullptr; + return masterXaction->clientConnectionManager.valid() ? + masterXaction->clientConnectionManager->clientConnection : nullptr; } diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 7ff087cde2a..68b6d2331a3 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -138,7 +138,8 @@ class HttpRequest: public Http::Message int imslen; - void setInternal(const bool val) { internal = val; } + /// this request is internally built + void setInternal() { internal = true; } void setDownloader(Downloader *); @@ -149,13 +150,14 @@ class HttpRequest: public Http::Message const Ip::Address& effectiveClientAddr() const; CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager; } - bool hasClientConnectionManager() const { return masterXaction->clientConnectionManager.valid(); } Comm::ConnectionPointer clientConnection() const; #if FOLLOW_X_FORWARDED_FOR const Ip::Address& indirectClientAddr() const; + void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } + void resetIndirectClientAddr(); #endif /* FOLLOW_X_FORWARDED_FOR */ @@ -262,6 +264,7 @@ class HttpRequest: public Http::Message Ip::Address indirect_client_addr; #endif /* FOLLOW_X_FORWARDED_FOR */ + /// whether this is an internally built request bool internal; protected: diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 08ca38920f2..28a773fe8ab 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -378,7 +378,7 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre /* Internally created requests cannot have bodies today */ request->content_length = 0; - request->setInternal(true); + request->setInternal(); request->http_ver = Http::ProtocolVersion(); diff --git a/src/peer_select.cc b/src/peer_select.cc index 5bb242bbcff..3e6beb30a49 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -286,7 +286,7 @@ PeerSelector::resolveSelected() const bool choseDirect = fs && fs->code == HIER_DIRECT; if (isIntercepted && useOriginalDst && choseDirect) { // check the client is still around before using any of its details - if (req->hasClientConnectionManager()) { + if (req->clientConnection()) { // construct a "result" adding the ORIGINAL_DST to the set instead of DIRECT Comm::ConnectionPointer p = new Comm::Connection(); p->remote = req->clientConnection()->local; From f6d82648df10d2d654ccc5d61bc5773c4cd3b3da Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 11 Mar 2019 17:50:44 +0300 Subject: [PATCH 11/66] Made ACLFilledChecklist::src_addr private Also fixed HttpRequest::effectiveClientAddr(). --- src/DelayId.cc | 2 +- src/FwdState.cc | 6 +++++- src/HttpRequest.cc | 10 ++++++---- src/HttpRequest.h | 5 ++++- src/acl/Arp.cc | 6 +++--- src/acl/Asn.cc | 2 +- src/acl/Eui64.cc | 10 +++++----- src/acl/FilledChecklist.cc | 10 +++++++++- src/acl/FilledChecklist.h | 6 +++++- src/acl/MaxConnection.cc | 2 +- src/acl/SourceDomain.cc | 6 +++--- src/acl/SourceIp.cc | 2 +- src/adaptation/ecap/XactionRep.cc | 2 +- src/adaptation/icap/ModXact.cc | 2 +- src/auth/Acl.cc | 4 +++- src/auth/AclMaxUserIp.cc | 2 +- src/client_side_request.cc | 4 ---- src/htcp.cc | 33 ++++++++++++++++++------------- src/icp_v2.cc | 2 +- src/snmp_core.cc | 2 +- 20 files changed, 71 insertions(+), 47 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 82890ac9e77..17f411b5fdc 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -95,7 +95,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) DelayId result (pool + 1); CompositePoolNode::CompositeSelectionDetails details; - details.src_addr = ch.src_addr; + details.src_addr = ch.srcAddr(); #if USE_AUTH details.user = r->auth_user_request; #endif diff --git a/src/FwdState.cc b/src/FwdState.cc index c7d9da1cbdf..535771063d6 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -1356,7 +1356,11 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) // maybe use TPROXY client address if (request && request->flags.spoofClientIp) { if (!conn->getPeer() || !conn->getPeer()->options.no_tproxy) { - conn->local = request->effectiveClientAddr(); +#if LINUX_NETFILTER + conn->local = request->effectiveClientAddr(Config.onoff.tproxy_uses_indirect_client); +#else + conn->local = request->clientAddr(); +#endif conn->local.port(0); // let OS pick the source port to prevent address clashes // some flags need setting on the socket to use this address conn->flags |= COMM_DOBIND; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index fca60c6ba58..e395a740845 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -731,10 +731,10 @@ HttpRequest::setDownloader(Downloader *d) } const Ip::Address& -HttpRequest::effectiveClientAddr() const +HttpRequest::effectiveClientAddr(const bool useIndirect) const { -#if FOLLOW_X_FORWARDED_FOR && LINUX_NETFILTER - if (Config.onoff.tproxy_uses_indirect_client) +#if FOLLOW_X_FORWARDED_FOR + if (useIndirect) return indirectClientAddr(); else #endif @@ -752,7 +752,9 @@ NoAddr() const Ip::Address& HttpRequest::clientAddr() const { - return internal ? NoAddr() : masterXaction->tcpClient->remote; + return internal ? NoAddr() : + masterXaction->tcpClient ? + masterXaction->tcpClient->remote : src_addr; } const Ip::Address& diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 68b6d2331a3..006892c5405 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -145,9 +145,11 @@ class HttpRequest: public Http::Message const Ip::Address& clientAddr() const; + void srcAddr(const Ip::Address &addr) { src_addr = addr; } + const Ip::Address& myAddr() const; - const Ip::Address& effectiveClientAddr() const; + const Ip::Address& effectiveClientAddr(const bool) const; CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager; } @@ -260,6 +262,7 @@ class HttpRequest: public Http::Message /// and(or) by annotate_transaction/annotate_client ACLs. NotePairs::Pointer theNotes; + Ip::Address src_addr; #if FOLLOW_X_FORWARDED_FOR Ip::Address indirect_client_addr; #endif /* FOLLOW_X_FORWARDED_FOR */ diff --git a/src/acl/Arp.cc b/src/acl/Arp.cc index fa84c41aed2..62ae067c761 100644 --- a/src/acl/Arp.cc +++ b/src/acl/Arp.cc @@ -115,13 +115,13 @@ ACLARP::match(ACLChecklist *cl) ACLFilledChecklist *checklist = Filled(cl); /* IPv6 does not do ARP */ - if (!checklist->src_addr.isIPv4()) { - debugs(14, 3, "ACLARP::match: IPv4 Required for ARP Lookups. Skipping " << checklist->src_addr ); + if (!checklist->srcAddr().isIPv4()) { + debugs(14, 3, "ACLARP::match: IPv4 Required for ARP Lookups. Skipping " << checklist->srcAddr() ); return 0; } Eui::Eui48 lookingFor; - lookingFor.lookup(checklist->src_addr); + lookingFor.lookup(checklist->srcAddr()); return (aclArpData.find(lookingFor) != aclArpData.end()); } diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index af0c2d31a02..7990cb1fe37 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -586,7 +586,7 @@ template class ACLStrategised; int ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { - return data->match(checklist->src_addr); + return data->match(checklist->srcAddr()); } int diff --git a/src/acl/Eui64.cc b/src/acl/Eui64.cc index 0d23854ec25..6d283c90317 100644 --- a/src/acl/Eui64.cc +++ b/src/acl/Eui64.cc @@ -87,19 +87,19 @@ ACLEui64::match(ACLChecklist *cl) ACLFilledChecklist *checklist = Filled(cl); /* IPv4 does not do EUI-64 (yet) */ - if (!checklist->src_addr.isIPv6()) { - debugs(14, 3, "ACLEui64::match: IPv6 Required for EUI-64 Lookups. Skipping " << checklist->src_addr ); + if (!checklist->srcAddr().isIPv6()) { + debugs(14, 3, "ACLEui64::match: IPv6 Required for EUI-64 Lookups. Skipping " << checklist->srcAddr() ); return 0; } Eui::Eui64 lookingFor; - if (lookingFor.lookup(checklist->src_addr)) { + if (lookingFor.lookup(checklist->srcAddr())) { bool found = (eui64Data.find(lookingFor) != eui64Data.end()); - debugs(28, 3, checklist->src_addr << "' " << (found ? "found" : "NOT found")); + debugs(28, 3, checklist->srcAddr() << "' " << (found ? "found" : "NOT found")); return found; } - debugs(28, 3, checklist->src_addr << " NOT found"); + debugs(28, 3, checklist->srcAddr() << " NOT found"); return 0; } diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index cf87af09206..0e74745b212 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -245,7 +245,7 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) if (httpRequest) { request = httpRequest; HTTPMSGLOCK(request); - src_addr = request->effectiveClientAddr(); + src_addr = request->effectiveClientAddr(Config.onoff.acl_uses_indirect_client); my_addr = request->myAddr(); setClientConnectionManager(request->clientConnectionManager().get()); } @@ -270,6 +270,14 @@ void ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) setClientConnection(conn); } +void ACLFilledChecklist::srcAddr(const Ip::Address &addr) +{ + if (request || clientConnectionManager()) + return; + + src_addr = addr; +} + void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) { if(!conn) diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 20bed51a8f1..2c68e22b928 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -52,6 +52,8 @@ class ACLFilledChecklist: public ACLChecklist void clientConnection(Comm::ConnectionPointer); + void srcAddr(const Ip::Address &addr); + /// The client side fd. It uses conn() if available int fd() const; @@ -72,8 +74,9 @@ class ACLFilledChecklist: public ACLChecklist virtual void syncAle(HttpRequest *adaptedRequest, const char *logUri) const; virtual void verifyAle() const; + const Ip::Address &srcAddr() const { return src_addr; } + public: - Ip::Address src_addr; Ip::Address dst_addr; Ip::Address my_addr; SBuf dst_peer_name; @@ -109,6 +112,7 @@ class ACLFilledChecklist: public ACLChecklist int fd_; /**< may be available when conn_ is not */ bool destinationDomainChecked_; bool sourceDomainChecked_; + Ip::Address src_addr; /// not implemented; will cause link failures if used ACLFilledChecklist(const ACLFilledChecklist &); /// not implemented; will cause link failures if used diff --git a/src/acl/MaxConnection.cc b/src/acl/MaxConnection.cc index 4e61c468e7e..fbeae3d2e6c 100644 --- a/src/acl/MaxConnection.cc +++ b/src/acl/MaxConnection.cc @@ -75,7 +75,7 @@ ACLMaxConnection::parse() int ACLMaxConnection::match(ACLChecklist *checklist) { - return clientdbEstablished(Filled(checklist)->src_addr, 0) > limit ? 1 : 0; + return clientdbEstablished(Filled(checklist)->srcAddr(), 0) > limit ? 1 : 0; } SBufList diff --git a/src/acl/SourceDomain.cc b/src/acl/SourceDomain.cc index 9193c8469bd..498f2fa3426 100644 --- a/src/acl/SourceDomain.cc +++ b/src/acl/SourceDomain.cc @@ -28,7 +28,7 @@ SourceDomainLookup::Instance() void SourceDomainLookup::checkForAsync(ACLChecklist *checklist) const { - fqdncache_nbgethostbyaddr(Filled(checklist)->src_addr, LookupDone, checklist); + fqdncache_nbgethostbyaddr(Filled(checklist)->srcAddr(), LookupDone, checklist); } void @@ -44,13 +44,13 @@ int ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { const char *fqdn = NULL; - fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); + fqdn = fqdncache_gethostbyaddr(checklist->srcAddr(), FQDN_LOOKUP_IF_MISS); if (fqdn) { return data->match(fqdn); } else if (!checklist->sourceDomainChecked()) { /* FIXME: Using AclMatchedName here is not OO correct. Should find a way to the current acl */ - debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << checklist->src_addr << "'"); + debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << checklist->srcAddr() << "'"); if (checklist->goAsync(SourceDomainLookup::Instance())) return -1; // else fall through to "none" match, hiding the lookup failure (XXX) diff --git a/src/acl/SourceIp.cc b/src/acl/SourceIp.cc index 7e8c38e4114..16facc54d75 100644 --- a/src/acl/SourceIp.cc +++ b/src/acl/SourceIp.cc @@ -21,7 +21,7 @@ ACLSourceIP::typeString() const int ACLSourceIP::match(ACLChecklist *checklist) { - return ACLIP::match(Filled(checklist)->src_addr); + return ACLIP::match(Filled(checklist)->srcAddr()); } ACL * diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index d4242d7c2cd..83d13ff72fe 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -128,7 +128,7 @@ Adaptation::Ecap::XactionRep::clientIpValue() const // TODO: move this logic into HttpRequest::clientIp(bool) and // HttpRequest::clientIpString(bool) and reuse everywhere if (TheConfig.send_client_ip && request) { - Ip::Address client_addr = request->effectiveClientAddr(); + Ip::Address client_addr = request->effectiveClientAddr(TheConfig.use_indirect_client); if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) { char ntoabuf[MAX_IPSTRLEN] = ""; client_addr.toStr(ntoabuf,MAX_IPSTRLEN); diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index 23cf903593c..72d043b3a03 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1473,7 +1473,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) if (TheConfig.send_client_ip && request) { Ip::Address client_addr; - client_addr = request->effectiveClientAddr(); + client_addr = request->effectiveClientAddr(TheConfig.use_indirect_client); if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) buf.appendf("X-Client-IP: %s\r\n", client_addr.toStr(ntoabuf,MAX_IPSTRLEN)); } diff --git a/src/auth/Acl.cc b/src/auth/Acl.cc index 1129bd5ddf5..d13d1b6e9ce 100644 --- a/src/auth/Acl.cc +++ b/src/auth/Acl.cc @@ -54,9 +54,11 @@ AuthenticateAcl(ACLChecklist *ch) /* get authed here */ /* Note: this fills in auth_user_request when applicable */ + // TODO: instead of this, make src_addr parameter constant + Ip::Address tmpAddr(checklist->srcAddr()); const AuthAclState result = Auth::UserRequest::tryToAuthenticateAndSetAuthUser( &checklist->auth_user_request, headertype, request, - checklist->clientConnectionManager(), checklist->src_addr, checklist->al); + checklist->clientConnectionManager(), tmpAddr, checklist->al); switch (result) { case AUTH_ACL_CANNOT_AUTHENTICATE: diff --git a/src/auth/AclMaxUserIp.cc b/src/auth/AclMaxUserIp.cc index 72dc1fe283a..b9f92e9cd7b 100644 --- a/src/auth/AclMaxUserIp.cc +++ b/src/auth/AclMaxUserIp.cc @@ -129,7 +129,7 @@ ACLMaxUserIP::match(ACLChecklist *cl) switch (answer) { case ACCESS_ALLOWED: // check for a match - ti = match(checklist->auth_user_request, checklist->src_addr); + ti = match(checklist->auth_user_request, checklist->srcAddr()); checklist->auth_user_request = NULL; return ti; diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 28a773fe8ab..2dee63b97c0 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -474,10 +474,6 @@ clientFollowXForwardedForCheck(allow_t answer, void *data) request->indirectClientAddr(addr); request->x_forwarded_for_iterator.cut(l); calloutContext->acl_checklist = clientAclChecklistCreate(Config.accessList.followXFF, http); - if (!Config.onoff.acl_uses_indirect_client) { - /* override the default src_addr tested if we have to go deeper than one level into XFF */ - Filled(calloutContext->acl_checklist)->src_addr = request->indirectClientAddr(); - } calloutContext->acl_checklist->nonBlockingCheck(clientFollowXForwardedForCheck, data); return; } diff --git a/src/htcp.cc b/src/htcp.cc index 66bf7a5f079..5511be8d19f 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -129,7 +129,14 @@ class htcpSpecifier : public RefCountable, public StoreClient void checkHit(); void checkedHit(StoreEntry *); - void setFrom(Ip::Address &anIp) { from = anIp; } + const Ip::Address &from() const { + assert(request); + return request->clientAddr(); + } + void setFrom(Ip::Address &anIp) { + assert(request); + request->srcAddr(anIp); + } void setDataHeader(htcpDataHeader *aDataHeader) { dhdr = aDataHeader; } @@ -153,7 +160,6 @@ class htcpSpecifier : public RefCountable, public StoreClient private: HttpRequest::Pointer checkHitRequest; - Ip::Address from; htcpDataHeader *dhdr = nullptr; }; @@ -254,14 +260,14 @@ static ssize_t htcpBuildTstOpData(char *buf, size_t buflen, htcpStuff * stuff); static void htcpHandleMsg(char *buf, int sz, Ip::Address &from); -static void htcpLogHtcp(Ip::Address &, const int, const LogTags_ot, const char *, AccessLogEntryPointer); +static void htcpLogHtcp(const Ip::Address &, const int, const LogTags_ot, const char *, AccessLogEntryPointer); static void htcpHandleTst(htcpDataHeader *, char *buf, int sz, Ip::Address &from); static void htcpRecv(int fd, void *data); -static void htcpSend(const char *buf, int len, Ip::Address &to); +static void htcpSend(const char *buf, int len, const Ip::Address &to); -static void htcpTstReply(htcpDataHeader *, StoreEntry *, htcpSpecifier *, Ip::Address &); +static void htcpTstReply(htcpDataHeader *, StoreEntry *, htcpSpecifier *, const Ip::Address &); static void htcpHandleTstRequest(htcpDataHeader *, char *buf, int sz, Ip::Address &from); @@ -583,7 +589,7 @@ htcpBuildPacket(char *buf, size_t buflen, htcpStuff * stuff) } static void -htcpSend(const char *buf, int len, Ip::Address &to) +htcpSend(const char *buf, int len, const Ip::Address &to) { debugs(31, 3, to); htcpHexdump("htcpSend", buf, len); @@ -794,13 +800,12 @@ htcpAccessAllowed(acl_access * acl, const htcpSpecifier::Pointer &s, Ip::Address return false; ACLFilledChecklist checklist(acl, s->request.getRaw(), nullptr); - checklist.src_addr = from; checklist.my_addr.setNoAddr(); return checklist.fastCheck().allowed(); } static void -htcpTstReply(htcpDataHeader * dhdr, StoreEntry * e, htcpSpecifier * spec, Ip::Address &from) +htcpTstReply(htcpDataHeader * dhdr, StoreEntry * e, htcpSpecifier * spec, const Ip::Address &from) { static char pkt[8192]; HttpHeader hdr(hoHtcpReply); @@ -973,7 +978,7 @@ void htcpSpecifier::fillChecklist(ACLFilledChecklist &checklist) const { checklist.setRequest(request.getRaw()); - htcpSyncAle(al, from, dhdr->opcode, uri); + htcpSyncAle(al, from(), dhdr->opcode, uri); checklist.al = al; } @@ -1157,11 +1162,11 @@ void htcpSpecifier::checkedHit(StoreEntry *e) { if (e) { - htcpTstReply(dhdr, e, this, from); /* hit */ - htcpLogHtcp(from, dhdr->opcode, LOG_UDP_HIT, uri, al); + htcpTstReply(dhdr, e, this, from()); /* hit */ + htcpLogHtcp(from(), dhdr->opcode, LOG_UDP_HIT, uri, al); } else { - htcpTstReply(dhdr, NULL, NULL, from); /* cache miss */ - htcpLogHtcp(from, dhdr->opcode, LOG_UDP_MISS, uri, al); + htcpTstReply(dhdr, NULL, NULL, from()); /* cache miss */ + htcpLogHtcp(from(), dhdr->opcode, LOG_UDP_MISS, uri, al); } } @@ -1625,7 +1630,7 @@ htcpClosePorts(void) } static void -htcpLogHtcp(Ip::Address &caddr, const int opcode, const LogTags_ot logcode, const char *url, AccessLogEntryPointer al) +htcpLogHtcp(const Ip::Address &caddr, const int opcode, const LogTags_ot logcode, const char *url, AccessLogEntryPointer al) { if (!Config.onoff.log_udp) return; diff --git a/src/icp_v2.cc b/src/icp_v2.cc index ce913e8b394..87d0d2cd072 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -472,7 +472,6 @@ icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request) return false; ACLFilledChecklist checklist(Config.accessList.icp, icp_request, NULL); - checklist.src_addr = from; checklist.my_addr.setNoAddr(); return checklist.fastCheck().allowed(); } @@ -500,6 +499,7 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) if ((result = HttpRequest::FromUrl(url, mx)) == NULL) icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); + result->srcAddr(from); return result; } diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 07a2f91d7a5..2230ae224fa 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -399,7 +399,7 @@ snmpDecodePacket(SnmpRequest * rq) * default (set above) is to deny all */ if (Community) { ACLFilledChecklist checklist(Config.accessList.snmp, NULL, NULL); - checklist.src_addr = rq->from; + checklist.srcAddr(rq->from); checklist.snmp_community = (char *) Community; if (checklist.fastCheck().allowed() && (snmp_coexist_V2toV1(PDU))) { From fec0823d6658cfcb3d711b2060e040c277052b81 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 12 Mar 2019 20:30:48 +0300 Subject: [PATCH 12/66] Made ACLFilledChecklist::my_addr private --- src/HttpRequest.cc | 4 +++- src/HttpRequest.h | 3 +++ src/acl/FilledChecklist.h | 8 +++++--- src/acl/LocalIp.cc | 2 +- src/acl/LocalPort.cc | 2 +- src/auth/Acl.cc | 4 +--- src/auth/UserRequest.cc | 6 +++--- src/auth/UserRequest.h | 4 ++-- src/htcp.cc | 12 +++++++----- src/icp_v2.cc | 11 +++++++---- 10 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index e395a740845..d735c582610 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -760,7 +760,9 @@ HttpRequest::clientAddr() const const Ip::Address& HttpRequest::myAddr() const { - return internal ? NoAddr() : masterXaction->tcpClient->local; + return internal ? NoAddr(): + masterXaction->tcpClient ? + masterXaction->tcpClient->local : my_addr; } #if FOLLOW_X_FORWARDED_FOR diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 006892c5405..c888c5a8c38 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -149,6 +149,8 @@ class HttpRequest: public Http::Message const Ip::Address& myAddr() const; + void myAddr(const Ip::Address &addr) { my_addr = addr; } + const Ip::Address& effectiveClientAddr(const bool) const; CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager; } @@ -263,6 +265,7 @@ class HttpRequest: public Http::Message NotePairs::Pointer theNotes; Ip::Address src_addr; + Ip::Address my_addr; #if FOLLOW_X_FORWARDED_FOR Ip::Address indirect_client_addr; #endif /* FOLLOW_X_FORWARDED_FOR */ diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 2c68e22b928..ae648805af8 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -54,6 +54,10 @@ class ACLFilledChecklist: public ACLChecklist void srcAddr(const Ip::Address &addr); + const Ip::Address &srcAddr() const { return src_addr; } + + const Ip::Address &myAddr() const { return my_addr; } + /// The client side fd. It uses conn() if available int fd() const; @@ -74,11 +78,8 @@ class ACLFilledChecklist: public ACLChecklist virtual void syncAle(HttpRequest *adaptedRequest, const char *logUri) const; virtual void verifyAle() const; - const Ip::Address &srcAddr() const { return src_addr; } - public: Ip::Address dst_addr; - Ip::Address my_addr; SBuf dst_peer_name; char *dst_rdns; @@ -113,6 +114,7 @@ class ACLFilledChecklist: public ACLChecklist bool destinationDomainChecked_; bool sourceDomainChecked_; Ip::Address src_addr; + Ip::Address my_addr; /// not implemented; will cause link failures if used ACLFilledChecklist(const ACLFilledChecklist &); /// not implemented; will cause link failures if used diff --git a/src/acl/LocalIp.cc b/src/acl/LocalIp.cc index 9e232a3abac..de7210ae9b6 100644 --- a/src/acl/LocalIp.cc +++ b/src/acl/LocalIp.cc @@ -21,7 +21,7 @@ ACLLocalIP::typeString() const int ACLLocalIP::match(ACLChecklist *checklist) { - return ACLIP::match (Filled(checklist)->my_addr); + return ACLIP::match (Filled(checklist)->myAddr()); } ACL * diff --git a/src/acl/LocalPort.cc b/src/acl/LocalPort.cc index 048fa998e1e..a43045a88e8 100644 --- a/src/acl/LocalPort.cc +++ b/src/acl/LocalPort.cc @@ -13,6 +13,6 @@ int ACLLocalPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { - return data->match (checklist->my_addr.port()); + return data->match (checklist->myAddr().port()); } diff --git a/src/auth/Acl.cc b/src/auth/Acl.cc index d13d1b6e9ce..e1af4d8eaef 100644 --- a/src/auth/Acl.cc +++ b/src/auth/Acl.cc @@ -54,11 +54,9 @@ AuthenticateAcl(ACLChecklist *ch) /* get authed here */ /* Note: this fills in auth_user_request when applicable */ - // TODO: instead of this, make src_addr parameter constant - Ip::Address tmpAddr(checklist->srcAddr()); const AuthAclState result = Auth::UserRequest::tryToAuthenticateAndSetAuthUser( &checklist->auth_user_request, headertype, request, - checklist->clientConnectionManager(), tmpAddr, checklist->al); + checklist->clientConnectionManager(), checklist->srcAddr(), checklist->al); switch (result) { case AUTH_ACL_CANNOT_AUTHENTICATE: diff --git a/src/auth/UserRequest.cc b/src/auth/UserRequest.cc index 040484b99d9..f305f6a4a7e 100644 --- a/src/auth/UserRequest.cc +++ b/src/auth/UserRequest.cc @@ -133,7 +133,7 @@ Auth::UserRequest::denyMessage(char const * const default_message) const } static void -authenticateAuthUserRequestSetIp(Auth::UserRequest::Pointer auth_user_request, Ip::Address &ipaddr) +authenticateAuthUserRequestSetIp(Auth::UserRequest::Pointer auth_user_request, const Ip::Address &ipaddr) { Auth::User::Pointer auth_user = auth_user_request->user(); @@ -272,7 +272,7 @@ authTryGetUser(Auth::UserRequest::Pointer auth_user_request, ConnStateData * con * Caller is responsible for locking and unlocking their *auth_user_request! */ AuthAclState -Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request, Http::HdrType headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr, AccessLogEntry::Pointer &al) +Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request, Http::HdrType headertype, HttpRequest * request, ConnStateData * conn, const Ip::Address &src_addr, AccessLogEntry::Pointer &al) { const char *proxy_auth; assert(headertype != 0); @@ -434,7 +434,7 @@ Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request, } AuthAclState -Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer * aUR, Http::HdrType headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr, AccessLogEntry::Pointer &al) +Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer * aUR, Http::HdrType headertype, HttpRequest * request, ConnStateData * conn, const Ip::Address &src_addr, AccessLogEntry::Pointer &al) { // If we have already been called, return the cached value Auth::UserRequest::Pointer t = authTryGetUser(*aUR, conn, request); diff --git a/src/auth/UserRequest.h b/src/auth/UserRequest.h index bd5905f9445..7f0f0b64bd4 100644 --- a/src/auth/UserRequest.h +++ b/src/auth/UserRequest.h @@ -162,7 +162,7 @@ class UserRequest : public RefCountable * * \return Some AUTH_ACL_* state */ - static AuthAclState tryToAuthenticateAndSetAuthUser(UserRequest::Pointer *aUR, Http::HdrType, HttpRequest *, ConnStateData *, Ip::Address &, AccessLogEntry::Pointer &); + static AuthAclState tryToAuthenticateAndSetAuthUser(UserRequest::Pointer *aUR, Http::HdrType, HttpRequest *, ConnStateData *, const Ip::Address &, AccessLogEntry::Pointer &); /// Add the appropriate [Proxy-]Authenticate header to the given reply static void AddReplyAuthHeader(HttpReply * rep, UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal); @@ -221,7 +221,7 @@ class UserRequest : public RefCountable private: - static AuthAclState authenticate(UserRequest::Pointer * auth_user_request, Http::HdrType headertype, HttpRequest * request, ConnStateData * conn, Ip::Address &src_addr, AccessLogEntry::Pointer &al); + static AuthAclState authenticate(UserRequest::Pointer * auth_user_request, Http::HdrType headertype, HttpRequest * request, ConnStateData * conn, const Ip::Address &src_addr, AccessLogEntry::Pointer &al); /** return a message on the 407 error pages */ char *message; diff --git a/src/htcp.cc b/src/htcp.cc index 5511be8d19f..ab37757134c 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -133,9 +133,13 @@ class htcpSpecifier : public RefCountable, public StoreClient assert(request); return request->clientAddr(); } - void setFrom(Ip::Address &anIp) { + void setAddresses(Ip::Address &anIp) { assert(request); request->srcAddr(anIp); + static Ip::Address noAddr; + noAddr.setNoAddr(); + request->myAddr(noAddr); + } void setDataHeader(htcpDataHeader *aDataHeader) { dhdr = aDataHeader; @@ -706,7 +710,6 @@ htcpUnpackSpecifier(char *buf, int sz) debugs(31, 3, "failed to create request. Invalid URI?"); return nil; } - return s; } @@ -800,7 +803,6 @@ htcpAccessAllowed(acl_access * acl, const htcpSpecifier::Pointer &s, Ip::Address return false; ACLFilledChecklist checklist(acl, s->request.getRaw(), nullptr); - checklist.my_addr.setNoAddr(); return checklist.fastCheck().allowed(); } @@ -1137,7 +1139,7 @@ htcpHandleTstRequest(htcpDataHeader * dhdr, char *buf, int sz, Ip::Address &from htcpLogHtcp(from, dhdr->opcode, LOG_UDP_INVALID, dash_str, nullptr); return; } else { - s->setFrom(from); + s->setAddresses(from); s->setDataHeader(dhdr); } @@ -1194,7 +1196,7 @@ htcpHandleClr(htcpDataHeader * hdr, char *buf, int sz, Ip::Address &from) htcpLogHtcp(from, hdr->opcode, LOG_UDP_INVALID, dash_str, nullptr); return; } else { - s->setFrom(from); + s->setAddresses(from); s->setDataHeader(hdr); } diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 87d0d2cd072..2fd6e19ff2a 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -472,7 +472,6 @@ icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request) return false; ACLFilledChecklist checklist(Config.accessList.icp, icp_request, NULL); - checklist.my_addr.setNoAddr(); return checklist.fastCheck().allowed(); } @@ -496,10 +495,14 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) HttpRequest *result; const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp, nullptr); - if ((result = HttpRequest::FromUrl(url, mx)) == NULL) + if ((result = HttpRequest::FromUrl(url, mx)) == NULL) { icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); - - result->srcAddr(from); + } else { + result->srcAddr(from); + static Ip::Address noAddr; + noAddr.setNoAddr(); + result->myAddr(noAddr); + } return result; } From b55f57268e2ce4592b30f7271524eb9dabc6b114 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 14 Mar 2019 00:56:34 +0300 Subject: [PATCH 13/66] Made MasterXaction's connection and connection manager members private Also refactored HttpRequest methods and polishing. --- src/DelayId.cc | 1 + src/Downloader.cc | 6 ++-- src/HttpRequest.cc | 52 +++++++++++++++++++++++----------- src/HttpRequest.h | 19 ++++++------- src/MasterXaction.cc | 18 +++++++++++- src/MasterXaction.h | 18 ++++++++---- src/PeerPoolMgr.cc | 2 +- src/acl/Asn.cc | 2 +- src/acl/FilledChecklist.cc | 14 ++++++--- src/acl/FilledChecklist.h | 10 ++++--- src/adaptation/ecap/Host.cc | 2 +- src/adaptation/icap/Xaction.cc | 2 +- src/client_side.cc | 4 +-- src/client_side_request.cc | 8 +----- src/comm/TcpAcceptor.cc | 4 +-- src/esi/Include.cc | 2 +- src/htcp.cc | 8 ++---- src/icmp/net_db.cc | 2 +- src/icp_v2.cc | 12 +++----- src/mgr/Inquirer.cc | 2 +- src/mime.cc | 2 +- src/neighbors.cc | 2 +- src/servers/FtpServer.cc | 1 - src/servers/Http1Server.cc | 1 - src/servers/Server.cc | 2 +- src/snmp_core.cc | 4 +-- src/tests/testHttpRequest.cc | 6 ++-- 27 files changed, 118 insertions(+), 88 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 17f411b5fdc..4c8988f303e 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -90,6 +90,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) ch.reply = reply; HTTPMSGLOCK(reply); } + ch.applyIndirectClientOption(Config.onoff.delay_pool_uses_indirect_client); if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck().allowed()) { diff --git a/src/Downloader.cc b/src/Downloader.cc index 75a98d5f6a4..ae2c349e39c 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -128,15 +128,13 @@ Downloader::buildRequest() { const HttpRequestMethod method = Http::METHOD_GET; - const MasterXaction::Pointer mx = new MasterXaction(initiator_, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(initiator_); HttpRequest *const request = HttpRequest::FromUrl(url_.c_str(), mx, method); - if (!request) { debugs(33, 5, "Invalid URI: " << url_); return false; //earlyError(...) } - request->setDownloader(this); - request->setInternal(); + request->prepareForDownloader(this); debugs(11, 2, "HTTP Client Downloader " << this << "/" << id); debugs(11, 2, "HTTP Client REQUEST:\n---------\n" << diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index d735c582610..dd33ceb2876 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -85,6 +85,8 @@ HttpRequest::init() ims = -1; imslen = 0; lastmod = -1; + client_addr.setEmpty(); + my_addr.setEmpty(); body_pipe = NULL; // hier dnsWait = -1; @@ -121,13 +123,13 @@ HttpRequest::init() myportname = port->name; flags.ignoreCc = port->ignore_cc; } + } #if FOLLOW_X_FORWARDED_FOR - // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) - // not details about the TCP connection itself - if (clientConnection()) - indirect_client_addr = clientConnection()->remote; + // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) + // not details about the TCP connection itself + if (clientConnection()) + indirect_client_addr = clientConnection()->remote; #endif /* FOLLOW_X_FORWARDED_FOR */ - } } void @@ -230,9 +232,11 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) if (!aReq) return false; + client_addr = aReq->client_addr; #if FOLLOW_X_FORWARDED_FOR indirect_client_addr = aReq->indirect_client_addr; #endif + my_addr = aReq->my_addr; dnsWait = aReq->dnsWait; @@ -722,12 +726,21 @@ UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &he } void -HttpRequest::setDownloader(Downloader *d) +HttpRequest::prepareForDownloader(Downloader *aDownloader) { - http_ver = Http::ProtocolVersion(); header.putStr(Http::HdrType::HOST, url.host()); header.putTime(Http::HdrType::DATE, squid_curtime); - downloader = d; + downloader = aDownloader; + toInternal(); +} + +void +HttpRequest::toInternal() +{ + /* Internally created requests cannot have bodies today */ + content_length = 0; + http_ver = Http::ProtocolVersion(); + internal = true; } const Ip::Address& @@ -745,7 +758,8 @@ static const Ip::Address& NoAddr() { static Ip::Address addr; - addr.setNoAddr(); + if (!addr.isNoAddr()) + addr.setNoAddr(); return addr; } @@ -753,16 +767,23 @@ const Ip::Address& HttpRequest::clientAddr() const { return internal ? NoAddr() : - masterXaction->tcpClient ? - masterXaction->tcpClient->remote : src_addr; + masterXaction->clientConnection() ? + masterXaction->clientConnection()->remote : client_addr; +} + +void +HttpRequest::prepareForCachingProtocol(const Ip::Address &fromAddr) +{ + client_addr = fromAddr; + my_addr = NoAddr(); } const Ip::Address& HttpRequest::myAddr() const { return internal ? NoAddr(): - masterXaction->tcpClient ? - masterXaction->tcpClient->local : my_addr; + masterXaction->clientConnection() ? + masterXaction->clientConnection()->local : my_addr; } #if FOLLOW_X_FORWARDED_FOR @@ -851,7 +872,7 @@ FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry return ip; /* handle non-intercepted cases that were not handled above */ - ip = FindListeningPortAddressInConn(request->masterXaction->tcpClient); + ip = FindListeningPortAddressInConn(request->clientConnection()); if (!ip && ale) ip = FindListeningPortAddressInConn(ale->tcpClient); return ip; // may still be nil @@ -860,6 +881,5 @@ FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry Comm::ConnectionPointer HttpRequest::clientConnection() const { - return masterXaction->clientConnectionManager.valid() ? - masterXaction->clientConnectionManager->clientConnection : nullptr; + return masterXaction->clientConnection(); } diff --git a/src/HttpRequest.h b/src/HttpRequest.h index c888c5a8c38..bb0b0d7431d 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -138,22 +138,21 @@ class HttpRequest: public Http::Message int imslen; - /// this request is internally built - void setInternal() { internal = true; } + /// mark this request as internally built + void toInternal(); - void setDownloader(Downloader *); + void prepareForDownloader(Downloader *); - const Ip::Address& clientAddr() const; + void prepareForCachingProtocol(const Ip::Address &fromAddr); - void srcAddr(const Ip::Address &addr) { src_addr = addr; } + const Ip::Address& clientAddr() const; const Ip::Address& myAddr() const; - void myAddr(const Ip::Address &addr) { my_addr = addr; } - - const Ip::Address& effectiveClientAddr(const bool) const; + /// \returns indirect client address, if allowed, or client address + const Ip::Address& effectiveClientAddr(const bool useIndirect) const; - CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager; } + CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager(); } Comm::ConnectionPointer clientConnection() const; @@ -264,7 +263,7 @@ class HttpRequest: public Http::Message /// and(or) by annotate_transaction/annotate_client ACLs. NotePairs::Pointer theNotes; - Ip::Address src_addr; + Ip::Address client_addr; Ip::Address my_addr; #if FOLLOW_X_FORWARDED_FOR Ip::Address indirect_client_addr; diff --git a/src/MasterXaction.cc b/src/MasterXaction.cc index 7188809f2be..cb672028b71 100644 --- a/src/MasterXaction.cc +++ b/src/MasterXaction.cc @@ -12,8 +12,24 @@ #include "MasterXaction.h" InstanceIdDefinitions(MasterXaction, "MXID_"); + +MasterXaction::MasterXaction(const XactionInitiator anInitiator) : + initiator(anInitiator) +{}; + MasterXaction::MasterXaction(const XactionInitiator anInitiator, ConnStateData *connManager) : initiator(anInitiator), - clientConnectionManager(connManager) + clientConnectionManager_(connManager), + clientConnection_(clientConnectionManager_.valid() ? clientConnectionManager_->clientConnection : nullptr) +{}; + +MasterXaction::MasterXaction(const XactionInitiator anInitiator, Comm::ConnectionPointer aConnection) : + initiator(anInitiator), + clientConnection_(aConnection) {}; +Comm::ConnectionPointer +MasterXaction::clientConnection() +{ + return clientConnectionManager_.valid() ? clientConnectionManager_->clientConnection : clientConnection_; +} diff --git a/src/MasterXaction.h b/src/MasterXaction.h index 189948ca2eb..89ae8464b23 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -44,8 +44,15 @@ class MasterXaction : public RefCountable { public: typedef RefCount Pointer; + explicit MasterXaction(const XactionInitiator); - explicit MasterXaction(const XactionInitiator anInitiator, ConnStateData *connManager); + MasterXaction(const XactionInitiator, ConnStateData *); + + MasterXaction(const XactionInitiator, Comm::ConnectionPointer); + + Comm::ConnectionPointer clientConnection(); + + CbcPointer &clientConnectionManager() { return clientConnectionManager_; } /// transaction ID. InstanceId id; @@ -53,19 +60,20 @@ class MasterXaction : public RefCountable /// the listening port which originated this transaction AnyP::PortCfgPointer squidPort; - /// the client TCP connection which originated this transaction - Comm::ConnectionPointer tcpClient; - /// the initiator of this transaction XactionInitiator initiator; +private: /** * The client connection manager, if known; * Used for any response actions needed directly to the client. * ie 1xx forwarding or connection pinning state changes */ - CbcPointer clientConnectionManager; + CbcPointer clientConnectionManager_; // TODO: add state from other Jobs in the transaction + + /// the client TCP connection which originated this transaction + Comm::ConnectionPointer clientConnection_; }; #endif /* SQUID_SRC_MASTERXACTION_H */ diff --git a/src/PeerPoolMgr.cc b/src/PeerPoolMgr.cc index 70ee922243d..3c5d0799ae2 100644 --- a/src/PeerPoolMgr.cc +++ b/src/PeerPoolMgr.cc @@ -60,7 +60,7 @@ PeerPoolMgr::start() { AsyncJob::start(); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerPool, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerPool); // ErrorState, getOutgoingAddress(), and other APIs may require a request. // We fake one. TODO: Optionally send this request to peers? request = new HttpRequest(Http::METHOD_OPTIONS, AnyP::PROTO_HTTP, "http", "*", mx); diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index 7990cb1fe37..ed4d4ac9c7d 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -237,7 +237,7 @@ asnCacheStart(int as) debugs(53, 3, "AS " << as); ASState *asState = new ASState; asState->as_number = as; - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAsn, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAsn); asState->request = new HttpRequest(mx); asState->request->url = whoisUrl; asState->request->method = Http::METHOD_GET; diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 0e74745b212..0f0c9258e6b 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -245,7 +245,7 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) if (httpRequest) { request = httpRequest; HTTPMSGLOCK(request); - src_addr = request->effectiveClientAddr(Config.onoff.acl_uses_indirect_client); + applyIndirectClientOption(Config.onoff.acl_uses_indirect_client); my_addr = request->myAddr(); setClientConnectionManager(request->clientConnectionManager().get()); } @@ -270,12 +270,12 @@ void ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) setClientConnection(conn); } -void ACLFilledChecklist::srcAddr(const Ip::Address &addr) +void ACLFilledChecklist::applyIndirectClientOption(const bool useIndirect) { - if (request || clientConnectionManager()) + if (!request) return; - src_addr = addr; + src_addr = request->effectiveClientAddr(useIndirect); } void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) @@ -287,6 +287,12 @@ void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) my_addr = conn->local; } +void ACLFilledChecklist::snmpDetails(char *snmpCommunity, const Ip::Address &from) +{ + snmp_community = snmpCommunity; + src_addr = from; +} + void ACLFilledChecklist::setIdent(const char *ident) { diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index ae648805af8..3d3c5255182 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -45,14 +45,14 @@ class ACLFilledChecklist: public ACLChecklist void setIdent(const char *userIdentity); public: - /// The client connection manager - ConnStateData * clientConnectionManager() const; - void clientConnectionManager(ConnStateData *); void clientConnection(Comm::ConnectionPointer); - void srcAddr(const Ip::Address &addr); + void applyIndirectClientOption(const bool); + + /// the associated client connection manager or nil + ConnStateData *clientConnectionManager() const; const Ip::Address &srcAddr() const { return src_addr; } @@ -91,6 +91,8 @@ class ACLFilledChecklist: public ACLChecklist Auth::UserRequest::Pointer auth_user_request; #endif #if SQUID_SNMP + void snmpDetails(char *community, const Ip::Address &from); + char *snmp_community; #endif diff --git a/src/adaptation/ecap/Host.cc b/src/adaptation/ecap/Host.cc index 203e6c77b51..b69e82658d7 100644 --- a/src/adaptation/ecap/Host.cc +++ b/src/adaptation/ecap/Host.cc @@ -163,7 +163,7 @@ Adaptation::Ecap::Host::closeDebug(std::ostream *debug) Adaptation::Ecap::Host::MessagePtr Adaptation::Ecap::Host::newRequest() const { - static const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptationOrphan_, nullptr); + static const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptationOrphan_); return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest(mx))); } diff --git a/src/adaptation/icap/Xaction.cc b/src/adaptation/icap/Xaction.cc index 1f71a6b2f9e..c91e7e1021b 100644 --- a/src/adaptation/icap/Xaction.cc +++ b/src/adaptation/icap/Xaction.cc @@ -97,7 +97,7 @@ Adaptation::Icap::Xaction::Xaction(const char *aTypeName, Adaptation::Icap::Serv { debugs(93,3, typeName << " constructed, this=" << this << " [icapx" << id << ']'); // we should not call virtual status() here - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptation, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptation); icapRequest = new HttpRequest(mx); HTTPMSGLOCK(icapRequest); icap_tr_start = current_time; diff --git a/src/client_side.cc b/src/client_side.cc index d38f04554be..1979dad634b 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2199,7 +2199,7 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) : pinning.peer = NULL; // store the details required for creating more MasterXaction objects as new requests come in - log_addr = xact->tcpClient->remote; + log_addr = clientConnection->remote; log_addr.applyClientMask(Config.Addrs.client_netmask); // register to receive notice of Squid signal events @@ -2608,7 +2608,6 @@ ConnStateData::postHttpsAccept() } MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); - mx->tcpClient = clientConnection; // Create a fake HTTP request for ssl_bump ACL check, // using tproxy/intercept provided destination IP and port. HttpRequest *request = new HttpRequest(mx); @@ -3262,7 +3261,6 @@ ConnStateData::buildFakeRequest(Http::MethodType const method, SBuf &useHost, un stream->registerWithConn(); MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); - mx->tcpClient = clientConnection; // Setup Http::Request object. Maybe should be replaced by a call to (modified) // clientProcessRequest HttpRequest::Pointer request = new HttpRequest(mx); diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 2dee63b97c0..d41cdff13d5 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -375,12 +375,7 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre * objects ? */ - /* Internally created requests cannot have bodies today */ - request->content_length = 0; - - request->setInternal(); - - request->http_ver = Http::ProtocolVersion(); + request->toInternal(); http->initRequest(request); @@ -2170,4 +2165,3 @@ ClientHttpRequest::calloutsError(const err_type error, const int errDetail) } //else if(calloutContext == NULL) is it possible? } - diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index e1b270e8f23..49e5ab025e2 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -329,10 +329,10 @@ Comm::TcpAcceptor::notify(const Comm::Flag flag, const Comm::ConnectionPointer & if (theCallSub != NULL) { AsyncCall::Pointer call = theCallSub->callback(); CommAcceptCbParams ¶ms = GetCommParams(call); - params.xaction = new MasterXaction(XactionInitiator::initClient, nullptr); + params.xaction = new MasterXaction(XactionInitiator::initClient, newConnDetails); params.xaction->squidPort = listenPort_; params.fd = conn->fd; - params.conn = params.xaction->tcpClient = newConnDetails; + params.conn = newConnDetails; params.flag = flag; params.xerrno = errcode; ScheduleCallHere(call); diff --git a/src/esi/Include.cc b/src/esi/Include.cc index e4f51e14360..ef50fc8a897 100644 --- a/src/esi/Include.cc +++ b/src/esi/Include.cc @@ -299,7 +299,7 @@ ESIInclude::Start (ESIStreamContext::Pointer stream, char const *url, ESIVarStat char const *tempUrl = vars->extractChar (); debugs(86, 5, "ESIIncludeStart: Starting subrequest with url '" << tempUrl << "'"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initEsi, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initEsi); if (clientBeginRequest(Http::METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ, mx)) { debugs(86, DBG_CRITICAL, "starting new ESI subrequest failed"); } diff --git a/src/htcp.cc b/src/htcp.cc index ab37757134c..e87f3046c74 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -135,11 +135,7 @@ class htcpSpecifier : public RefCountable, public StoreClient } void setAddresses(Ip::Address &anIp) { assert(request); - request->srcAddr(anIp); - static Ip::Address noAddr; - noAddr.setNoAddr(); - request->myAddr(noAddr); - + request->prepareForCachingProtocol(anIp); } void setDataHeader(htcpDataHeader *aDataHeader) { dhdr = aDataHeader; @@ -704,7 +700,7 @@ htcpUnpackSpecifier(char *buf, int sz) // Parse the request method.HttpRequestMethodXXX(s->method); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp); s->request = HttpRequest::FromUrl(s->uri, mx, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method); if (!s->request) { debugs(31, 3, "failed to create request. Invalid URI?"); diff --git a/src/icmp/net_db.cc b/src/icmp/net_db.cc index 82b21d343f9..69cecafc2ca 100644 --- a/src/icmp/net_db.cc +++ b/src/icmp/net_db.cc @@ -1274,7 +1274,7 @@ netdbExchangeStart(void *data) static const SBuf netDB("netdb"); char *uri = internalRemoteUri(p->secure.encryptTransport, p->host, p->http_port, "/squid-internal-dynamic/", netDB); debugs(38, 3, "Requesting '" << uri << "'"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp); HttpRequestPointer req(HttpRequest::FromUrl(uri, mx)); if (!req) { diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 2fd6e19ff2a..ff4b5ef4643 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -494,15 +494,11 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) } HttpRequest *result; - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp, nullptr); - if ((result = HttpRequest::FromUrl(url, mx)) == NULL) { + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp); + if ((result = HttpRequest::FromUrl(url, mx)) == NULL) icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); - } else { - result->srcAddr(from); - static Ip::Address noAddr; - noAddr.setNoAddr(); - result->myAddr(noAddr); - } + else + result->prepareForCachingProtocol(from); return result; } diff --git a/src/mgr/Inquirer.cc b/src/mgr/Inquirer.cc index b680060cd81..71706a4b79c 100644 --- a/src/mgr/Inquirer.cc +++ b/src/mgr/Inquirer.cc @@ -75,7 +75,7 @@ Mgr::Inquirer::start() std::unique_ptr replyBuf; if (strands.empty()) { const char *url = aggrAction->command().params.httpUri.termedBuf(); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc); HttpRequest *req = HttpRequest::FromUrl(url, mx); ErrorState err(ERR_INVALID_URL, Http::scNotFound, req); std::unique_ptr reply(err.BuildHttpReply()); diff --git a/src/mime.cc b/src/mime.cc index 49f184fa7a0..d732bdf3100 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -403,7 +403,7 @@ MimeIcon::created(StoreEntry *newEntry) /* fill `e` with a canned 2xx response object */ - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon); HttpRequestPointer r(HttpRequest::FromUrl(url_, mx)); if (!r) fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_); diff --git a/src/neighbors.cc b/src/neighbors.cc index 284df5e78ab..1a0d3e2bc9a 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1402,7 +1402,7 @@ peerCountMcastPeersStart(void *data) snprintf(url, MAX_URL, "http://"); p->in_addr.toUrl(url+7, MAX_URL -8 ); strcat(url, "/"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast); HttpRequest *req = HttpRequest::FromUrl(url, mx); assert(req != nullptr); StoreEntry *fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET); diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 113f93357ea..dd38807e6ed 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -725,7 +725,6 @@ Ftp::Server::parseOneRequest() ¶ms : NULL; calcUri(path); MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); - mx->tcpClient = clientConnection; HttpRequest *const request = HttpRequest::FromUrl(uri.c_str(), mx, method); if (!request) { debugs(33, 5, "Invalid FTP URL: " << uri); diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index f9a1960c812..bbe62bbc305 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -134,7 +134,6 @@ Http::One::Server::buildHttpRequest(Http::StreamPointer &context) // TODO: move URL parse into Http Parser and INVALID_URL into the above parse error handling MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); - mx->tcpClient = clientConnection; if ((request = HttpRequest::FromUrl(http->uri, mx, parser_->method())) == NULL) { debugs(33, 5, "Invalid URL: " << http->uri); // setReplyToError() requires log_uri diff --git a/src/servers/Server.cc b/src/servers/Server.cc index 8d692d68ee2..a1f581be1cc 100644 --- a/src/servers/Server.cc +++ b/src/servers/Server.cc @@ -23,7 +23,7 @@ Server::Server(const MasterXaction::Pointer &xact) : AsyncJob("::Server"), // kids overwrite - clientConnection(xact->tcpClient), + clientConnection(xact->clientConnection()), transferProtocol(xact->squidPort->transport), port(xact->squidPort), receivedFirstByte_(false) diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 2230ae224fa..3653922273f 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -399,9 +399,7 @@ snmpDecodePacket(SnmpRequest * rq) * default (set above) is to deny all */ if (Community) { ACLFilledChecklist checklist(Config.accessList.snmp, NULL, NULL); - checklist.srcAddr(rq->from); - checklist.snmp_community = (char *) Community; - + checklist.snmpDetails(reinterpret_cast(Community), rq->from); if (checklist.fastCheck().allowed() && (snmp_coexist_V2toV1(PDU))) { rq->community = Community; rq->PDU = PDU; diff --git a/src/tests/testHttpRequest.cc b/src/tests/testHttpRequest.cc index 2f36790835f..c4d743efe32 100644 --- a/src/tests/testHttpRequest.cc +++ b/src/tests/testHttpRequest.cc @@ -46,7 +46,7 @@ testHttpRequest::testCreateFromUrl() /* vanilla url, implict method */ unsigned short expected_port; char * url = xstrdup("http://foo:90/bar"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); HttpRequest *aRequest = HttpRequest::FromUrl(url, mx); expected_port = 90; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); @@ -115,7 +115,7 @@ testHttpRequest::testIPv6HostColonBug() /* valid IPv6 address without port */ url = xstrdup("http://[2000:800::45]/foo"); - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET); expected_port = 80; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); @@ -155,7 +155,7 @@ void testHttpRequest::testSanityCheckStartLine() { MemBuf input; - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, nullptr); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); PrivateHttpRequest engine(mx); Http::StatusCode error = Http::scNone; size_t hdr_len; From 7ae3e72e9dfc6da2dedc2fe200dcb2cd3df81157 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 14 Mar 2019 16:57:50 +0300 Subject: [PATCH 14/66] Fixed ACLFilledChecklist address configuration in several contexts In some contexts we need to configure client/local addresses with values, other from the ones taken from the established client connection (by default). These cases include clientFollowXForwardedForCheck() and ConnStateData::postHttpsAccept() methods. Also some polishing and commenting. --- src/HttpRequest.cc | 2 +- src/HttpRequest.h | 12 ++++++---- src/MasterXaction.h | 4 ++-- src/acl/AtStep.cc | 2 +- src/acl/FilledChecklist.cc | 44 ++++++++++++++++++++++++++++-------- src/acl/FilledChecklist.h | 18 +++++++++++++-- src/acl/MyPortName.cc | 2 +- src/acl/ServerCertificate.cc | 2 +- src/auth/Acl.cc | 2 +- src/auth/AclProxyAuth.cc | 6 ++--- src/client_side.cc | 1 + src/client_side_request.cc | 4 +++- src/htcp.cc | 1 + src/icp_v2.cc | 1 + src/ident/AclIdent.cc | 6 ++--- 15 files changed, 77 insertions(+), 30 deletions(-) diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index dd33ceb2876..bb15eb9340a 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -794,7 +794,7 @@ HttpRequest::indirectClientAddr() const } void -HttpRequest::resetIndirectClientAddr() +HttpRequest::ignoreIndirectClientAddr() { indirect_client_addr = clientAddr(); indirect_client_addr.port(0); diff --git a/src/HttpRequest.h b/src/HttpRequest.h index bb0b0d7431d..e17e5028993 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -140,16 +140,18 @@ class HttpRequest: public Http::Message /// mark this request as internally built void toInternal(); - + /// Downloader specific settings void prepareForDownloader(Downloader *); - + /// ICP/HTCP specific settings void prepareForCachingProtocol(const Ip::Address &fromAddr); + /// the remote address of the client connection const Ip::Address& clientAddr() const; + /// the local address of the client connection const Ip::Address& myAddr() const; - /// \returns indirect client address, if allowed, or client address + /// \returns indirect client address, if allowed, or direct client address const Ip::Address& effectiveClientAddr(const bool useIndirect) const; CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager(); } @@ -160,8 +162,8 @@ class HttpRequest: public Http::Message const Ip::Address& indirectClientAddr() const; void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } - - void resetIndirectClientAddr(); + /// always use direct client address + void ignoreIndirectClientAddr(); #endif /* FOLLOW_X_FORWARDED_FOR */ HierarchyLogEntry hier; diff --git a/src/MasterXaction.h b/src/MasterXaction.h index 89ae8464b23..a97030fecaa 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -15,7 +15,6 @@ #include "base/InstanceId.h" #include "base/Lock.h" #include "base/RefCount.h" -//#include "client_side.h" #include "comm/forward.h" #include "XactionInitiator.h" @@ -70,10 +69,11 @@ class MasterXaction : public RefCountable * ie 1xx forwarding or connection pinning state changes */ CbcPointer clientConnectionManager_; - // TODO: add state from other Jobs in the transaction /// the client TCP connection which originated this transaction Comm::ConnectionPointer clientConnection_; + + // TODO: add state from other Jobs in the transaction }; #endif /* SQUID_SRC_MASTERXACTION_H */ diff --git a/src/acl/AtStep.cc b/src/acl/AtStep.cc index 33e4b29a66b..33a3cdf8953 100644 --- a/src/acl/AtStep.cc +++ b/src/acl/AtStep.cc @@ -21,7 +21,7 @@ int ACLAtStepStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { Ssl::ServerBump *bump = NULL; - if (checklist->clientConnectionManager() != NULL && (bump = checklist->clientConnectionManager()->serverBump())) + if (checklist->clientConnectionManager() && (bump = checklist->clientConnectionManager()->serverBump())) return data->match(bump->step); else return data->match(Ssl::bumpStep1); diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 0f0c9258e6b..c57efc5cdb2 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -40,7 +40,11 @@ ACLFilledChecklist::ACLFilledChecklist() : conn_(NULL), fd_(-1), destinationDomainChecked_(false), - sourceDomainChecked_(false) + sourceDomainChecked_(false), +#if FOLLOW_X_FORWARDED_FOR + forceIndirectAddr_(false), +#endif + forceListeningAddr_(false) { my_addr.setEmpty(); src_addr.setEmpty(); @@ -146,6 +150,26 @@ ACLFilledChecklist::clientConnectionManager() const return cbdataReferenceValid(conn_) ? conn_ : nullptr; } +/// the remote address of the client connection +const Ip::Address & +ACLFilledChecklist::srcAddr() const +{ +#if FOLLOW_X_FORWARDED_FOR + if (forceIndirectAddr_ && request) + return request->indirectClientAddr(); +#endif /* FOLLOW_X_FORWARDED_FOR */ + return src_addr; +} + +const Ip::Address & +ACLFilledChecklist::myAddr() const +{ + return (forceListeningAddr_ && clientConnectionManager()) ? + clientConnectionManager()->port->s : + my_addr; +} + + void ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) { @@ -227,7 +251,11 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re conn_(NULL), fd_(-1), destinationDomainChecked_(false), - sourceDomainChecked_(false) + sourceDomainChecked_(false), +#if FOLLOW_X_FORWARDED_FOR + forceIndirectAddr_(false), +#endif + forceListeningAddr_(false) { my_addr.setEmpty(); src_addr.setEmpty(); @@ -253,13 +281,11 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) void ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) { - if (request) - return; - - setClientConnectionManager(aConn); - - if (clientConnectionManager()) - setClientConnection(clientConnectionManager()->clientConnection); + if (!clientConnectionManager()) { + setClientConnectionManager(aConn); + if (clientConnectionManager()) + setClientConnection(clientConnectionManager()->clientConnection); + } } void ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 3d3c5255182..9d4e7a8d674 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -51,12 +51,20 @@ class ACLFilledChecklist: public ACLChecklist void applyIndirectClientOption(const bool); + /// always use Squid listening address instead of the connection local address + void forceListeningAddr() { forceListeningAddr_ = true; } +#if FOLLOW_X_FORWARDED_FOR + /// always use indirect client address instead of direct client address + void forceIndirectAddr() { forceIndirectAddr_ = true; } +#endif /* FOLLOW_X_FORWARDED_FOR */ /// the associated client connection manager or nil ConnStateData *clientConnectionManager() const; - const Ip::Address &srcAddr() const { return src_addr; } + /// remote address, direct or indirect + const Ip::Address &srcAddr() const; - const Ip::Address &myAddr() const { return my_addr; } + /// local address, listening or of the established connection + const Ip::Address &myAddr() const; /// The client side fd. It uses conn() if available int fd() const; @@ -117,6 +125,12 @@ class ACLFilledChecklist: public ACLChecklist bool sourceDomainChecked_; Ip::Address src_addr; Ip::Address my_addr; +#if FOLLOW_X_FORWARDED_FOR + /// whether we will use indirect client address instead of direct address + bool forceIndirectAddr_; +#endif /* FOLLOW_X_FORWARDED_FOR */ + /// whether we will use Squid listening address instead of local connection address + bool forceListeningAddr_; /// not implemented; will cause link failures if used ACLFilledChecklist(const ACLFilledChecklist &); /// not implemented; will cause link failures if used diff --git a/src/acl/MyPortName.cc b/src/acl/MyPortName.cc index 710e6ff8a11..ab46e0e87ae 100644 --- a/src/acl/MyPortName.cc +++ b/src/acl/MyPortName.cc @@ -18,7 +18,7 @@ int ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { - if (checklist->clientConnectionManager() != NULL && checklist->clientConnectionManager()->port != NULL) + if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->port) return data->match(checklist->clientConnectionManager()->port->name); if (checklist->request != NULL) return data->match(checklist->request->myportname.termedBuf()); diff --git a/src/acl/ServerCertificate.cc b/src/acl/ServerCertificate.cc index 3070aa2492f..516ca478fdf 100644 --- a/src/acl/ServerCertificate.cc +++ b/src/acl/ServerCertificate.cc @@ -24,7 +24,7 @@ ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledCheckli Security::CertPointer cert; if (checklist->serverCert) cert = checklist->serverCert; - else if (checklist->clientConnectionManager() != NULL && checklist->clientConnectionManager()->serverBump()) + else if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->serverBump()) cert = checklist->clientConnectionManager()->serverBump()->serverCert; if (!cert) diff --git a/src/auth/Acl.cc b/src/auth/Acl.cc index e1af4d8eaef..e65a5b3b4fc 100644 --- a/src/auth/Acl.cc +++ b/src/auth/Acl.cc @@ -36,7 +36,7 @@ AuthenticateAcl(ACLChecklist *ch) return ACCESS_DENIED; } else if (request->flags.sslBumped) { debugs(28, 5, "SslBumped request: It is an encapsulated request do not authenticate"); - checklist->auth_user_request = checklist->clientConnectionManager() != NULL ? checklist->clientConnectionManager()->getAuth() : request->auth_user_request; + checklist->auth_user_request = checklist->clientConnectionManager() ? checklist->clientConnectionManager()->getAuth() : request->auth_user_request; if (checklist->auth_user_request != NULL) return ACCESS_ALLOWED; else diff --git a/src/auth/AclProxyAuth.cc b/src/auth/AclProxyAuth.cc index f4873e2c914..50c7da9914a 100644 --- a/src/auth/AclProxyAuth.cc +++ b/src/auth/AclProxyAuth.cc @@ -141,14 +141,14 @@ ProxyAuthLookup::LookupDone(void *data) { ACLFilledChecklist *checklist = Filled(static_cast(data)); - if (checklist->auth_user_request == NULL || !checklist->auth_user_request->valid() || checklist->clientConnectionManager() == NULL) { + if (!checklist->auth_user_request || !checklist->auth_user_request->valid() || !checklist->clientConnectionManager()) { /* credentials could not be checked either way * restart the whole process */ /* OR the connection was closed, there's no way to continue */ checklist->auth_user_request = NULL; - if (checklist->clientConnectionManager() != NULL) { - checklist->clientConnectionManager()->setAuth(NULL, "proxy_auth ACL failure"); + if (checklist->clientConnectionManager()) { + checklist->clientConnectionManager()->setAuth(nullptr, "proxy_auth ACL failure"); } } diff --git a/src/client_side.cc b/src/client_side.cc index 1979dad634b..449714368a7 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2619,6 +2619,7 @@ ConnStateData::postHttpsAccept() ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL); acl_checklist->clientConnectionManager(this); + acl_checklist->forceListeningAddr(); // Build a local AccessLogEntry to allow requiresAle() acls work acl_checklist->al = new AccessLogEntry; acl_checklist->al->cache.start_time = current_time; diff --git a/src/client_side_request.cc b/src/client_side_request.cc index d41cdff13d5..38a2797967d 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -469,6 +469,8 @@ clientFollowXForwardedForCheck(allow_t answer, void *data) request->indirectClientAddr(addr); request->x_forwarded_for_iterator.cut(l); calloutContext->acl_checklist = clientAclChecklistCreate(Config.accessList.followXFF, http); + /* override the default src_addr tested if we have to go deeper than one level into XFF */ + Filled(calloutContext->acl_checklist)->forceIndirectAddr(); calloutContext->acl_checklist->nonBlockingCheck(clientFollowXForwardedForCheck, data); return; } @@ -670,7 +672,7 @@ ClientRequestContext::clientAccessCheck() http->request->header.has(Http::HdrType::X_FORWARDED_FOR)) { /* we always trust the direct client address for actual use */ - http->request->resetIndirectClientAddr(); + http->request->ignoreIndirectClientAddr(); /* setup the XFF iterator for processing */ http->request->x_forwarded_for_iterator = http->request->header.getList(Http::HdrType::X_FORWARDED_FOR); diff --git a/src/htcp.cc b/src/htcp.cc index e87f3046c74..7637e86b834 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -706,6 +706,7 @@ htcpUnpackSpecifier(char *buf, int sz) debugs(31, 3, "failed to create request. Invalid URI?"); return nil; } + return s; } diff --git a/src/icp_v2.cc b/src/icp_v2.cc index ff4b5ef4643..a8fb772a0e0 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -499,6 +499,7 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); else result->prepareForCachingProtocol(from); + return result; } diff --git a/src/ident/AclIdent.cc b/src/ident/AclIdent.cc index 8e2f1dbd9c7..ec737ac0ed0 100644 --- a/src/ident/AclIdent.cc +++ b/src/ident/AclIdent.cc @@ -69,9 +69,9 @@ ACLIdent::match(ACLChecklist *cl) ACLFilledChecklist *checklist = Filled(cl); if (checklist->rfc931[0]) { return data->match(checklist->rfc931); - } else if (checklist->clientConnectionManager() != NULL && checklist->clientConnectionManager()->clientConnection != NULL && checklist->clientConnectionManager()->clientConnection->rfc931[0]) { + } else if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->clientConnection && checklist->clientConnectionManager()->clientConnection->rfc931[0]) { return data->match(checklist->clientConnectionManager()->clientConnection->rfc931); - } else if (checklist->clientConnectionManager() != NULL && Comm::IsConnOpen(checklist->clientConnectionManager()->clientConnection)) { + } else if (checklist->clientConnectionManager() && Comm::IsConnOpen(checklist->clientConnectionManager()->clientConnection)) { if (checklist->goAsync(IdentLookup::Instance())) { debugs(28, 3, "switching to ident lookup state"); return -1; @@ -138,7 +138,7 @@ IdentLookup::LookupDone(const char *ident, void *data) * Cache the ident result in the connection, to avoid redoing ident lookup * over and over on persistent connections */ - if (checklist->clientConnectionManager() != NULL && checklist->clientConnectionManager()->clientConnection != NULL && !checklist->clientConnectionManager()->clientConnection->rfc931[0]) + if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->clientConnection && !checklist->clientConnectionManager()->clientConnection->rfc931[0]) xstrncpy(checklist->clientConnectionManager()->clientConnection->rfc931, checklist->rfc931, USER_IDENT_SZ); checklist->resumeNonBlockingCheck(IdentLookup::Instance()); From ef4a8df145020fdf51879f088c208b053ab29ee9 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sat, 16 Mar 2019 01:10:48 +0300 Subject: [PATCH 15/66] Initialize ACLFilledCheckList with available local addresses ... in htcp and icp contexts. Before this change, 'noaddr' was used. Also refactored ACLFilledCheckList methods to protect already initialized address fields from ambiguous re-initialization. Also added some method descriptions. --- src/DelayId.cc | 2 +- src/HttpRequest.cc | 4 +-- src/HttpRequest.h | 9 +++-- src/acl/FilledChecklist.cc | 74 ++++++++++++++++++-------------------- src/acl/FilledChecklist.h | 35 +++++++++++------- src/client_side.cc | 1 - src/htcp.cc | 9 ++--- src/icp_v2.cc | 2 +- src/snmp_core.cc | 2 +- 9 files changed, 74 insertions(+), 64 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 4c8988f303e..6ad77b96cb7 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -90,7 +90,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) ch.reply = reply; HTTPMSGLOCK(reply); } - ch.applyIndirectClientOption(Config.onoff.delay_pool_uses_indirect_client); + ch.configureClientAddr(Config.onoff.delay_pool_uses_indirect_client); if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck().allowed()) { diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index bb15eb9340a..6a33d19a0ec 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -772,10 +772,10 @@ HttpRequest::clientAddr() const } void -HttpRequest::prepareForCachingProtocol(const Ip::Address &fromAddr) +HttpRequest::prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr) { client_addr = fromAddr; - my_addr = NoAddr(); + my_addr = localAddr; } const Ip::Address& diff --git a/src/HttpRequest.h b/src/HttpRequest.h index e17e5028993..42d5bae577b 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -138,12 +138,15 @@ class HttpRequest: public Http::Message int imslen; - /// mark this request as internally built + /// Mark this request as internally built. For internal requests, + /// client connection addresses are undefined. void toInternal(); + /// Downloader specific settings void prepareForDownloader(Downloader *); - /// ICP/HTCP specific settings - void prepareForCachingProtocol(const Ip::Address &fromAddr); + + /// specify addresses manually when lacking client connection + void prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr); /// the remote address of the client connection const Ip::Address& clientAddr() const; diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index c57efc5cdb2..1a81cf88ebd 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -42,9 +42,8 @@ ACLFilledChecklist::ACLFilledChecklist() : destinationDomainChecked_(false), sourceDomainChecked_(false), #if FOLLOW_X_FORWARDED_FOR - forceIndirectAddr_(false), + forceIndirectAddr_(false) #endif - forceListeningAddr_(false) { my_addr.setEmpty(); src_addr.setEmpty(); @@ -150,7 +149,6 @@ ACLFilledChecklist::clientConnectionManager() const return cbdataReferenceValid(conn_) ? conn_ : nullptr; } -/// the remote address of the client connection const Ip::Address & ACLFilledChecklist::srcAddr() const { @@ -161,24 +159,6 @@ ACLFilledChecklist::srcAddr() const return src_addr; } -const Ip::Address & -ACLFilledChecklist::myAddr() const -{ - return (forceListeningAddr_ && clientConnectionManager()) ? - clientConnectionManager()->port->s : - my_addr; -} - - -void -ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) -{ - if (!(aConn && cbdataReferenceValid(aConn))) - return; - assert(!clientConnectionManager()); - conn_ = cbdataReference(aConn); -} - int ACLFilledChecklist::fd() const { @@ -253,9 +233,9 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re destinationDomainChecked_(false), sourceDomainChecked_(false), #if FOLLOW_X_FORWARDED_FOR - forceIndirectAddr_(false), + forceIndirectAddr_(false) #endif - forceListeningAddr_(false) + { my_addr.setEmpty(); src_addr.setEmpty(); @@ -273,35 +253,42 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) if (httpRequest) { request = httpRequest; HTTPMSGLOCK(request); - applyIndirectClientOption(Config.onoff.acl_uses_indirect_client); + src_addr = request->effectiveClientAddr(Config.onoff.acl_uses_indirect_client); my_addr = request->myAddr(); setClientConnectionManager(request->clientConnectionManager().get()); + setClientConnection(request->clientConnection()); } } void ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) { - if (!clientConnectionManager()) { - setClientConnectionManager(aConn); - if (clientConnectionManager()) - setClientConnection(clientConnectionManager()->clientConnection); - } + setClientConnectionManager(aConn); + if (clientConnectionManager()) + setClientConnection(clientConnectionManager()->clientConnection); } void ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) { - if (request || clientConnectionManager()) - return; - setClientConnection(conn); } -void ACLFilledChecklist::applyIndirectClientOption(const bool useIndirect) +void ACLFilledChecklist::configureClientAddr(const bool useIndirect) +{ + assert(request); + src_addr = Config.onoff.acl_uses_indirect_client ? + request->effectiveClientAddr(useIndirect) : request->clientAddr(); +} + +void +ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) { - if (!request) + if (!(aConn && cbdataReferenceValid(aConn))) return; - src_addr = request->effectiveClientAddr(useIndirect); + if (clientConnectionManager()) + return; + + conn_ = cbdataReference(aConn); } void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) @@ -309,14 +296,23 @@ void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) if(!conn) return; - src_addr = conn->remote; - my_addr = conn->local; + if (clientConnection_) + return; + + clientConnection_ = conn; + + if (request) + return; // addresses already initialized from request + + src_addr = clientConnection_->remote; + my_addr = clientConnection_->local; } -void ACLFilledChecklist::snmpDetails(char *snmpCommunity, const Ip::Address &from) +void ACLFilledChecklist::snmpDetails(char *snmpCommunity, const Ip::Address &fromAddr, const Ip::Address &localAddr) { snmp_community = snmpCommunity; - src_addr = from; + src_addr = fromAddr; + my_addr = localAddr; } void diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 9d4e7a8d674..e51557d5a86 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -39,32 +39,43 @@ class ACLFilledChecklist: public ACLChecklist ACLFilledChecklist(const acl_access *, HttpRequest *, const char *ident = nullptr); ~ACLFilledChecklist(); - /// configure client request-related fields for the first time + /// Configure client request-related fields for the first time. + /// The passed HttpRequest parameter usually contains all client-related + /// data, including addresses and the connection manager. void setRequest(HttpRequest *); + /// configure rfc931 user identity for the first time void setIdent(const char *userIdentity); -public: + /// Configures client-related fields from the passed client connection manager. + /// Has no effect if the client connection manager field is already initialized. + /// This method should be used in contexts where HttpRequest may be unavailable. void clientConnectionManager(ConnStateData *); + /// Configures client-related fields from the passed client connection. + /// Has no effect if the fields are already initialized. + /// This method should be used in contexts where HttpRequest and + /// connection manager may be unavailable. void clientConnection(Comm::ConnectionPointer); - void applyIndirectClientOption(const bool); + /// Use either indirect client address or direct address + /// depending on the argument, passed as one of *uses_indirect_client + /// configuration options. + void configureClientAddr(const bool useIndirect); - /// always use Squid listening address instead of the connection local address - void forceListeningAddr() { forceListeningAddr_ = true; } #if FOLLOW_X_FORWARDED_FOR - /// always use indirect client address instead of direct client address - void forceIndirectAddr() { forceIndirectAddr_ = true; } + /// always use indirect client address instead of direct client address + void forceIndirectAddr() { forceIndirectAddr_ = true; } #endif /* FOLLOW_X_FORWARDED_FOR */ + /// the associated client connection manager or nil ConnStateData *clientConnectionManager() const; /// remote address, direct or indirect const Ip::Address &srcAddr() const; - /// local address, listening or of the established connection - const Ip::Address &myAddr() const; + /// local address + const Ip::Address &myAddr() const { return my_addr; } /// The client side fd. It uses conn() if available int fd() const; @@ -99,7 +110,8 @@ class ACLFilledChecklist: public ACLChecklist Auth::UserRequest::Pointer auth_user_request; #endif #if SQUID_SNMP - void snmpDetails(char *community, const Ip::Address &from); + /// configure with SNMP specific parameters + void snmpDetails(char *community, const Ip::Address &fromAddr, const Ip::Address &localAddr); char *snmp_community; #endif @@ -120,6 +132,7 @@ class ACLFilledChecklist: public ACLChecklist void setClientConnection(Comm::ConnectionPointer); ConnStateData * conn_; /**< hack for ident and NTLM */ + Comm::ConnectionPointer clientConnection_; int fd_; /**< may be available when conn_ is not */ bool destinationDomainChecked_; bool sourceDomainChecked_; @@ -129,8 +142,6 @@ class ACLFilledChecklist: public ACLChecklist /// whether we will use indirect client address instead of direct address bool forceIndirectAddr_; #endif /* FOLLOW_X_FORWARDED_FOR */ - /// whether we will use Squid listening address instead of local connection address - bool forceListeningAddr_; /// not implemented; will cause link failures if used ACLFilledChecklist(const ACLFilledChecklist &); /// not implemented; will cause link failures if used diff --git a/src/client_side.cc b/src/client_side.cc index 449714368a7..1979dad634b 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2619,7 +2619,6 @@ ConnStateData::postHttpsAccept() ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL); acl_checklist->clientConnectionManager(this); - acl_checklist->forceListeningAddr(); // Build a local AccessLogEntry to allow requiresAle() acls work acl_checklist->al = new AccessLogEntry; acl_checklist->al->cache.start_time = current_time; diff --git a/src/htcp.cc b/src/htcp.cc index 7637e86b834..6da2027d83e 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -119,6 +119,9 @@ struct _htcpAuthHeader { Countstr signature; }; +static Comm::ConnectionPointer htcpOutgoingConn; +static Comm::ConnectionPointer htcpIncomingConn; + class htcpSpecifier : public RefCountable, public StoreClient { MEMPROXY_CLASS(htcpSpecifier); @@ -133,9 +136,9 @@ class htcpSpecifier : public RefCountable, public StoreClient assert(request); return request->clientAddr(); } - void setAddresses(Ip::Address &anIp) { + void setAddresses(Ip::Address &from) { assert(request); - request->prepareForCachingProtocol(anIp); + request->prepareForConnectionlessProtocol(from, htcpIncomingConn->local); } void setDataHeader(htcpDataHeader *aDataHeader) { dhdr = aDataHeader; @@ -238,8 +241,6 @@ enum { static void htcpIncomingConnectionOpened(const Comm::ConnectionPointer &conn, int errNo); static uint32_t msg_id_counter = 0; -static Comm::ConnectionPointer htcpOutgoingConn = NULL; -static Comm::ConnectionPointer htcpIncomingConn = NULL; #define N_QUERIED_KEYS 8192 static uint32_t queried_id[N_QUERIED_KEYS]; static cache_key queried_keys[N_QUERIED_KEYS][SQUID_MD5_DIGEST_LENGTH]; diff --git a/src/icp_v2.cc b/src/icp_v2.cc index a8fb772a0e0..2e4b5cbc905 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -498,7 +498,7 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) if ((result = HttpRequest::FromUrl(url, mx)) == NULL) icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); else - result->prepareForCachingProtocol(from); + result->prepareForConnectionlessProtocol(from, icpIncomingConn->local); return result; diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 3653922273f..1e7889419ef 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -399,7 +399,7 @@ snmpDecodePacket(SnmpRequest * rq) * default (set above) is to deny all */ if (Community) { ACLFilledChecklist checklist(Config.accessList.snmp, NULL, NULL); - checklist.snmpDetails(reinterpret_cast(Community), rq->from); + checklist.snmpDetails(reinterpret_cast(Community), rq->from, snmpIncomingConn->local); if (checklist.fastCheck().allowed() && (snmp_coexist_V2toV1(PDU))) { rq->community = Community; rq->PDU = PDU; From 4ca596a3a22c90b6b384a35c3e45058e4b6d831a Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 21 Mar 2019 15:58:00 +0300 Subject: [PATCH 16/66] Some polishing * Added method descriptions * More consistent field names * Removed a stale TODO --- src/HttpRequest.h | 9 ++++++--- src/MasterXaction.h | 2 ++ src/acl/FilledChecklist.cc | 35 +++++++++++++++++++++++------------ src/acl/FilledChecklist.h | 4 +++- src/client_side.cc | 1 - 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 42d5bae577b..c209c579eb8 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -142,7 +142,7 @@ class HttpRequest: public Http::Message /// client connection addresses are undefined. void toInternal(); - /// Downloader specific settings + /// supply Downloader-specific settings void prepareForDownloader(Downloader *); /// specify addresses manually when lacking client connection @@ -154,18 +154,21 @@ class HttpRequest: public Http::Message /// the local address of the client connection const Ip::Address& myAddr() const; - /// \returns indirect client address, if allowed, or direct client address + /// indirect client address, if allowed, or direct client address const Ip::Address& effectiveClientAddr(const bool useIndirect) const; + /// the client connection manager of the underlying transaction, if any CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager(); } + /// the client connection of the underlying transaction, if any Comm::ConnectionPointer clientConnection() const; #if FOLLOW_X_FORWARDED_FOR + /// the indirect client address const Ip::Address& indirectClientAddr() const; void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } - /// always use direct client address + /// force using direct client address void ignoreIndirectClientAddr(); #endif /* FOLLOW_X_FORWARDED_FOR */ diff --git a/src/MasterXaction.h b/src/MasterXaction.h index a97030fecaa..915a4e731d3 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -49,8 +49,10 @@ class MasterXaction : public RefCountable MasterXaction(const XactionInitiator, Comm::ConnectionPointer); + /// the client connection of the transaction, if any Comm::ConnectionPointer clientConnection(); + /// the client connection manager of the transaction, if any CbcPointer &clientConnectionManager() { return clientConnectionManager_; } /// transaction ID. diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 1a81cf88ebd..3ee173a0c21 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -37,7 +37,7 @@ ACLFilledChecklist::ACLFilledChecklist() : sslErrors(NULL), #endif requestErrorType(ERR_MAX), - conn_(NULL), + connectionManager_(nullptr), fd_(-1), destinationDomainChecked_(false), sourceDomainChecked_(false), @@ -61,7 +61,7 @@ ACLFilledChecklist::~ACLFilledChecklist() HTTPMSGUNLOCK(reply); - cbdataReferenceDone(conn_); + cbdataReferenceDone(connectionManager_); #if USE_OPENSSL cbdataReferenceDone(sslErrors); @@ -146,7 +146,7 @@ ACLFilledChecklist::syncAle(HttpRequest *adaptedRequest, const char *logUri) con ConnStateData * ACLFilledChecklist::clientConnectionManager() const { - return cbdataReferenceValid(conn_) ? conn_ : nullptr; + return cbdataReferenceValid(connectionManager_) ? connectionManager_ : nullptr; } const Ip::Address & @@ -228,7 +228,7 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re sslErrors(NULL), #endif requestErrorType(ERR_MAX), - conn_(NULL), + connectionManager_(NULL), fd_(-1), destinationDomainChecked_(false), sourceDomainChecked_(false), @@ -247,7 +247,8 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re setIdent(ident); } -void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) +void +ACLFilledChecklist::setRequest(HttpRequest *httpRequest) { assert(!request); if (httpRequest) { @@ -260,25 +261,30 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) } } -void ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) +void +ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) { setClientConnectionManager(aConn); if (clientConnectionManager()) setClientConnection(clientConnectionManager()->clientConnection); } -void ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) +void +ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) { setClientConnection(conn); } -void ACLFilledChecklist::configureClientAddr(const bool useIndirect) +void +ACLFilledChecklist::configureClientAddr(const bool useIndirect) { assert(request); src_addr = Config.onoff.acl_uses_indirect_client ? request->effectiveClientAddr(useIndirect) : request->clientAddr(); } +/// Initializes the client connection manager; does nothing +/// if already initialized. void ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) { @@ -288,10 +294,14 @@ ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) if (clientConnectionManager()) return; - conn_ = cbdataReference(aConn); + connectionManager_ = cbdataReference(aConn); } -void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) + +/// Initializes the client connection and addresses; does nothing +/// if already initialized. +void +ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) { if(!conn) return; @@ -302,13 +312,14 @@ void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) clientConnection_ = conn; if (request) - return; // addresses already initialized from request + return; // addresses should have already initialized from the request src_addr = clientConnection_->remote; my_addr = clientConnection_->local; } -void ACLFilledChecklist::snmpDetails(char *snmpCommunity, const Ip::Address &fromAddr, const Ip::Address &localAddr) +void +ACLFilledChecklist::snmpDetails(char *snmpCommunity, const Ip::Address &fromAddr, const Ip::Address &localAddr) { snmp_community = snmpCommunity; src_addr = fromAddr; diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index e51557d5a86..a0c5f8575bb 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -131,7 +131,9 @@ class ACLFilledChecklist: public ACLChecklist void setClientConnectionManager(ConnStateData *); void setClientConnection(Comm::ConnectionPointer); - ConnStateData * conn_; /**< hack for ident and NTLM */ + /// a client connection manager, if any + ConnStateData *connectionManager_; + /// a client connection, if any Comm::ConnectionPointer clientConnection_; int fd_; /**< may be available when conn_ is not */ bool destinationDomainChecked_; diff --git a/src/client_side.cc b/src/client_side.cc index 1979dad634b..acf30739d97 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2274,7 +2274,6 @@ ConnStateData::whenClientIpKnown() // TODO: we check early to limit error response bandwith but we // should recheck when we can honor delay_pool_uses_indirect - // TODO: we should also pass the port details for myportname here. for (unsigned int pool = 0; pool < pools.size(); ++pool) { From 425102447fa213a6789ca310c224d9ceb68a4abb Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Fri, 22 Mar 2019 15:30:52 +0300 Subject: [PATCH 17/66] Eliminated HttpRequest::myportname Since the only user of this public field was ACLMyPortNameStrategy::match(), we do not need keeping this(copied) value in HttpRequest because: * HttpRequest::myportname was always initialized by means of(passed) connection manager. * We now guarantee that each ACLFilledChecklist gets a connection manager, if available. --- src/HttpRequest.cc | 6 ------ src/HttpRequest.h | 2 -- src/acl/MyPortName.cc | 2 -- src/client_side.cc | 1 - 4 files changed, 11 deletions(-) diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 6a33d19a0ec..4199d9f8942 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -96,7 +96,6 @@ HttpRequest::init() peer_domain = NULL; // not allocated/deallocated by this class peer_host = NULL; vary_headers = SBuf(); - myportname = null_string; tag = null_string; #if USE_AUTH extacl_user = null_string; @@ -120,7 +119,6 @@ HttpRequest::init() if (clientConnectionManager().valid()) { if (const auto port = clientConnectionManager()->port) { - myportname = port->name; flags.ignoreCc = port->ignore_cc; } } @@ -156,8 +154,6 @@ HttpRequest::clean() range = NULL; } - myportname.clean(); - theNotes = nullptr; tag.clean(); @@ -259,8 +255,6 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) extacl_passwd = aReq->extacl_passwd; #endif - myportname = aReq->myportname; - forcedBodyContinuation = aReq->forcedBodyContinuation; downloader = aReq->downloader; diff --git a/src/HttpRequest.h b/src/HttpRequest.h index c209c579eb8..629cab01930 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -190,8 +190,6 @@ class HttpRequest: public Http::Message char *peer_domain; /* Configured peer forceddomain */ - String myportname; // Internal tag name= value from port this requests arrived in. - String tag; /* Internal tag for this request */ String extacl_user; /* User name returned by extacl lookup */ diff --git a/src/acl/MyPortName.cc b/src/acl/MyPortName.cc index ab46e0e87ae..6d75730fccb 100644 --- a/src/acl/MyPortName.cc +++ b/src/acl/MyPortName.cc @@ -20,8 +20,6 @@ ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *che { if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->port) return data->match(checklist->clientConnectionManager()->port->name); - if (checklist->request != NULL) - return data->match(checklist->request->myportname.termedBuf()); return 0; } diff --git a/src/client_side.cc b/src/client_side.cc index acf30739d97..e9d04130b3b 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2614,7 +2614,6 @@ ConnStateData::postHttpsAccept() assert(clientConnection->flags & (COMM_TRANSPARENT | COMM_INTERCEPTION)); request->url.host(clientConnection->local.toStr(ip, sizeof(ip))); request->url.port(clientConnection->local.port()); - request->myportname = port->name; ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL); acl_checklist->clientConnectionManager(this); From cb9ccb15ada931c0f502db9442ac95d85735d12c Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Fri, 22 Mar 2019 19:52:17 +0300 Subject: [PATCH 18/66] Unit tests fixing --- src/tests/stub_HttpRequest.cc | 5 +++++ src/tests/stub_libauth.cc | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tests/stub_HttpRequest.cc b/src/tests/stub_HttpRequest.cc index 4d3fcfebb6a..dda53055afe 100644 --- a/src/tests/stub_HttpRequest.cc +++ b/src/tests/stub_HttpRequest.cc @@ -57,5 +57,10 @@ void HttpRequest::packFirstLineInto(Packable *, bool) const STUB bool HttpRequest::sanityCheckStartLine(const char *, const size_t, Http::StatusCode *) STUB_RETVAL(false) void HttpRequest::hdrCacheInit() STUB bool HttpRequest::inheritProperties(const Http::Message *) STUB_RETVAL(false) +const Ip::Address& HttpRequest::indirectClientAddr() const STUB_RETREF(Ip::Address) +const Ip::Address& HttpRequest::clientAddr() const STUB_RETREF(Ip::Address) +const Ip::Address& HttpRequest::myAddr() const STUB_RETREF(Ip::Address) +const Ip::Address& HttpRequest::effectiveClientAddr(const bool useIndirect) const STUB_RETREF(Ip::Address) +Comm::ConnectionPointer HttpRequest::clientConnection() const STUB NotePairs::Pointer HttpRequest::notes() STUB_RETVAL(NotePairs::Pointer()) diff --git a/src/tests/stub_libauth.cc b/src/tests/stub_libauth.cc index 9d5b3e36825..7484ce237c6 100644 --- a/src/tests/stub_libauth.cc +++ b/src/tests/stub_libauth.cc @@ -70,8 +70,8 @@ void Auth::UserRequest::addAuthenticationInfoHeader(HttpReply *, int) STUB void Auth::UserRequest::addAuthenticationInfoTrailer(HttpReply *, int) STUB void Auth::UserRequest::releaseAuthServer() STUB const char * Auth::UserRequest::connLastHeader() STUB_RETVAL("stub") -AuthAclState Auth::UserRequest::authenticate(Auth::UserRequest::Pointer *, Http::HdrType, HttpRequest *, ConnStateData *, Ip::Address &, AccessLogEntry::Pointer &) STUB_RETVAL(AUTH_AUTHENTICATED) -AuthAclState Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer *, Http::HdrType, HttpRequest *, ConnStateData *, Ip::Address &, AccessLogEntry::Pointer &) STUB_RETVAL(AUTH_AUTHENTICATED) +AuthAclState Auth::UserRequest::authenticate(Auth::UserRequest::Pointer *, Http::HdrType, HttpRequest *, ConnStateData *, const Ip::Address &, AccessLogEntry::Pointer &) STUB_RETVAL(AUTH_AUTHENTICATED) +AuthAclState Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer *, Http::HdrType, HttpRequest *, ConnStateData *, const Ip::Address &, AccessLogEntry::Pointer &) STUB_RETVAL(AUTH_AUTHENTICATED) void Auth::UserRequest::AddReplyAuthHeader(HttpReply *, Auth::UserRequest::Pointer, HttpRequest *, int, int) STUB Auth::Scheme::Pointer Auth::UserRequest::scheme() const STUB_RETVAL(NULL) From f8a0ecb94d2a56754e01f3726a2402b33ef88bbe Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Fri, 22 Mar 2019 21:54:34 +0300 Subject: [PATCH 19/66] Some polishing * Use auto if possible. * Comments polishing. * Added a couple of TODOs. --- src/MasterXaction.h | 7 ++----- src/acl/FilledChecklist.cc | 2 +- src/acl/FilledChecklist.h | 9 ++++++--- src/format/Format.cc | 10 +++++----- src/ident/AclIdent.cc | 2 +- src/ssl/PeekingPeerConnector.cc | 14 +++++++------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/MasterXaction.h b/src/MasterXaction.h index 915a4e731d3..da304ab875e 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -65,11 +65,8 @@ class MasterXaction : public RefCountable XactionInitiator initiator; private: - /** - * The client connection manager, if known; - * Used for any response actions needed directly to the client. - * ie 1xx forwarding or connection pinning state changes - */ + + /// the client connection manager, if any CbcPointer clientConnectionManager_; /// the client TCP connection which originated this transaction diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 3ee173a0c21..f2d1a322412 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -228,7 +228,7 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re sslErrors(NULL), #endif requestErrorType(ERR_MAX), - connectionManager_(NULL), + connectionManager_(nullptr), fd_(-1), destinationDomainChecked_(false), sourceDomainChecked_(false), diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index a0c5f8575bb..0adeec0e985 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -58,13 +58,14 @@ class ACLFilledChecklist: public ACLChecklist /// connection manager may be unavailable. void clientConnection(Comm::ConnectionPointer); - /// Use either indirect client address or direct address - /// depending on the argument, passed as one of *uses_indirect_client + /// Configures srcAddr() to return either indirect client address or direct + /// address depending on the argument, passed as one of *uses_indirect_client /// configuration options. void configureClientAddr(const bool useIndirect); #if FOLLOW_X_FORWARDED_FOR - /// always use indirect client address instead of direct client address + /// Configures srcAddr() to always return available indirect client address + /// instead of direct client address. void forceIndirectAddr() { forceIndirectAddr_ = true; } #endif /* FOLLOW_X_FORWARDED_FOR */ @@ -80,6 +81,7 @@ class ACLFilledChecklist: public ACLChecklist /// The client side fd. It uses conn() if available int fd() const; + // TODO: remove as unused? /// set the client side FD void fd(int aDescriptor); @@ -135,6 +137,7 @@ class ACLFilledChecklist: public ACLChecklist ConnStateData *connectionManager_; /// a client connection, if any Comm::ConnectionPointer clientConnection_; + // TODO: remove as unused? int fd_; /**< may be available when conn_ is not */ bool destinationDomainChecked_; bool sourceDomainChecked_; diff --git a/src/format/Format.cc b/src/format/Format.cc index c9216a30e2e..b7b92e29cfc 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -1225,7 +1225,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CERT: if (al->request) { - ConnStateData *conn = al->request->clientConnectionManager().get(); + auto *conn = al->request->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) out = sslGetUserAttribute(ssl, fmt->data.header.header); @@ -1235,7 +1235,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CA_CERT: if (al->request) { - ConnStateData *conn = al->request->clientConnectionManager().get(); + auto *conn = al->request->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) out = sslGetCAAttribute(ssl, fmt->data.header.header); @@ -1263,7 +1263,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_CLIENT_SNI: if (al->request && al->request->clientConnectionManager().valid()) { - if (const ConnStateData *conn = al->request->clientConnectionManager().get()) { + if (const auto *conn = al->request->clientConnectionManager().get()) { if (!conn->tlsClientSni().isEmpty()) { sb = conn->tlsClientSni(); out = sb.c_str(); @@ -1274,7 +1274,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_SERVER_CERT_ERRORS: if (al->request && al->request->clientConnectionManager().valid()) { - if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager()->serverBump()) { + if (auto *srvBump = al->request->clientConnectionManager()->serverBump()) { const char *separator = fmt->data.string ? fmt->data.string : ":"; for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) { if (!sb.isEmpty()) @@ -1296,7 +1296,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_SERVER_CERT_SUBJECT: case LFT_SSL_SERVER_CERT_WHOLE: if (al->request && al->request->clientConnectionManager().valid()) { - if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager()->serverBump()) { + if (auto *srvBump = al->request->clientConnectionManager()->serverBump()) { if (X509 *serverCert = srvBump->serverCert.get()) { if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT) out = Ssl::GetX509UserAttribute(serverCert, "DN"); diff --git a/src/ident/AclIdent.cc b/src/ident/AclIdent.cc index ec737ac0ed0..1a736d83427 100644 --- a/src/ident/AclIdent.cc +++ b/src/ident/AclIdent.cc @@ -116,7 +116,7 @@ void IdentLookup::checkForAsync(ACLChecklist *cl)const { ACLFilledChecklist *checklist = Filled(cl); - const ConnStateData *conn = checklist->clientConnectionManager(); + const auto *conn = checklist->clientConnectionManager(); // check that ACLIdent::match() tested this lookup precondition assert(conn && Comm::IsConnOpen(conn->clientConnection)); debugs(28, 3, HERE << "Doing ident lookup" ); diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index 94a6e69162e..701b56844fa 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -47,7 +47,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSplice() { // Mark Step3 of bumping if (request->clientConnectionManager().valid()) { - if (Ssl::ServerBump *serverBump = request->clientConnectionManager()->serverBump()) { + if (auto *serverBump = request->clientConnectionManager()->serverBump()) { serverBump->step = Ssl::bumpStep3; } } @@ -114,7 +114,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSpliceMatched(const Ssl::BumpMode acti Ssl::BumpMode Ssl::PeekingPeerConnector::checkForPeekAndSpliceGuess() const { - if (const ConnStateData *csd = request->clientConnectionManager().valid()) { + if (const auto *csd = request->clientConnectionManager().valid()) { const Ssl::BumpMode currentMode = csd->sslBumpMode; if (currentMode == Ssl::bumpStare) { debugs(83,5, "default to bumping after staring"); @@ -140,7 +140,7 @@ Ssl::PeekingPeerConnector::initialize(Security::SessionPointer &serverSession) if (!Security::PeerConnector::initialize(serverSession)) return false; - if (ConnStateData *csd = request->clientConnectionManager().valid()) { + if (auto *csd = request->clientConnectionManager().valid()) { // client connection is required in the case we need to splice // or terminate client and server connections @@ -216,7 +216,7 @@ Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error) return; // remember the server certificate from the ErrorDetail object - if (Ssl::ServerBump *serverBump = request->clientConnectionManager()->serverBump()) { + if (auto *serverBump = request->clientConnectionManager()->serverBump()) { if (!serverBump->serverCert.get()) { // remember the server certificate from the ErrorDetail object if (error && error->detail && error->detail->peerCert()) @@ -230,7 +230,7 @@ Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error) // For intercepted connections, set the host name to the server // certificate CN. Otherwise, we just hope that CONNECT is using // a user-entered address (a host name or a user-entered IP). - const bool isConnectRequest = !request->clientConnectionManager()->port->flags.isIntercepted(); + const auto isConnectRequest = !request->clientConnectionManager()->port->flags.isIntercepted(); if (request->flags.sslPeek && !isConnectRequest) { if (X509 *srvX509 = serverBump->serverCert.get()) { if (const char *name = Ssl::CommonHostName(srvX509)) { @@ -319,7 +319,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() if (serverCertificateHandled) return; - if (ConnStateData *csd = request->clientConnectionManager().valid()) { + if (auto *csd = request->clientConnectionManager().valid()) { const int fd = serverConnection()->fd; Security::SessionPointer session(fd_table[fd].ssl); Security::CertPointer serverCert(SSL_get_peer_certificate(session.get())); @@ -338,7 +338,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() void Ssl::PeekingPeerConnector::serverCertificateVerified() { - if (ConnStateData *csd = request->clientConnectionManager().valid()) { + if (auto *csd = request->clientConnectionManager().valid()) { Security::CertPointer serverCert; if(Ssl::ServerBump *serverBump = csd->serverBump()) serverCert.resetAndLock(serverBump->serverCert.get()); From 74b9a4832d54e6da681086810da5187e762ec247 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Mar 2019 17:48:13 +0300 Subject: [PATCH 20/66] Fixes after review * Honour FOLLOW_X_FORWARDED_FOR * No connection manager/client connection for internal requests * Avoid initializing indirect_client_addr in HttpRequest constructor with client connection remote address. We should leave it empty until it is initialized with a genuine(calculated) indirect address. * Polishing method names, autos, comments etc. --- src/DelayId.cc | 7 ++++- src/FwdState.cc | 9 ++++--- src/HttpRequest.cc | 43 ++++++++++++++++--------------- src/HttpRequest.h | 12 +++------ src/acl/FilledChecklist.cc | 21 +++++++++++---- src/acl/FilledChecklist.h | 15 +++++------ src/adaptation/ecap/XactionRep.cc | 8 +++++- src/adaptation/icap/ModXact.cc | 7 ++++- src/client_side_request.cc | 2 +- src/clients/FtpRelay.cc | 7 +++-- src/format/Format.cc | 10 +++---- src/ident/AclIdent.cc | 2 +- src/ssl/PeekingPeerConnector.cc | 14 +++++----- src/tunnel.cc | 2 +- 14 files changed, 91 insertions(+), 68 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 6ad77b96cb7..16e39f6e451 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -90,7 +90,12 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) ch.reply = reply; HTTPMSGLOCK(reply); } - ch.configureClientAddr(Config.onoff.delay_pool_uses_indirect_client); +#if FOLLOW_X_FORWARDED_FOR + if (Config.onoff.delay_pool_uses_indirect_client) + ch.configureClientAddr(true); + else +#endif /* FOLLOW_X_FORWARDED_FOR */ + ch.configureClientAddr(false); if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck().allowed()) { diff --git a/src/FwdState.cc b/src/FwdState.cc index 535771063d6..518528e439d 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -1356,11 +1356,12 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) // maybe use TPROXY client address if (request && request->flags.spoofClientIp) { if (!conn->getPeer() || !conn->getPeer()->options.no_tproxy) { -#if LINUX_NETFILTER - conn->local = request->effectiveClientAddr(Config.onoff.tproxy_uses_indirect_client); -#else - conn->local = request->clientAddr(); +#if FOLLOW_X_FORWARDED_FOR && LINUX_NETFILTER + if (Config.onoff.tproxy_uses_indirect_client) + conn->local = request->indirectClientAddr(); + else #endif + conn->local = request->clientAddr(); conn->local.port(0); // let OS pick the source port to prevent address clashes // some flags need setting on the socket to use this address conn->flags |= COMM_DOBIND; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 4199d9f8942..b29eca84fd6 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -122,12 +122,6 @@ HttpRequest::init() flags.ignoreCc = port->ignore_cc; } } -#if FOLLOW_X_FORWARDED_FOR - // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) - // not details about the TCP connection itself - if (clientConnection()) - indirect_client_addr = clientConnection()->remote; -#endif /* FOLLOW_X_FORWARDED_FOR */ } void @@ -725,11 +719,11 @@ HttpRequest::prepareForDownloader(Downloader *aDownloader) header.putStr(Http::HdrType::HOST, url.host()); header.putTime(Http::HdrType::DATE, squid_curtime); downloader = aDownloader; - toInternal(); + makeInternal(); } void -HttpRequest::toInternal() +HttpRequest::makeInternal() { /* Internally created requests cannot have bodies today */ content_length = 0; @@ -737,15 +731,13 @@ HttpRequest::toInternal() internal = true; } -const Ip::Address& -HttpRequest::effectiveClientAddr(const bool useIndirect) const +CbcPointer & +HttpRequest::clientConnectionManager() { -#if FOLLOW_X_FORWARDED_FOR - if (useIndirect) - return indirectClientAddr(); - else -#endif - return clientAddr(); + if (!internal) + return masterXaction->clientConnectionManager(); + static CbcPointer noManager; + return noManager; } static const Ip::Address& @@ -760,9 +752,11 @@ NoAddr() const Ip::Address& HttpRequest::clientAddr() const { - return internal ? NoAddr() : - masterXaction->clientConnection() ? - masterXaction->clientConnection()->remote : client_addr; + if (internal) + return NoAddr(); + if (clientConnection()) + return clientConnection()->remote; + return client_addr; } void @@ -784,7 +778,11 @@ HttpRequest::myAddr() const const Ip::Address& HttpRequest::indirectClientAddr() const { - return internal ? NoAddr() : indirect_client_addr; + if (internal) + return NoAddr(); + if (indirect_client_addr.port()) // configured + return indirect_client_addr; + return clientAddr(); } void @@ -875,5 +873,8 @@ FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry Comm::ConnectionPointer HttpRequest::clientConnection() const { - return masterXaction->clientConnection(); + if (!internal) + return masterXaction->clientConnection(); + static Comm::ConnectionPointer noConnection; + return noConnection; } diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 629cab01930..dceca8fc58a 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -138,9 +138,8 @@ class HttpRequest: public Http::Message int imslen; - /// Mark this request as internally built. For internal requests, - /// client connection addresses are undefined. - void toInternal(); + /// this request was initiated by Squid (rather than received on a client connection) + void makeInternal(); /// supply Downloader-specific settings void prepareForDownloader(Downloader *); @@ -154,11 +153,8 @@ class HttpRequest: public Http::Message /// the local address of the client connection const Ip::Address& myAddr() const; - /// indirect client address, if allowed, or direct client address - const Ip::Address& effectiveClientAddr(const bool useIndirect) const; - /// the client connection manager of the underlying transaction, if any - CbcPointer &clientConnectionManager() { return masterXaction->clientConnectionManager(); } + CbcPointer &clientConnectionManager(); /// the client connection of the underlying transaction, if any Comm::ConnectionPointer clientConnection() const; @@ -275,7 +271,7 @@ class HttpRequest: public Http::Message Ip::Address indirect_client_addr; #endif /* FOLLOW_X_FORWARDED_FOR */ - /// whether this is an internally built request + /// whether this request was initiated by Squid itself bool internal; protected: diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index f2d1a322412..fef31dbe312 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -254,7 +254,12 @@ ACLFilledChecklist::setRequest(HttpRequest *httpRequest) if (httpRequest) { request = httpRequest; HTTPMSGLOCK(request); - src_addr = request->effectiveClientAddr(Config.onoff.acl_uses_indirect_client); +#if FOLLOW_X_FORWARDED_FOR + if (Config.onoff.acl_uses_indirect_client) + src_addr = request->indirectClientAddr(); + else +#endif /* FOLLOW_X_FORWARDED_FOR */ + src_addr = request->clientAddr(); my_addr = request->myAddr(); setClientConnectionManager(request->clientConnectionManager().get()); setClientConnection(request->clientConnection()); @@ -279,8 +284,12 @@ void ACLFilledChecklist::configureClientAddr(const bool useIndirect) { assert(request); - src_addr = Config.onoff.acl_uses_indirect_client ? - request->effectiveClientAddr(useIndirect) : request->clientAddr(); +#if FOLLOW_X_FORWARDED_FOR + if (Config.onoff.acl_uses_indirect_client && useIndirect) + src_addr = request->indirectClientAddr(); + else +#endif /* FOLLOW_X_FORWARDED_FOR */ + src_addr = request->clientAddr(); } /// Initializes the client connection manager; does nothing @@ -303,11 +312,13 @@ ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) { - if(!conn) + if (!conn) return; - if (clientConnection_) + if (clientConnection_) { + Must(conn == clientConnection_); return; + } clientConnection_ = conn; diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 0adeec0e985..ec99f7d11c0 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -58,10 +58,9 @@ class ACLFilledChecklist: public ACLChecklist /// connection manager may be unavailable. void clientConnection(Comm::ConnectionPointer); - /// Configures srcAddr() to return either indirect client address or direct - /// address depending on the argument, passed as one of *uses_indirect_client - /// configuration options. - void configureClientAddr(const bool useIndirect); + /// Configures srcAddr() to return either indirect client address (if possible) + /// or direct address. + void configureClientAddr(const bool wantIndirect); #if FOLLOW_X_FORWARDED_FOR /// Configures srcAddr() to always return available indirect client address @@ -72,16 +71,16 @@ class ACLFilledChecklist: public ACLChecklist /// the associated client connection manager or nil ConnStateData *clientConnectionManager() const; - /// remote address, direct or indirect + /// remote/source address of a client-to-Squid connection, direct or indirect const Ip::Address &srcAddr() const; - /// local address + /// local/destination address of a client-to-Squid connection const Ip::Address &myAddr() const { return my_addr; } /// The client side fd. It uses conn() if available int fd() const; - // TODO: remove as unused? + // TODO: Unused. Remove? /// set the client side FD void fd(int aDescriptor); @@ -137,7 +136,7 @@ class ACLFilledChecklist: public ACLChecklist ConnStateData *connectionManager_; /// a client connection, if any Comm::ConnectionPointer clientConnection_; - // TODO: remove as unused? + // TODO: Unused. Remove? int fd_; /**< may be available when conn_ is not */ bool destinationDomainChecked_; bool sourceDomainChecked_; diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index 83d13ff72fe..3194eba9bff 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -128,7 +128,13 @@ Adaptation::Ecap::XactionRep::clientIpValue() const // TODO: move this logic into HttpRequest::clientIp(bool) and // HttpRequest::clientIpString(bool) and reuse everywhere if (TheConfig.send_client_ip && request) { - Ip::Address client_addr = request->effectiveClientAddr(TheConfig.use_indirect_client); + Ip::Address client_addr; +#if FOLLOW_X_FORWARDED_FOR + if (TheConfig.use_indirect_client) + client_addr = request->indirectClientAddr(); + else +#endif + client_addr = request->clientAddr(); if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) { char ntoabuf[MAX_IPSTRLEN] = ""; client_addr.toStr(ntoabuf,MAX_IPSTRLEN); diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index 72d043b3a03..2545026fa8c 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1473,7 +1473,12 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) if (TheConfig.send_client_ip && request) { Ip::Address client_addr; - client_addr = request->effectiveClientAddr(TheConfig.use_indirect_client); +#if FOLLOW_X_FORWARDED_FOR + if (TheConfig.use_indirect_client) + client_addr = request->indirectClientAddr(); + else +#endif /* FOLLOW_X_FORWARDED_FOR */ + client_addr = request->clientAddr(); if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) buf.appendf("X-Client-IP: %s\r\n", client_addr.toStr(ntoabuf,MAX_IPSTRLEN)); } diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 38a2797967d..26796c3a155 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -375,7 +375,7 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre * objects ? */ - request->toInternal(); + request->makeInternal(); http->initRequest(request); diff --git a/src/clients/FtpRelay.cc b/src/clients/FtpRelay.cc index 87935049d13..209bab71fd5 100644 --- a/src/clients/FtpRelay.cc +++ b/src/clients/FtpRelay.cc @@ -227,7 +227,7 @@ Ftp::Relay::serverComplete() Ftp::MasterState & Ftp::Relay::updateMaster() { - CbcPointer &mgr = fwd->request->clientConnectionManager(); + const auto &mgr = fwd->request->clientConnectionManager(); if (mgr.valid()) { if (Ftp::Server *srv = dynamic_cast(mgr.get())) return *srv->master; @@ -770,9 +770,8 @@ void Ftp::Relay::stopOriginWait(int code) { if (originWaitInProgress) { - CbcPointer &mgr = fwd->request->clientConnectionManager(); - if (mgr.valid()) { - if (Ftp::Server *srv = dynamic_cast(mgr.get())) { + if (const auto mgr = fwd->request->clientConnectionManager().get()) { + if (const auto srv = dynamic_cast(mgr)) { typedef UnaryMemFunT CbDialer; AsyncCall::Pointer call = asyncCall(11, 3, "Ftp::Server::stopWaitingForOrigin", CbDialer(srv, &Ftp::Server::stopWaitingForOrigin, code)); diff --git a/src/format/Format.cc b/src/format/Format.cc index b7b92e29cfc..f92a5b8b968 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -1225,7 +1225,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CERT: if (al->request) { - auto *conn = al->request->clientConnectionManager().get(); + const auto conn = al->request->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) out = sslGetUserAttribute(ssl, fmt->data.header.header); @@ -1235,7 +1235,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CA_CERT: if (al->request) { - auto *conn = al->request->clientConnectionManager().get(); + const auto conn = al->request->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) out = sslGetCAAttribute(ssl, fmt->data.header.header); @@ -1263,7 +1263,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_CLIENT_SNI: if (al->request && al->request->clientConnectionManager().valid()) { - if (const auto *conn = al->request->clientConnectionManager().get()) { + if (const auto conn = al->request->clientConnectionManager().get()) { if (!conn->tlsClientSni().isEmpty()) { sb = conn->tlsClientSni(); out = sb.c_str(); @@ -1274,7 +1274,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_SERVER_CERT_ERRORS: if (al->request && al->request->clientConnectionManager().valid()) { - if (auto *srvBump = al->request->clientConnectionManager()->serverBump()) { + if (const auto srvBump = al->request->clientConnectionManager()->serverBump()) { const char *separator = fmt->data.string ? fmt->data.string : ":"; for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) { if (!sb.isEmpty()) @@ -1296,7 +1296,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_SERVER_CERT_SUBJECT: case LFT_SSL_SERVER_CERT_WHOLE: if (al->request && al->request->clientConnectionManager().valid()) { - if (auto *srvBump = al->request->clientConnectionManager()->serverBump()) { + if (const auto srvBump = al->request->clientConnectionManager()->serverBump()) { if (X509 *serverCert = srvBump->serverCert.get()) { if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT) out = Ssl::GetX509UserAttribute(serverCert, "DN"); diff --git a/src/ident/AclIdent.cc b/src/ident/AclIdent.cc index 1a736d83427..54e037622c2 100644 --- a/src/ident/AclIdent.cc +++ b/src/ident/AclIdent.cc @@ -116,7 +116,7 @@ void IdentLookup::checkForAsync(ACLChecklist *cl)const { ACLFilledChecklist *checklist = Filled(cl); - const auto *conn = checklist->clientConnectionManager(); + const auto conn = checklist->clientConnectionManager(); // check that ACLIdent::match() tested this lookup precondition assert(conn && Comm::IsConnOpen(conn->clientConnection)); debugs(28, 3, HERE << "Doing ident lookup" ); diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index 701b56844fa..9a32fb901e7 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -46,8 +46,8 @@ void Ssl::PeekingPeerConnector::checkForPeekAndSplice() { // Mark Step3 of bumping - if (request->clientConnectionManager().valid()) { - if (auto *serverBump = request->clientConnectionManager()->serverBump()) { + if (const auto manager = request->clientConnectionManager().get()) { + if (const auto serverBump = manager->serverBump()) { serverBump->step = Ssl::bumpStep3; } } @@ -114,7 +114,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSpliceMatched(const Ssl::BumpMode acti Ssl::BumpMode Ssl::PeekingPeerConnector::checkForPeekAndSpliceGuess() const { - if (const auto *csd = request->clientConnectionManager().valid()) { + if (const auto csd = request->clientConnectionManager().valid()) { const Ssl::BumpMode currentMode = csd->sslBumpMode; if (currentMode == Ssl::bumpStare) { debugs(83,5, "default to bumping after staring"); @@ -140,7 +140,7 @@ Ssl::PeekingPeerConnector::initialize(Security::SessionPointer &serverSession) if (!Security::PeerConnector::initialize(serverSession)) return false; - if (auto *csd = request->clientConnectionManager().valid()) { + if (const auto csd = request->clientConnectionManager().valid()) { // client connection is required in the case we need to splice // or terminate client and server connections @@ -216,7 +216,7 @@ Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error) return; // remember the server certificate from the ErrorDetail object - if (auto *serverBump = request->clientConnectionManager()->serverBump()) { + if (const auto serverBump = request->clientConnectionManager()->serverBump()) { if (!serverBump->serverCert.get()) { // remember the server certificate from the ErrorDetail object if (error && error->detail && error->detail->peerCert()) @@ -319,7 +319,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() if (serverCertificateHandled) return; - if (auto *csd = request->clientConnectionManager().valid()) { + if (const auto csd = request->clientConnectionManager().get()) { const int fd = serverConnection()->fd; Security::SessionPointer session(fd_table[fd].ssl); Security::CertPointer serverCert(SSL_get_peer_certificate(session.get())); @@ -338,7 +338,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() void Ssl::PeekingPeerConnector::serverCertificateVerified() { - if (auto *csd = request->clientConnectionManager().valid()) { + if (const auto csd = request->clientConnectionManager().get()) { Security::CertPointer serverCert; if(Ssl::ServerBump *serverBump = csd->serverBump()) serverCert.resetAndLock(serverBump->serverCert.get()); diff --git a/src/tunnel.cc b/src/tunnel.cc index f973f72e90f..6f2819a15bc 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1358,7 +1358,7 @@ switchToTunnel(HttpRequest *request, Comm::ConnectionPointer &clientConn, Comm:: ++statCounter.server.all.requests; ++statCounter.server.other.requests; - auto conn = request->clientConnectionManager().get(); + const auto conn = request->clientConnectionManager().get(); Must(conn); Http::StreamPointer context = conn->pipeline.front(); Must(context && context->http); From 1d9260b5846506f5c5fb504117a66c6b11953100 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sun, 31 Mar 2019 21:03:52 +0300 Subject: [PATCH 21/66] Added Address::isEmpty() Also prefer CbcPointer::valid() over CbcPointer::get() in 'if' blocks (partially undone 74b9a4). Also added a TODO that Downloader should use the original transaction. --- src/Downloader.cc | 1 + src/HttpRequest.cc | 2 +- src/clients/FtpRelay.cc | 2 +- src/ip/Address.cc | 7 +++++++ src/ip/Address.h | 3 +++ src/ssl/PeekingPeerConnector.cc | 6 +++--- 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Downloader.cc b/src/Downloader.cc index ae2c349e39c..d6415957061 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -128,6 +128,7 @@ Downloader::buildRequest() { const HttpRequestMethod method = Http::METHOD_GET; + // TODO: reuse the original transaction, if available const MasterXaction::Pointer mx = new MasterXaction(initiator_); HttpRequest *const request = HttpRequest::FromUrl(url_.c_str(), mx, method); if (!request) { diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index b29eca84fd6..cb233c0a346 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -780,7 +780,7 @@ HttpRequest::indirectClientAddr() const { if (internal) return NoAddr(); - if (indirect_client_addr.port()) // configured + if (!indirect_client_addr.isEmpty()) return indirect_client_addr; return clientAddr(); } diff --git a/src/clients/FtpRelay.cc b/src/clients/FtpRelay.cc index 209bab71fd5..b45ec1ad60f 100644 --- a/src/clients/FtpRelay.cc +++ b/src/clients/FtpRelay.cc @@ -770,7 +770,7 @@ void Ftp::Relay::stopOriginWait(int code) { if (originWaitInProgress) { - if (const auto mgr = fwd->request->clientConnectionManager().get()) { + if (const auto mgr = fwd->request->clientConnectionManager().valid()) { if (const auto srv = dynamic_cast(mgr)) { typedef UnaryMemFunT CbDialer; AsyncCall::Pointer call = asyncCall(11, 3, "Ftp::Server::stopWaitingForOrigin", diff --git a/src/ip/Address.cc b/src/ip/Address.cc index 6761e94624b..1a7e357ec97 100644 --- a/src/ip/Address.cc +++ b/src/ip/Address.cc @@ -172,6 +172,13 @@ Ip::Address::isAnyAddr() const return IN6_IS_ADDR_UNSPECIFIED(&mSocketAddr_.sin6_addr) || IN6_ARE_ADDR_EQUAL(&mSocketAddr_.sin6_addr, &v4_anyaddr); } +bool +Ip::Address::isEmpty() const +{ + static const Ip::Address emptyAddr; + return *this == emptyAddr; +} + /// NOTE: Does NOT clear the Port stored. Ony the Address and Type. void Ip::Address::setAnyAddr() diff --git a/src/ip/Address.h b/src/ip/Address.h index 138fe3c65cb..69e807156c4 100644 --- a/src/ip/Address.h +++ b/src/ip/Address.h @@ -134,6 +134,9 @@ class Address */ bool isSiteLocalAuto() const; + /// whether the address is the same as the one created with default constructor + bool isEmpty() const; + /*@}*/ /** Retrieve the Port if stored. diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index 9a32fb901e7..cd26aa31f02 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -46,7 +46,7 @@ void Ssl::PeekingPeerConnector::checkForPeekAndSplice() { // Mark Step3 of bumping - if (const auto manager = request->clientConnectionManager().get()) { + if (const auto manager = request->clientConnectionManager().valid()) { if (const auto serverBump = manager->serverBump()) { serverBump->step = Ssl::bumpStep3; } @@ -319,7 +319,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() if (serverCertificateHandled) return; - if (const auto csd = request->clientConnectionManager().get()) { + if (const auto csd = request->clientConnectionManager().valid()) { const int fd = serverConnection()->fd; Security::SessionPointer session(fd_table[fd].ssl); Security::CertPointer serverCert(SSL_get_peer_certificate(session.get())); @@ -338,7 +338,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() void Ssl::PeekingPeerConnector::serverCertificateVerified() { - if (const auto csd = request->clientConnectionManager().get()) { + if (const auto csd = request->clientConnectionManager().valid()) { Security::CertPointer serverCert; if(Ssl::ServerBump *serverBump = csd->serverBump()) serverCert.resetAndLock(serverBump->serverCert.get()); From 119ec517b5ab82042edee4ef9ae130809de6bcbd Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 1 Apr 2019 14:46:22 +0300 Subject: [PATCH 22/66] Autoformatted --- src/DelayId.cc | 2 +- src/HttpRequest.cc | 13 +++++++------ src/MasterXaction.cc | 1 + src/MasterXaction.h | 2 +- src/acl/FilledChecklist.cc | 3 +-- src/acl/FilledChecklist.h | 6 +++--- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 16e39f6e451..769428e0aff 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -95,7 +95,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) ch.configureClientAddr(true); else #endif /* FOLLOW_X_FORWARDED_FOR */ - ch.configureClientAddr(false); + ch.configureClientAddr(false); if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck().allowed()) { diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index cb233c0a346..fb3ce6eeba9 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -770,8 +770,8 @@ const Ip::Address& HttpRequest::myAddr() const { return internal ? NoAddr(): - masterXaction->clientConnection() ? - masterXaction->clientConnection()->local : my_addr; + masterXaction->clientConnection() ? + masterXaction->clientConnection()->local : my_addr; } #if FOLLOW_X_FORWARDED_FOR @@ -779,7 +779,7 @@ const Ip::Address& HttpRequest::indirectClientAddr() const { if (internal) - return NoAddr(); + return NoAddr(); if (!indirect_client_addr.isEmpty()) return indirect_client_addr; return clientAddr(); @@ -873,8 +873,9 @@ FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry Comm::ConnectionPointer HttpRequest::clientConnection() const { - if (!internal) + if (!internal) return masterXaction->clientConnection(); - static Comm::ConnectionPointer noConnection; - return noConnection; + static Comm::ConnectionPointer noConnection; + return noConnection; } + diff --git a/src/MasterXaction.cc b/src/MasterXaction.cc index cb672028b71..862fed46b31 100644 --- a/src/MasterXaction.cc +++ b/src/MasterXaction.cc @@ -33,3 +33,4 @@ MasterXaction::clientConnection() { return clientConnectionManager_.valid() ? clientConnectionManager_->clientConnection : clientConnection_; } + diff --git a/src/MasterXaction.h b/src/MasterXaction.h index da304ab875e..8d35498754a 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -10,8 +10,8 @@ #define SQUID_SRC_MASTERXACTION_H #include "anyp/forward.h" -#include "base/CbcPointer.h" #include "anyp/PortCfg.h" +#include "base/CbcPointer.h" #include "base/InstanceId.h" #include "base/Lock.h" #include "base/RefCount.h" diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index fef31dbe312..2cc92fe8a08 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -289,7 +289,7 @@ ACLFilledChecklist::configureClientAddr(const bool useIndirect) src_addr = request->indirectClientAddr(); else #endif /* FOLLOW_X_FORWARDED_FOR */ - src_addr = request->clientAddr(); + src_addr = request->clientAddr(); } /// Initializes the client connection manager; does nothing @@ -306,7 +306,6 @@ ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) connectionManager_ = cbdataReference(aConn); } - /// Initializes the client connection and addresses; does nothing /// if already initialized. void diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index ec99f7d11c0..532df67b1d6 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -63,9 +63,9 @@ class ACLFilledChecklist: public ACLChecklist void configureClientAddr(const bool wantIndirect); #if FOLLOW_X_FORWARDED_FOR - /// Configures srcAddr() to always return available indirect client address - /// instead of direct client address. - void forceIndirectAddr() { forceIndirectAddr_ = true; } + /// Configures srcAddr() to always return available indirect client address + /// instead of direct client address. + void forceIndirectAddr() { forceIndirectAddr_ = true; } #endif /* FOLLOW_X_FORWARDED_FOR */ /// the associated client connection manager or nil From c47540e2e29fe46068e38841f95199f0800aedbd Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 1 Apr 2019 15:33:23 +0300 Subject: [PATCH 23/66] Fixed unit tests --- src/tests/stub_HttpRequest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/stub_HttpRequest.cc b/src/tests/stub_HttpRequest.cc index dda53055afe..28bcd327680 100644 --- a/src/tests/stub_HttpRequest.cc +++ b/src/tests/stub_HttpRequest.cc @@ -60,7 +60,7 @@ bool HttpRequest::inheritProperties(const Http::Message *) STUB_RETVAL(false) const Ip::Address& HttpRequest::indirectClientAddr() const STUB_RETREF(Ip::Address) const Ip::Address& HttpRequest::clientAddr() const STUB_RETREF(Ip::Address) const Ip::Address& HttpRequest::myAddr() const STUB_RETREF(Ip::Address) -const Ip::Address& HttpRequest::effectiveClientAddr(const bool useIndirect) const STUB_RETREF(Ip::Address) Comm::ConnectionPointer HttpRequest::clientConnection() const STUB +CbcPointer &HttpRequest::clientConnectionManager() STUB_RETREF(CbcPointer) NotePairs::Pointer HttpRequest::notes() STUB_RETVAL(NotePairs::Pointer()) From 2f6c8f8a2489442d0a56eb641d2adf88fa683915 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 2 Apr 2019 20:57:16 +0300 Subject: [PATCH 24/66] Honour delay_pool_uses_indirect_client in delay pools context This old behavior was changed in this branch: when configuring check list for delay_access, both acl_uses_indirect_client and delay_pool_uses_indirect_client were examined before configuring direct/indirect client addresses. We need to restore the old (correct) behavior here so that the same addresses were used for ACL matching and indexing. --- src/DelayId.cc | 4 ++-- src/acl/FilledChecklist.cc | 30 +++++++++--------------------- src/acl/FilledChecklist.h | 20 +++++++++++++------- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 769428e0aff..558db8c8320 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -92,10 +92,10 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) } #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.delay_pool_uses_indirect_client) - ch.configureClientAddr(true); + ch.forceIndirectAddr(); else #endif /* FOLLOW_X_FORWARDED_FOR */ - ch.configureClientAddr(false); + ch.forceDirectAddr(); if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck().allowed()) { diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 2cc92fe8a08..eec9c910e71 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -41,9 +41,7 @@ ACLFilledChecklist::ACLFilledChecklist() : fd_(-1), destinationDomainChecked_(false), sourceDomainChecked_(false), -#if FOLLOW_X_FORWARDED_FOR - forceIndirectAddr_(false) -#endif + srcAddrRestrictions_(noRestrictions) { my_addr.setEmpty(); src_addr.setEmpty(); @@ -152,10 +150,15 @@ ACLFilledChecklist::clientConnectionManager() const const Ip::Address & ACLFilledChecklist::srcAddr() const { + if (request) { #if FOLLOW_X_FORWARDED_FOR - if (forceIndirectAddr_ && request) - return request->indirectClientAddr(); + if (srcAddrRestrictions_ == forceIndirect) + return request->indirectClientAddr(); #endif /* FOLLOW_X_FORWARDED_FOR */ + if (srcAddrRestrictions_ == forceDirect) + return request->clientAddr(); + assert(srcAddrRestrictions_ == noRestrictions); + } return src_addr; } @@ -232,10 +235,7 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re fd_(-1), destinationDomainChecked_(false), sourceDomainChecked_(false), -#if FOLLOW_X_FORWARDED_FOR - forceIndirectAddr_(false) -#endif - + srcAddrRestrictions_(noRestrictions) { my_addr.setEmpty(); src_addr.setEmpty(); @@ -280,18 +280,6 @@ ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) setClientConnection(conn); } -void -ACLFilledChecklist::configureClientAddr(const bool useIndirect) -{ - assert(request); -#if FOLLOW_X_FORWARDED_FOR - if (Config.onoff.acl_uses_indirect_client && useIndirect) - src_addr = request->indirectClientAddr(); - else -#endif /* FOLLOW_X_FORWARDED_FOR */ - src_addr = request->clientAddr(); -} - /// Initializes the client connection manager; does nothing /// if already initialized. void diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 532df67b1d6..aa0ac44dbd2 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -58,16 +58,15 @@ class ACLFilledChecklist: public ACLChecklist /// connection manager may be unavailable. void clientConnection(Comm::ConnectionPointer); - /// Configures srcAddr() to return either indirect client address (if possible) - /// or direct address. - void configureClientAddr(const bool wantIndirect); - #if FOLLOW_X_FORWARDED_FOR /// Configures srcAddr() to always return available indirect client address /// instead of direct client address. - void forceIndirectAddr() { forceIndirectAddr_ = true; } + void forceIndirectAddr() { srcAddrRestrictions_ = forceIndirect; } #endif /* FOLLOW_X_FORWARDED_FOR */ + /// Configures srcAddr() to always return direct client address + void forceDirectAddr() { srcAddrRestrictions_ = forceDirect; } + /// the associated client connection manager or nil ConnStateData *clientConnectionManager() const; @@ -142,10 +141,17 @@ class ACLFilledChecklist: public ACLChecklist bool sourceDomainChecked_; Ip::Address src_addr; Ip::Address my_addr; + + typedef enum { + noRestrictions, #if FOLLOW_X_FORWARDED_FOR - /// whether we will use indirect client address instead of direct address - bool forceIndirectAddr_; + forceIndirect, ///< will use indirect client address instead of direct address #endif /* FOLLOW_X_FORWARDED_FOR */ + forceDirect ///< will use direct client address instead of indirect address (if configured) + } SrcAddrRestrictions; + + /// forces using either direct or indirect client address + SrcAddrRestrictions srcAddrRestrictions_; /// not implemented; will cause link failures if used ACLFilledChecklist(const ACLFilledChecklist &); /// not implemented; will cause link failures if used From 7515e06cdeab9496affc74bc3ee5b85189b2697f Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 2 Apr 2019 22:41:38 +0300 Subject: [PATCH 25/66] Fixed unit tests for disabled follow-x-forwarded-for --- src/tests/stub_HttpRequest.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/stub_HttpRequest.cc b/src/tests/stub_HttpRequest.cc index 28bcd327680..41658906e02 100644 --- a/src/tests/stub_HttpRequest.cc +++ b/src/tests/stub_HttpRequest.cc @@ -57,7 +57,9 @@ void HttpRequest::packFirstLineInto(Packable *, bool) const STUB bool HttpRequest::sanityCheckStartLine(const char *, const size_t, Http::StatusCode *) STUB_RETVAL(false) void HttpRequest::hdrCacheInit() STUB bool HttpRequest::inheritProperties(const Http::Message *) STUB_RETVAL(false) +#if FOLLOW_X_FORWARDED_FOR const Ip::Address& HttpRequest::indirectClientAddr() const STUB_RETREF(Ip::Address) +#endif /* FOLLOW_X_FORWARDED_FOR */ const Ip::Address& HttpRequest::clientAddr() const STUB_RETREF(Ip::Address) const Ip::Address& HttpRequest::myAddr() const STUB_RETREF(Ip::Address) Comm::ConnectionPointer HttpRequest::clientConnection() const STUB From 79e18ca663af08ec49892440a6caec19055572e6 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 22 Apr 2019 18:00:31 +0300 Subject: [PATCH 26/66] Addressing review comments Not finished yet. --- src/FwdState.cc | 9 ++-- src/HttpRequest.cc | 3 +- src/HttpRequest.h | 6 +-- src/acl/FilledChecklist.cc | 88 ++++++++++++++++------------------ src/acl/FilledChecklist.h | 26 +++------- src/adaptation/icap/ModXact.cc | 2 +- src/client_side.cc | 22 ++++----- src/client_side_request.cc | 2 +- src/comm/TcpAcceptor.cc | 2 +- src/servers/FtpServer.cc | 2 +- src/servers/Http1Server.cc | 2 +- 11 files changed, 71 insertions(+), 93 deletions(-) diff --git a/src/FwdState.cc b/src/FwdState.cc index 518528e439d..cee55046856 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -317,12 +317,11 @@ FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, Ht if ( Config.accessList.miss && !request->clientAddr().isNoAddr() && !request->flags.internal && request->url.getScheme() != AnyP::PROTO_CACHE_OBJECT) { - /** - * Check if this host is allowed to fetch MISSES from us (miss_access). - * Intentionally replace the src_addr automatically selected by the checklist code - * we do NOT want the indirect client address to be tested here. - */ + // Check if this host is allowed to fetch MISSES from us (miss_access). ACLFilledChecklist ch(Config.accessList.miss, request, NULL); + // TODO: Explain this acl_uses_indirect_client violation in squid.conf. + // TODO: Refer to the above squid.conf documentation here. + ch.forceDirectAddr(); ch.al = al; ch.syncAle(request, nullptr); if (ch.fastCheck().denied()) { diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index fb3ce6eeba9..5e85ec5d98f 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -788,8 +788,7 @@ HttpRequest::indirectClientAddr() const void HttpRequest::ignoreIndirectClientAddr() { - indirect_client_addr = clientAddr(); - indirect_client_addr.port(0); + indirect_client_addr.setEmpty(); } #endif /* FOLLOW_X_FORWARDED_FOR */ diff --git a/src/HttpRequest.h b/src/HttpRequest.h index dceca8fc58a..35186605701 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -265,10 +265,10 @@ class HttpRequest: public Http::Message /// and(or) by annotate_transaction/annotate_client ACLs. NotePairs::Pointer theNotes; - Ip::Address client_addr; - Ip::Address my_addr; + Ip::Address client_addr; ///< source address of a non-TCP (e.g. ICMP) client + Ip::Address my_addr; ///< local address which a non-TCP (e.g., ICMP) client connects to #if FOLLOW_X_FORWARDED_FOR - Ip::Address indirect_client_addr; + Ip::Address indirect_client_addr; ///< calculated client address, after applying X-Forwarded-For rules #endif /* FOLLOW_X_FORWARDED_FOR */ /// whether this request was initiated by Squid itself diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index eec9c910e71..24f2d09accb 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -40,8 +40,7 @@ ACLFilledChecklist::ACLFilledChecklist() : connectionManager_(nullptr), fd_(-1), destinationDomainChecked_(false), - sourceDomainChecked_(false), - srcAddrRestrictions_(noRestrictions) + sourceDomainChecked_(false) { my_addr.setEmpty(); src_addr.setEmpty(); @@ -147,19 +146,20 @@ ACLFilledChecklist::clientConnectionManager() const return cbdataReferenceValid(connectionManager_) ? connectionManager_ : nullptr; } -const Ip::Address & -ACLFilledChecklist::srcAddr() const -{ - if (request) { #if FOLLOW_X_FORWARDED_FOR - if (srcAddrRestrictions_ == forceIndirect) - return request->indirectClientAddr(); -#endif /* FOLLOW_X_FORWARDED_FOR */ - if (srcAddrRestrictions_ == forceDirect) - return request->clientAddr(); - assert(srcAddrRestrictions_ == noRestrictions); - } - return src_addr; +void +ACLFilledChecklist::forceIndirectAddr() +{ + assert(request); + src_addr = request->indirectClientAddr(); +} +#endif + +void +ACLFilledChecklist::forceDirectAddr() +{ + assert(request); + src_addr = request->clientAddr(); } int @@ -234,8 +234,7 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re connectionManager_(nullptr), fd_(-1), destinationDomainChecked_(false), - sourceDomainChecked_(false), - srcAddrRestrictions_(noRestrictions) + sourceDomainChecked_(false) { my_addr.setEmpty(); src_addr.setEmpty(); @@ -247,55 +246,52 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re setIdent(ident); } -void -ACLFilledChecklist::setRequest(HttpRequest *httpRequest) +void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) { assert(!request); if (httpRequest) { request = httpRequest; HTTPMSGLOCK(request); -#if FOLLOW_X_FORWARDED_FOR - if (Config.onoff.acl_uses_indirect_client) - src_addr = request->indirectClientAddr(); - else -#endif /* FOLLOW_X_FORWARDED_FOR */ - src_addr = request->clientAddr(); - my_addr = request->myAddr(); setClientConnectionManager(request->clientConnectionManager().get()); - setClientConnection(request->clientConnection()); + if (!clientConnectionManager()) // could not take the connection from the connection manager + setClientConnection(request->clientConnection()); } } +/// configures addresses of the client-to-Squid connection void -ACLFilledChecklist::clientConnectionManager(ConnStateData *aConn) +ACLFilledChecklist::setClientSideAddresses() { - setClientConnectionManager(aConn); - if (clientConnectionManager()) - setClientConnection(clientConnectionManager()->clientConnection); -} - -void -ACLFilledChecklist::clientConnection(Comm::ConnectionPointer conn) -{ - setClientConnection(conn); + if (request) { +#if FOLLOW_X_FORWARDED_FOR + if (Config.onoff.acl_uses_indirect_client) { + assert(src_addr != request->indirectClientAddr()); + src_addr = request->indirectClientAddr(); + } else +#endif + { + assert(src_addr != request->clientAddr()); + src_addr = request->clientAddr(); + } + my_addr = request->myAddr(); + } else if (clientConnection_) { + src_addr = clientConnection_->remote; + my_addr = clientConnection_->local; + } } -/// Initializes the client connection manager; does nothing -/// if already initialized. void ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) { if (!(aConn && cbdataReferenceValid(aConn))) return; - if (clientConnectionManager()) - return; + if (!clientConnectionManager()) + connectionManager_ = cbdataReference(aConn); - connectionManager_ = cbdataReference(aConn); + setClientConnection(clientConnectionManager()->clientConnection); } -/// Initializes the client connection and addresses; does nothing -/// if already initialized. void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) { @@ -309,11 +305,7 @@ ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) clientConnection_ = conn; - if (request) - return; // addresses should have already initialized from the request - - src_addr = clientConnection_->remote; - my_addr = clientConnection_->local; + setClientSideAddresses(); } void diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index aa0ac44dbd2..64bc5f415d6 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -50,28 +50,28 @@ class ACLFilledChecklist: public ACLChecklist /// Configures client-related fields from the passed client connection manager. /// Has no effect if the client connection manager field is already initialized. /// This method should be used in contexts where HttpRequest may be unavailable. - void clientConnectionManager(ConnStateData *); + void setClientConnectionManager(ConnStateData *); /// Configures client-related fields from the passed client connection. /// Has no effect if the fields are already initialized. /// This method should be used in contexts where HttpRequest and /// connection manager may be unavailable. - void clientConnection(Comm::ConnectionPointer); + void setClientConnection(Comm::ConnectionPointer); #if FOLLOW_X_FORWARDED_FOR /// Configures srcAddr() to always return available indirect client address /// instead of direct client address. - void forceIndirectAddr() { srcAddrRestrictions_ = forceIndirect; } -#endif /* FOLLOW_X_FORWARDED_FOR */ + void forceIndirectAddr(); +#endif /// Configures srcAddr() to always return direct client address - void forceDirectAddr() { srcAddrRestrictions_ = forceDirect; } + void forceDirectAddr(); /// the associated client connection manager or nil ConnStateData *clientConnectionManager() const; /// remote/source address of a client-to-Squid connection, direct or indirect - const Ip::Address &srcAddr() const; + const Ip::Address &srcAddr() const { return src_addr; } /// local/destination address of a client-to-Squid connection const Ip::Address &myAddr() const { return my_addr; } @@ -128,9 +128,7 @@ class ACLFilledChecklist: public ACLChecklist err_type requestErrorType; private: - void setClientConnectionManager(ConnStateData *); - void setClientConnection(Comm::ConnectionPointer); - + void setClientSideAddresses(); /// a client connection manager, if any ConnStateData *connectionManager_; /// a client connection, if any @@ -142,16 +140,6 @@ class ACLFilledChecklist: public ACLChecklist Ip::Address src_addr; Ip::Address my_addr; - typedef enum { - noRestrictions, -#if FOLLOW_X_FORWARDED_FOR - forceIndirect, ///< will use indirect client address instead of direct address -#endif /* FOLLOW_X_FORWARDED_FOR */ - forceDirect ///< will use direct client address instead of indirect address (if configured) - } SrcAddrRestrictions; - - /// forces using either direct or indirect client address - SrcAddrRestrictions srcAddrRestrictions_; /// not implemented; will cause link failures if used ACLFilledChecklist(const ACLFilledChecklist &); /// not implemented; will cause link failures if used diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index 2545026fa8c..9155bcadb8a 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1477,7 +1477,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) if (TheConfig.use_indirect_client) client_addr = request->indirectClientAddr(); else -#endif /* FOLLOW_X_FORWARDED_FOR */ +#endif client_addr = request->clientAddr(); if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) buf.appendf("X-Client-IP: %s\r\n", client_addr.toStr(ntoabuf,MAX_IPSTRLEN)); diff --git a/src/client_side.cc b/src/client_side.cc index e9d04130b3b..cbfec54582b 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -437,7 +437,6 @@ ClientHttpRequest::logRequest() } ACLFilledChecklist checklist(NULL, request, NULL); - checklist.clientConnectionManager(getConn()); if (al->reply) { checklist.reply = al->reply; @@ -451,13 +450,14 @@ ClientHttpRequest::logRequest() } // no need checklist.syncAle(): already synced checklist.al = al; + checklist.setClientConnectionManager(getConn()); accessLogLog(al, &checklist); bool updatePerformanceCounters = true; if (Config.accessList.stats_collection) { ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, NULL); - statsCheck.clientConnectionManager(getConn()); statsCheck.al = al; + statsCheck.setClientConnectionManager(getConn()); if (al->reply) { statsCheck.reply = al->reply; HTTPMSGLOCK(statsCheck.reply); @@ -1516,8 +1516,8 @@ bool ConnStateData::serveDelayedError(Http::Stream *context) bool allowDomainMismatch = false; if (Config.ssl_client.cert_error) { ACLFilledChecklist check(Config.ssl_client.cert_error, request, dash_str); - check.clientConnectionManager(this); check.al = http->al; + check.setClientConnectionManager(this); check.sslErrors = new Security::CertErrors(Security::CertError(SQUID_X509_V_ERR_DOMAIN_MISMATCH, srvCert)); check.syncAle(request, http->log_uri); allowDomainMismatch = check.fastCheck().allowed(); @@ -1564,7 +1564,7 @@ clientTunnelOnError(ConnStateData *conn, Http::StreamPointer &context, HttpReque ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request.getRaw(), nullptr); checklist.al = (context && context->http) ? context->http->al : nullptr; checklist.requestErrorType = requestError; - checklist.clientConnectionManager(conn); + checklist.setClientConnectionManager(conn); ClientHttpRequest *http = context ? context->http : nullptr; const char *log_uri = http ? http->log_uri : nullptr; checklist.syncAle(request.getRaw(), log_uri); @@ -1810,7 +1810,7 @@ ConnStateData::proxyProtocolValidateClient() return proxyProtocolError("PROXY client not permitted by default ACL"); ACLFilledChecklist ch(Config.accessList.proxyProtocol, NULL, clientConnection->rfc931); - ch.clientConnectionManager(this); + ch.setClientConnectionManager(this); if (!ch.fastCheck().allowed()) return proxyProtocolError("PROXY client not permitted by ACLs"); @@ -2253,7 +2253,7 @@ ConnStateData::whenClientIpKnown() #if USE_IDENT if (Ident::TheConfig.identLookup) { ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, NULL, NULL); - identChecklist.clientConnectionManager(this); + identChecklist.setClientConnectionManager(this); if (identChecklist.fastCheck().allowed()) Ident::Start(clientConnection, clientIdentDone, this); } @@ -2270,7 +2270,7 @@ ConnStateData::whenClientIpKnown() const auto &pools = ClientDelayPools::Instance()->pools; if (pools.size()) { ACLFilledChecklist ch(NULL, NULL, NULL); - ch.clientConnectionManager(this); + ch.setClientConnectionManager(this); // TODO: we check early to limit error response bandwith but we // should recheck when we can honor delay_pool_uses_indirect @@ -2616,7 +2616,7 @@ ConnStateData::postHttpsAccept() request->url.port(clientConnection->local.port()); ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL); - acl_checklist->clientConnectionManager(this); + acl_checklist->setClientConnectionManager(this); // Build a local AccessLogEntry to allow requiresAle() acls work acl_checklist->al = new AccessLogEntry; acl_checklist->al->cache.start_time = current_time; @@ -2704,7 +2704,7 @@ void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &cer ACLFilledChecklist checklist(NULL, sslServerBump->request.getRaw(), clientConnection != NULL ? clientConnection->rfc931 : dash_str); - checklist.clientConnectionManager(this); + checklist.setClientConnectionManager(this); checklist.sslErrors = cbdataReference(sslServerBump->sslErrors()); for (sslproxy_cert_adapt *ca = Config.ssl_client.cert_adapt; ca != NULL; ca = ca->next) { @@ -3091,8 +3091,8 @@ ConnStateData::startPeekAndSplice() // Run a accessList check to check if want to splice or continue bumping ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, sslServerBump->request.getRaw(), nullptr); - acl_checklist->clientConnectionManager(this); acl_checklist->al = http ? http->al : nullptr; + acl_checklist->setClientConnectionManager(this); //acl_checklist->src_addr = params.conn->remote; //acl_checklist->my_addr = s->s; acl_checklist->banAction(allow_t(ACCESS_ALLOWED, Ssl::bumpNone)); @@ -3548,7 +3548,7 @@ clientAclChecklistFill(ACLFilledChecklist &checklist, ClientHttpRequest *http) // then call setIdent() inside checklist.setRequest(). Otherwise, restore // USE_IDENT lost in commit 94439e4. ConnStateData * conn = http->getConn(); - checklist.clientConnectionManager(conn); + checklist.setClientConnectionManager(conn); const char *ident = (cbdataReferenceValid(conn) && conn && conn->clientConnection) ? conn->clientConnection->rfc931 : dash_str; diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 26796c3a155..237f858e0b8 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1790,8 +1790,8 @@ ClientHttpRequest::doCallouts() // Set appropriate MARKs and CONNMARKs if needed. if (getConn() && Comm::IsConnOpen(getConn()->clientConnection)) { ACLFilledChecklist ch(nullptr, request, nullptr); - ch.clientConnectionManager(getConn()); ch.al = calloutContext->http->al; + ch.setClientConnectionManager(getConn()); ch.syncAle(request, log_uri); if (!calloutContext->toClientMarkingDone) { diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index 49e5ab025e2..431ac6f4676 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -263,7 +263,7 @@ logAcceptError(const Comm::ConnectionPointer &conn) al->url = "error:accept-client-connection"; al->setVirginUrlForMissingRequest(al->url); ACLFilledChecklist ch(nullptr, nullptr, nullptr); - ch.clientConnection(conn); + ch.setClientConnection(conn); ch.al = al; accessLogLog(al, &ch); } diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index dd38807e6ed..cbf39bc8333 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1543,8 +1543,8 @@ Ftp::Server::handleUploadRequest(String &, String &) ClientHttpRequest *http = pipeline.front()->http; HttpRequest *request = http->request; ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, NULL); - bodyContinuationCheck.clientConnectionManager(this); bodyContinuationCheck.al = http->al; + bodyContinuationCheck.setClientConnectionManager(this); bodyContinuationCheck.syncAle(request, http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { request->forcedBodyContinuation = true; diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index bbe62bbc305..a13f7f9eda8 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -256,8 +256,8 @@ Http::One::Server::processParsedRequest(Http::StreamPointer &context) if (Config.accessList.forceRequestBodyContinuation) { ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), NULL); - bodyContinuationCheck.clientConnectionManager(this); bodyContinuationCheck.al = http->al; + bodyContinuationCheck.setClientConnectionManager(this); bodyContinuationCheck.syncAle(request.getRaw(), http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { debugs(33, 5, "Body Continuation forced"); From f177621c6a55f2dfa564b16169c74f0cc1426702 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 23 Apr 2019 20:22:32 +0300 Subject: [PATCH 27/66] Refactoring and polishing * Refactored two public setClientConnectionManager() and setClientConnection() methods into a single public method. This simplification should eliminate possible doubts about proper method selection. * Removed unnecessary #endif comments, if the above block is rather small. --- src/HttpRequest.h | 6 +++--- src/acl/FilledChecklist.cc | 15 ++++++++++----- src/acl/FilledChecklist.h | 16 ++++++---------- src/client_side.cc | 22 +++++++++++----------- src/client_side_request.cc | 2 +- src/comm/TcpAcceptor.cc | 2 +- src/servers/FtpServer.cc | 2 +- src/servers/Http1Server.cc | 2 +- src/tests/stub_HttpRequest.cc | 2 +- 9 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 35186605701..18f335b78a7 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -166,7 +166,7 @@ class HttpRequest: public Http::Message void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } /// force using direct client address void ignoreIndirectClientAddr(); -#endif /* FOLLOW_X_FORWARDED_FOR */ +#endif HierarchyLogEntry hier; @@ -198,7 +198,7 @@ class HttpRequest: public Http::Message #if FOLLOW_X_FORWARDED_FOR String x_forwarded_for_iterator; /* XXX a list of IP addresses */ -#endif /* FOLLOW_X_FORWARDED_FOR */ +#endif /// A strong etag of the cached entry. Used for refreshing that entry. String etag; @@ -269,7 +269,7 @@ class HttpRequest: public Http::Message Ip::Address my_addr; ///< local address which a non-TCP (e.g., ICMP) client connects to #if FOLLOW_X_FORWARDED_FOR Ip::Address indirect_client_addr; ///< calculated client address, after applying X-Forwarded-For rules -#endif /* FOLLOW_X_FORWARDED_FOR */ +#endif /// whether this request was initiated by Squid itself bool internal; diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 24f2d09accb..52a207a4be4 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -252,7 +252,7 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) if (httpRequest) { request = httpRequest; HTTPMSGLOCK(request); - setClientConnectionManager(request->clientConnectionManager().get()); + setClientConnectionDetails(request->clientConnectionManager().get()); if (!clientConnectionManager()) // could not take the connection from the connection manager setClientConnection(request->clientConnection()); } @@ -281,17 +281,22 @@ ACLFilledChecklist::setClientSideAddresses() } void -ACLFilledChecklist::setClientConnectionManager(ConnStateData *aConn) +ACLFilledChecklist::setClientConnectionDetails(ConnStateData *aConn, Comm::ConnectionPointer conn) { - if (!(aConn && cbdataReferenceValid(aConn))) + if (clientConnectionManager()) return; - if (!clientConnectionManager()) + if (aConn && cbdataReferenceValid(aConn)) { connectionManager_ = cbdataReference(aConn); + setClientConnection(clientConnectionManager()->clientConnection); + return; + } - setClientConnection(clientConnectionManager()->clientConnection); + setClientConnection(conn); } +/// Configures client-related fields from the passed client connection. +/// Has no effect if the fields are already initialized. void ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) { diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 64bc5f415d6..a87f3323ac7 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -47,16 +47,11 @@ class ACLFilledChecklist: public ACLChecklist /// configure rfc931 user identity for the first time void setIdent(const char *userIdentity); - /// Configures client-related fields from the passed client connection manager. - /// Has no effect if the client connection manager field is already initialized. - /// This method should be used in contexts where HttpRequest may be unavailable. - void setClientConnectionManager(ConnStateData *); - - /// Configures client-related fields from the passed client connection. - /// Has no effect if the fields are already initialized. - /// This method should be used in contexts where HttpRequest and - /// connection manager may be unavailable. - void setClientConnection(Comm::ConnectionPointer); + /// Configures client-related fields from the passed client connection manager + /// or client connection. The second parameter is used only if the first one + /// is nil or invalid. Has no effect if the client connection manager field + /// has been already initialized. + void setClientConnectionDetails(ConnStateData *, Comm::ConnectionPointer conn = nullptr); #if FOLLOW_X_FORWARDED_FOR /// Configures srcAddr() to always return available indirect client address @@ -128,6 +123,7 @@ class ACLFilledChecklist: public ACLChecklist err_type requestErrorType; private: + void setClientConnection(Comm::ConnectionPointer); void setClientSideAddresses(); /// a client connection manager, if any ConnStateData *connectionManager_; diff --git a/src/client_side.cc b/src/client_side.cc index cbfec54582b..f4daf829303 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -450,14 +450,14 @@ ClientHttpRequest::logRequest() } // no need checklist.syncAle(): already synced checklist.al = al; - checklist.setClientConnectionManager(getConn()); + checklist.setClientConnectionDetails(getConn()); accessLogLog(al, &checklist); bool updatePerformanceCounters = true; if (Config.accessList.stats_collection) { ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, NULL); statsCheck.al = al; - statsCheck.setClientConnectionManager(getConn()); + statsCheck.setClientConnectionDetails(getConn()); if (al->reply) { statsCheck.reply = al->reply; HTTPMSGLOCK(statsCheck.reply); @@ -1517,7 +1517,7 @@ bool ConnStateData::serveDelayedError(Http::Stream *context) if (Config.ssl_client.cert_error) { ACLFilledChecklist check(Config.ssl_client.cert_error, request, dash_str); check.al = http->al; - check.setClientConnectionManager(this); + check.setClientConnectionDetails(this); check.sslErrors = new Security::CertErrors(Security::CertError(SQUID_X509_V_ERR_DOMAIN_MISMATCH, srvCert)); check.syncAle(request, http->log_uri); allowDomainMismatch = check.fastCheck().allowed(); @@ -1564,7 +1564,7 @@ clientTunnelOnError(ConnStateData *conn, Http::StreamPointer &context, HttpReque ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request.getRaw(), nullptr); checklist.al = (context && context->http) ? context->http->al : nullptr; checklist.requestErrorType = requestError; - checklist.setClientConnectionManager(conn); + checklist.setClientConnectionDetails(conn); ClientHttpRequest *http = context ? context->http : nullptr; const char *log_uri = http ? http->log_uri : nullptr; checklist.syncAle(request.getRaw(), log_uri); @@ -1810,7 +1810,7 @@ ConnStateData::proxyProtocolValidateClient() return proxyProtocolError("PROXY client not permitted by default ACL"); ACLFilledChecklist ch(Config.accessList.proxyProtocol, NULL, clientConnection->rfc931); - ch.setClientConnectionManager(this); + ch.setClientConnectionDetails(this); if (!ch.fastCheck().allowed()) return proxyProtocolError("PROXY client not permitted by ACLs"); @@ -2253,7 +2253,7 @@ ConnStateData::whenClientIpKnown() #if USE_IDENT if (Ident::TheConfig.identLookup) { ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, NULL, NULL); - identChecklist.setClientConnectionManager(this); + identChecklist.setClientConnectionDetails(this); if (identChecklist.fastCheck().allowed()) Ident::Start(clientConnection, clientIdentDone, this); } @@ -2270,7 +2270,7 @@ ConnStateData::whenClientIpKnown() const auto &pools = ClientDelayPools::Instance()->pools; if (pools.size()) { ACLFilledChecklist ch(NULL, NULL, NULL); - ch.setClientConnectionManager(this); + ch.setClientConnectionDetails(this); // TODO: we check early to limit error response bandwith but we // should recheck when we can honor delay_pool_uses_indirect @@ -2616,7 +2616,7 @@ ConnStateData::postHttpsAccept() request->url.port(clientConnection->local.port()); ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL); - acl_checklist->setClientConnectionManager(this); + acl_checklist->setClientConnectionDetails(this); // Build a local AccessLogEntry to allow requiresAle() acls work acl_checklist->al = new AccessLogEntry; acl_checklist->al->cache.start_time = current_time; @@ -2704,7 +2704,7 @@ void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &cer ACLFilledChecklist checklist(NULL, sslServerBump->request.getRaw(), clientConnection != NULL ? clientConnection->rfc931 : dash_str); - checklist.setClientConnectionManager(this); + checklist.setClientConnectionDetails(this); checklist.sslErrors = cbdataReference(sslServerBump->sslErrors()); for (sslproxy_cert_adapt *ca = Config.ssl_client.cert_adapt; ca != NULL; ca = ca->next) { @@ -3092,7 +3092,7 @@ ConnStateData::startPeekAndSplice() ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, sslServerBump->request.getRaw(), nullptr); acl_checklist->al = http ? http->al : nullptr; - acl_checklist->setClientConnectionManager(this); + acl_checklist->setClientConnectionDetails(this); //acl_checklist->src_addr = params.conn->remote; //acl_checklist->my_addr = s->s; acl_checklist->banAction(allow_t(ACCESS_ALLOWED, Ssl::bumpNone)); @@ -3548,7 +3548,7 @@ clientAclChecklistFill(ACLFilledChecklist &checklist, ClientHttpRequest *http) // then call setIdent() inside checklist.setRequest(). Otherwise, restore // USE_IDENT lost in commit 94439e4. ConnStateData * conn = http->getConn(); - checklist.setClientConnectionManager(conn); + checklist.setClientConnectionDetails(conn); const char *ident = (cbdataReferenceValid(conn) && conn && conn->clientConnection) ? conn->clientConnection->rfc931 : dash_str; diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 237f858e0b8..eb384507a3b 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1791,7 +1791,7 @@ ClientHttpRequest::doCallouts() if (getConn() && Comm::IsConnOpen(getConn()->clientConnection)) { ACLFilledChecklist ch(nullptr, request, nullptr); ch.al = calloutContext->http->al; - ch.setClientConnectionManager(getConn()); + ch.setClientConnectionDetails(getConn()); ch.syncAle(request, log_uri); if (!calloutContext->toClientMarkingDone) { diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index 431ac6f4676..941ebe48b46 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -263,7 +263,7 @@ logAcceptError(const Comm::ConnectionPointer &conn) al->url = "error:accept-client-connection"; al->setVirginUrlForMissingRequest(al->url); ACLFilledChecklist ch(nullptr, nullptr, nullptr); - ch.setClientConnection(conn); + ch.setClientConnectionDetails(nullptr, conn); ch.al = al; accessLogLog(al, &ch); } diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index cbf39bc8333..fa09a2f849d 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1544,7 +1544,7 @@ Ftp::Server::handleUploadRequest(String &, String &) HttpRequest *request = http->request; ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, NULL); bodyContinuationCheck.al = http->al; - bodyContinuationCheck.setClientConnectionManager(this); + bodyContinuationCheck.setClientConnectionDetails(this); bodyContinuationCheck.syncAle(request, http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { request->forcedBodyContinuation = true; diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index a13f7f9eda8..24b6d5e8303 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -257,7 +257,7 @@ Http::One::Server::processParsedRequest(Http::StreamPointer &context) if (Config.accessList.forceRequestBodyContinuation) { ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), NULL); bodyContinuationCheck.al = http->al; - bodyContinuationCheck.setClientConnectionManager(this); + bodyContinuationCheck.setClientConnectionDetails(this); bodyContinuationCheck.syncAle(request.getRaw(), http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { debugs(33, 5, "Body Continuation forced"); diff --git a/src/tests/stub_HttpRequest.cc b/src/tests/stub_HttpRequest.cc index 41658906e02..1a3274adce2 100644 --- a/src/tests/stub_HttpRequest.cc +++ b/src/tests/stub_HttpRequest.cc @@ -59,7 +59,7 @@ void HttpRequest::hdrCacheInit() STUB bool HttpRequest::inheritProperties(const Http::Message *) STUB_RETVAL(false) #if FOLLOW_X_FORWARDED_FOR const Ip::Address& HttpRequest::indirectClientAddr() const STUB_RETREF(Ip::Address) -#endif /* FOLLOW_X_FORWARDED_FOR */ +#endif const Ip::Address& HttpRequest::clientAddr() const STUB_RETREF(Ip::Address) const Ip::Address& HttpRequest::myAddr() const STUB_RETREF(Ip::Address) Comm::ConnectionPointer HttpRequest::clientConnection() const STUB From 568a40251b2fed9b6fc9eb14b350d1e4d0615c1f Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Wed, 24 Apr 2019 15:52:56 +0300 Subject: [PATCH 28/66] Polishing Polished comments and optimized excessive clientConnectionManager() calls. --- src/acl/AtStep.cc | 11 +++++------ src/acl/FilledChecklist.cc | 17 ++++++++++------- src/acl/FilledChecklist.h | 9 ++++----- src/acl/MyPortName.cc | 6 ++++-- src/acl/ServerCertificate.cc | 8 +++++--- src/acl/ServerName.cc | 2 +- src/auth/Acl.cc | 3 ++- src/auth/AclProxyAuth.cc | 9 ++++----- src/ident/AclIdent.cc | 17 ++++++++++------- 9 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/acl/AtStep.cc b/src/acl/AtStep.cc index 33a3cdf8953..ad7a8cb269d 100644 --- a/src/acl/AtStep.cc +++ b/src/acl/AtStep.cc @@ -20,12 +20,11 @@ int ACLAtStepStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { - Ssl::ServerBump *bump = NULL; - if (checklist->clientConnectionManager() && (bump = checklist->clientConnectionManager()->serverBump())) - return data->match(bump->step); - else - return data->match(Ssl::bumpStep1); - return 0; + if (const auto mgr = checklist->clientConnectionManager()) { + if (const auto bump = mgr->serverBump()) + return data->match(bump->step); + } + return data->match(Ssl::bumpStep1); } #endif /* USE_OPENSSL */ diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 52a207a4be4..2237a2a8790 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -85,9 +85,11 @@ ACLFilledChecklist::verifyAle() const // fill the old external_acl_type codes are set if any // data on them exists in the Checklist - if (!al->cache.port && clientConnectionManager()) { - showDebugWarning("listening port"); - al->cache.port = clientConnectionManager()->port; + if (!al->cache.port) { + if (const auto mgr = clientConnectionManager()) { + showDebugWarning("listening port"); + al->cache.port = mgr->port; + } } if (request) { @@ -281,14 +283,15 @@ ACLFilledChecklist::setClientSideAddresses() } void -ACLFilledChecklist::setClientConnectionDetails(ConnStateData *aConn, Comm::ConnectionPointer conn) +ACLFilledChecklist::setClientConnectionDetails(ConnStateData *mgr, Comm::ConnectionPointer conn) { if (clientConnectionManager()) return; - if (aConn && cbdataReferenceValid(aConn)) { - connectionManager_ = cbdataReference(aConn); - setClientConnection(clientConnectionManager()->clientConnection); + if (mgr && cbdataReferenceValid(mgr)) { + connectionManager_ = cbdataReference(mgr); + Must(!conn || conn == mgr->clientConnection); + setClientConnection(mgr->clientConnection); return; } diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index a87f3323ac7..59e1d12d1ea 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -47,10 +47,9 @@ class ACLFilledChecklist: public ACLChecklist /// configure rfc931 user identity for the first time void setIdent(const char *userIdentity); - /// Configures client-related fields from the passed client connection manager - /// or client connection. The second parameter is used only if the first one - /// is nil or invalid. Has no effect if the client connection manager field - /// has been already initialized. + /// Configure client connection-related information. Each and both parameters + /// can be nil (or equivalent). Specifying mgr->clientConnection as the second + /// parameter is useless. void setClientConnectionDetails(ConnStateData *, Comm::ConnectionPointer conn = nullptr); #if FOLLOW_X_FORWARDED_FOR @@ -62,7 +61,7 @@ class ACLFilledChecklist: public ACLChecklist /// Configures srcAddr() to always return direct client address void forceDirectAddr(); - /// the associated client connection manager or nil + /// a valid client connection manager or nil ConnStateData *clientConnectionManager() const; /// remote/source address of a client-to-Squid connection, direct or indirect diff --git a/src/acl/MyPortName.cc b/src/acl/MyPortName.cc index 6d75730fccb..a54a8318a2c 100644 --- a/src/acl/MyPortName.cc +++ b/src/acl/MyPortName.cc @@ -18,8 +18,10 @@ int ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { - if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->port) - return data->match(checklist->clientConnectionManager()->port->name); + if (const auto mgr = checklist->clientConnectionManager()) { + if (const auto port = mgr->port) + return data->match(port->name); + } return 0; } diff --git a/src/acl/ServerCertificate.cc b/src/acl/ServerCertificate.cc index 516ca478fdf..845955239af 100644 --- a/src/acl/ServerCertificate.cc +++ b/src/acl/ServerCertificate.cc @@ -22,10 +22,12 @@ int ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { Security::CertPointer cert; - if (checklist->serverCert) + if (checklist->serverCert) { cert = checklist->serverCert; - else if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->serverBump()) - cert = checklist->clientConnectionManager()->serverBump()->serverCert; + } else if (const auto mgr = checklist->clientConnectionManager()) { + if (mgr->serverBump()) + cert = mgr->serverBump()->serverCert; + } if (!cert) return 0; diff --git a/src/acl/ServerName.cc b/src/acl/ServerName.cc index d8d9a205af3..8aeae4755bf 100644 --- a/src/acl/ServerName.cc +++ b/src/acl/ServerName.cc @@ -92,7 +92,7 @@ ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *ch const char *serverName = nullptr; SBuf clientSniKeeper; // because c_str() is not constant - if (ConnStateData *conn = checklist->clientConnectionManager()) { + if (const auto conn = checklist->clientConnectionManager()) { const char *clientRequestedServerName = nullptr; clientSniKeeper = conn->tlsClientSni(); if (clientSniKeeper.isEmpty()) { diff --git a/src/auth/Acl.cc b/src/auth/Acl.cc index e65a5b3b4fc..6369650a03e 100644 --- a/src/auth/Acl.cc +++ b/src/auth/Acl.cc @@ -36,7 +36,8 @@ AuthenticateAcl(ACLChecklist *ch) return ACCESS_DENIED; } else if (request->flags.sslBumped) { debugs(28, 5, "SslBumped request: It is an encapsulated request do not authenticate"); - checklist->auth_user_request = checklist->clientConnectionManager() ? checklist->clientConnectionManager()->getAuth() : request->auth_user_request; + const auto mgr = checklist->clientConnectionManager(); + checklist->auth_user_request = mgr ? mgr->getAuth() : request->auth_user_request; if (checklist->auth_user_request != NULL) return ACCESS_ALLOWED; else diff --git a/src/auth/AclProxyAuth.cc b/src/auth/AclProxyAuth.cc index 50c7da9914a..71fe588cf1c 100644 --- a/src/auth/AclProxyAuth.cc +++ b/src/auth/AclProxyAuth.cc @@ -140,16 +140,15 @@ void ProxyAuthLookup::LookupDone(void *data) { ACLFilledChecklist *checklist = Filled(static_cast(data)); - - if (!checklist->auth_user_request || !checklist->auth_user_request->valid() || !checklist->clientConnectionManager()) { + const auto mgr = checklist->clientConnectionManager(); + if (!checklist->auth_user_request || !checklist->auth_user_request->valid() || !mgr) { /* credentials could not be checked either way * restart the whole process */ /* OR the connection was closed, there's no way to continue */ checklist->auth_user_request = NULL; - if (checklist->clientConnectionManager()) { - checklist->clientConnectionManager()->setAuth(nullptr, "proxy_auth ACL failure"); - } + if (mgr) + mgr->setAuth(nullptr, "proxy_auth ACL failure"); } checklist->resumeNonBlockingCheck(ProxyAuthLookup::Instance()); diff --git a/src/ident/AclIdent.cc b/src/ident/AclIdent.cc index 54e037622c2..6ff68b5ff20 100644 --- a/src/ident/AclIdent.cc +++ b/src/ident/AclIdent.cc @@ -67,11 +67,13 @@ int ACLIdent::match(ACLChecklist *cl) { ACLFilledChecklist *checklist = Filled(cl); - if (checklist->rfc931[0]) { + if (checklist->rfc931[0]) return data->match(checklist->rfc931); - } else if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->clientConnection && checklist->clientConnectionManager()->clientConnection->rfc931[0]) { - return data->match(checklist->clientConnectionManager()->clientConnection->rfc931); - } else if (checklist->clientConnectionManager() && Comm::IsConnOpen(checklist->clientConnectionManager()->clientConnection)) { + + const auto mgr = checklist->clientConnectionManager(); + if (mgr && mgr->clientConnection && mgr->clientConnection->rfc931[0]) { + return data->match(mgr->clientConnection->rfc931); + } else if (mgr && Comm::IsConnOpen(mgr->clientConnection)) { if (checklist->goAsync(IdentLookup::Instance())) { debugs(28, 3, "switching to ident lookup state"); return -1; @@ -120,7 +122,7 @@ IdentLookup::checkForAsync(ACLChecklist *cl)const // check that ACLIdent::match() tested this lookup precondition assert(conn && Comm::IsConnOpen(conn->clientConnection)); debugs(28, 3, HERE << "Doing ident lookup" ); - Ident::Start(checklist->clientConnectionManager()->clientConnection, LookupDone, checklist); + Ident::Start(conn->clientConnection, LookupDone, checklist); } void @@ -138,8 +140,9 @@ IdentLookup::LookupDone(const char *ident, void *data) * Cache the ident result in the connection, to avoid redoing ident lookup * over and over on persistent connections */ - if (checklist->clientConnectionManager() && checklist->clientConnectionManager()->clientConnection && !checklist->clientConnectionManager()->clientConnection->rfc931[0]) - xstrncpy(checklist->clientConnectionManager()->clientConnection->rfc931, checklist->rfc931, USER_IDENT_SZ); + const auto mgr = checklist->clientConnectionManager(); + if (mgr && mgr->clientConnection && !mgr->clientConnection->rfc931[0]) + xstrncpy(mgr->clientConnection->rfc931, checklist->rfc931, USER_IDENT_SZ); checklist->resumeNonBlockingCheck(IdentLookup::Instance()); } From 7e8819cb9118bc61bf74149f6db8c4659b362ecc Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 25 Apr 2019 15:34:31 +0300 Subject: [PATCH 29/66] Distinguish received 'internal' and self-generated requests. Currently HttpRequest::flags::internal is used for marking received requests having 'squid-internal-' path prefix. On the other hand, the recently added HttpRequest::internal flag marks requests generated by Squid itself, such as Downloader requests. To avoid confusion I renamed both flags to reflect their real nature and fixed with the (renamed) 'selfInitiated' flag several contexts (netdb, peer_digest and asn), where it was missing. Also removed the obsolete isNoAddr() condition for 'miss_access' check in FwdState. This should be probably done at 2e8c280 (bug 924 fix). Also fixed 'miss_access' condition inconsistency in FwdState and tunnel code (since 2e8c280). --- src/FwdState.cc | 11 ++--------- src/HttpRequest.cc | 26 ++++++++++++++++---------- src/HttpRequest.h | 9 ++++++--- src/RequestFlags.h | 4 ++-- src/acl/Asn.cc | 1 + src/client_side.cc | 8 ++++---- src/client_side_reply.cc | 6 +++--- src/client_side_request.cc | 4 ++-- src/client_side_request.h | 4 ++-- src/icmp/net_db.cc | 2 ++ src/peer_digest.cc | 2 ++ src/tunnel.cc | 8 +------- 12 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/FwdState.cc b/src/FwdState.cc index cee55046856..73530ec0dc2 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -309,14 +309,7 @@ FwdState::~FwdState() void FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, HttpRequest *request, const AccessLogEntryPointer &al) { - /** \note - * client_addr == no_addr indicates this is an "internal" request - * from peer_digest.c, asn.c, netdb.c, etc and should always - * be allowed. yuck, I know. - */ - - if ( Config.accessList.miss && !request->clientAddr().isNoAddr() && - !request->flags.internal && request->url.getScheme() != AnyP::PROTO_CACHE_OBJECT) { + if (Config.accessList.miss && request->needCheckMissAccess()) { // Check if this host is allowed to fetch MISSES from us (miss_access). ACLFilledChecklist ch(Config.accessList.miss, request, NULL); // TODO: Explain this acl_uses_indirect_client violation in squid.conf. @@ -355,7 +348,7 @@ FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, Ht return; } - if (request->flags.internal) { + if (request->flags.internalReceived) { debugs(17, 2, "calling internalStart() due to request flag"); internalStart(clientConn, request, entry); return; diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 5e85ec5d98f..162c23a1499 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -115,7 +115,7 @@ HttpRequest::init() #endif rangeOffsetLimit = -2; //a value of -2 means not checked yet forcedBodyContinuation = false; - internal = false; + selfInitiated_ = false; if (clientConnectionManager().valid()) { if (const auto port = clientConnectionManager()->port) { @@ -257,7 +257,7 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) sources = aReq->sources; - internal = aReq->internal; + selfInitiated_ = aReq->selfInitiated_; return true; } @@ -719,22 +719,22 @@ HttpRequest::prepareForDownloader(Downloader *aDownloader) header.putStr(Http::HdrType::HOST, url.host()); header.putTime(Http::HdrType::DATE, squid_curtime); downloader = aDownloader; - makeInternal(); + selfInitiated(); } void -HttpRequest::makeInternal() +HttpRequest::selfInitiated() { /* Internally created requests cannot have bodies today */ content_length = 0; http_ver = Http::ProtocolVersion(); - internal = true; + selfInitiated_ = true; } CbcPointer & HttpRequest::clientConnectionManager() { - if (!internal) + if (!selfInitiated_) return masterXaction->clientConnectionManager(); static CbcPointer noManager; return noManager; @@ -752,7 +752,7 @@ NoAddr() const Ip::Address& HttpRequest::clientAddr() const { - if (internal) + if (selfInitiated_) return NoAddr(); if (clientConnection()) return clientConnection()->remote; @@ -769,7 +769,7 @@ HttpRequest::prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const const Ip::Address& HttpRequest::myAddr() const { - return internal ? NoAddr(): + return selfInitiated_ ? NoAddr(): masterXaction->clientConnection() ? masterXaction->clientConnection()->local : my_addr; } @@ -778,7 +778,7 @@ HttpRequest::myAddr() const const Ip::Address& HttpRequest::indirectClientAddr() const { - if (internal) + if (selfInitiated_) return NoAddr(); if (!indirect_client_addr.isEmpty()) return indirect_client_addr; @@ -814,6 +814,12 @@ HttpRequest::setInterceptionFlags(const AccessLogEntryPointer &al) } } +bool +HttpRequest::needCheckMissAccess() const +{ + return !(flags.internalReceived || url.getScheme() == AnyP::PROTO_CACHE_OBJECT); +} + char * HttpRequest::canonicalCleanUrl() const { @@ -872,7 +878,7 @@ FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry Comm::ConnectionPointer HttpRequest::clientConnection() const { - if (!internal) + if (!selfInitiated_) return masterXaction->clientConnection(); static Comm::ConnectionPointer noConnection; return noConnection; diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 18f335b78a7..16c5128e54c 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -97,6 +97,9 @@ class HttpRequest: public Http::Message /// sets TPROXY-related flags void setInterceptionFlags(const AccessLogEntryPointer &al); + /// whether this request is a subject of 'miss_access' check + bool needCheckMissAccess() const; + protected: void clean(); @@ -139,7 +142,7 @@ class HttpRequest: public Http::Message int imslen; /// this request was initiated by Squid (rather than received on a client connection) - void makeInternal(); + void selfInitiated(); /// supply Downloader-specific settings void prepareForDownloader(Downloader *); @@ -271,8 +274,8 @@ class HttpRequest: public Http::Message Ip::Address indirect_client_addr; ///< calculated client address, after applying X-Forwarded-For rules #endif - /// whether this request was initiated by Squid itself - bool internal; + /// whether this request was spawned by Squid itself + bool selfInitiated_; protected: virtual void packFirstLineInto(Packable * p, bool full_uri) const; diff --git a/src/RequestFlags.h b/src/RequestFlags.h index 6b984e36357..44e7f8b3233 100644 --- a/src/RequestFlags.h +++ b/src/RequestFlags.h @@ -70,8 +70,8 @@ class RequestFlags /// This applies to TPROXY traffic that has not had spoofing disabled through /// the spoof_client_ip squid.conf ACL. bool spoofClientIp = false; - /** set if the request is internal (\see ClientHttpRequest::flags.internal)*/ - bool internal = false; + /// set if the received request is internal (\see ClientHttpRequest::flags.internalReceived) + bool internalReceived = false; /** if set, request to try very hard to keep the connection alive */ bool mustKeepalive = false; /** set if the rquest wants connection oriented auth */ diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index ed4d4ac9c7d..6ad5d64e18d 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -241,6 +241,7 @@ asnCacheStart(int as) asState->request = new HttpRequest(mx); asState->request->url = whoisUrl; asState->request->method = Http::METHOD_GET; + asState->request->selfInitiated(); // XXX: performance regression, c_str() reallocates const auto asres = xstrdup(whoisUrl.absolute().c_str()); diff --git a/src/client_side.cc b/src/client_side.cc index f4daf829303..f3080cf6017 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1404,7 +1404,7 @@ parseHttpRequest(ConnStateData *csd, const Http1::RequestParserPointer &hp) http->uri = xstrdup(internalLocalUri(NULL, hp->requestUri())); // We just re-wrote the URL. Must replace the Host: header. // But have not parsed there yet!! flag for local-only handling. - http->flags.internal = true; + http->flags.internalReceived = true; } else if (csd->port->flags.accelSurrogate) { /* accelerator mode */ @@ -1641,19 +1641,19 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp, if (internalCheck(request->url.path())) { if (internalHostnameIs(request->url.host()) && request->url.port() == getMyPort()) { debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true)); - http->flags.internal = true; + http->flags.internalReceived = true; } else if (Config.onoff.global_internal_static && internalStaticCheck(request->url.path())) { debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true) << " (global_internal_static on)"); request->url.setScheme(AnyP::PROTO_HTTP, "http"); request->url.host(internalHostname()); request->url.port(getMyPort()); - http->flags.internal = true; + http->flags.internalReceived = true; http->setLogUriToRequestUri(); } else debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true) << " (not this proxy)"); } - request->flags.internal = http->flags.internal; + request->flags.internalReceived = http->flags.internalReceived; if (!isFtp) { // XXX: for non-HTTP messages instantiate a different Http::Message child type diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 04a77c73663..ef010fd1a7d 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -647,7 +647,7 @@ clientReplyContext::cacheHit(StoreIOBuffer result) http->logType.update(LOG_TCP_MISS); processMiss(); return; - } else if (!http->flags.internal && refreshCheckHTTP(e, r)) { + } else if (!http->flags.internalReceived && refreshCheckHTTP(e, r)) { debugs(88, 5, "clientCacheHit: in refreshCheck() block"); /* * We hold a stale copy; it needs to be validated @@ -874,7 +874,7 @@ clientReplyContext::blockedHit() const if (!Config.accessList.sendHit) return false; // hits are not blocked by default - if (http->flags.internal) + if (http->flags.internalReceived) return false; // internal content "hits" cannot be blocked if (const HttpReply *rep = http->storeEntry()->getReply()) { @@ -1682,7 +1682,7 @@ clientReplyContext::identifyStoreObject() // client sent CC:no-cache or some other condition has been // encountered which prevents delivering a public/cached object. - if (!r->flags.noCache || r->flags.internal) { + if (!r->flags.noCache || r->flags.internalReceived) { lookingforstore = 5; StoreEntry::getPublicByRequest (this, r); } else { diff --git a/src/client_side_request.cc b/src/client_side_request.cc index eb384507a3b..ac03bd59531 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -375,7 +375,7 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre * objects ? */ - request->makeInternal(); + request->selfInitiated(); http->initRequest(request); @@ -582,7 +582,7 @@ ClientRequestContext::hostHeaderVerify() return; } - if (http->request->flags.internal) { + if (http->request->flags.internalReceived) { // TODO: kill this when URL handling allows partial URLs out of accel mode // and we no longer screw with the URL just to add our internal host there debugs(85, 6, HERE << "validate skipped due to internal composite URL."); diff --git a/src/client_side_request.h b/src/client_side_request.h index 9f6652b8c60..5280f5850bb 100644 --- a/src/client_side_request.h +++ b/src/client_side_request.h @@ -124,10 +124,10 @@ class ClientHttpRequest AccessLogEntry::Pointer al; ///< access.log entry struct Flags { - Flags() : accel(false), internal(false), done_copying(false), purging(false) {} + Flags() : accel(false), internalReceived(false), done_copying(false), purging(false) {} bool accel; - bool internal; + bool internalReceived; bool done_copying; bool purging; } flags; diff --git a/src/icmp/net_db.cc b/src/icmp/net_db.cc index 69cecafc2ca..c948bdbad10 100644 --- a/src/icmp/net_db.cc +++ b/src/icmp/net_db.cc @@ -1282,6 +1282,8 @@ netdbExchangeStart(void *data) return; } + req->selfInitiated(); + netdbExchangeState *ex = new netdbExchangeState(p, req); ex->e = storeCreateEntry(uri, uri, RequestFlags(), Http::METHOD_GET); assert(NULL != ex->e); diff --git a/src/peer_digest.cc b/src/peer_digest.cc index a5383c2bd3a..cbd8c6b90ce 100644 --- a/src/peer_digest.cc +++ b/src/peer_digest.cc @@ -334,6 +334,8 @@ peerDigestRequest(PeerDigest * pd) /* add custom headers */ assert(!req->header.len); + req->selfInitiated(); + req->header.putStr(Http::HdrType::ACCEPT, StoreDigestMimeStr); req->header.putStr(Http::HdrType::ACCEPT, "text/html"); diff --git a/src/tunnel.cc b/src/tunnel.cc index 6f2819a15bc..729e94900ff 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1095,13 +1095,7 @@ tunnelStart(ClientHttpRequest * http) HttpRequest *request = http->request; char *url = http->uri; - /* - * client_addr.isNoAddr() indicates this is an "internal" request - * from peer_digest.c, asn.c, netdb.c, etc and should always - * be allowed. yuck, I know. - */ - - if (Config.accessList.miss && !request->clientAddr().isNoAddr()) { + if (Config.accessList.miss && request->needCheckMissAccess()) { /* * Check if this host is allowed to fetch MISSES from us (miss_access) * default is to allow. From 2391ffaf5d2891a5eb6672986ea739e422f455d9 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 25 Apr 2019 16:31:33 +0300 Subject: [PATCH 30/66] Renamed ACLFilledCheckList::srcAddr() "client*" name for both method and field is more consistent with HttpRequest names, used for its initialization. --- src/DelayId.cc | 2 +- src/acl/Arp.cc | 6 +++--- src/acl/Asn.cc | 2 +- src/acl/Eui64.cc | 10 +++++----- src/acl/FilledChecklist.cc | 20 ++++++++++---------- src/acl/FilledChecklist.h | 12 ++++++++---- src/acl/MaxConnection.cc | 2 +- src/acl/SourceDomain.cc | 6 +++--- src/acl/SourceIp.cc | 2 +- src/auth/Acl.cc | 2 +- src/auth/AclMaxUserIp.cc | 2 +- 11 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 558db8c8320..433cf0cd470 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -101,7 +101,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) DelayId result (pool + 1); CompositePoolNode::CompositeSelectionDetails details; - details.src_addr = ch.srcAddr(); + details.src_addr = ch.clientAddr(); #if USE_AUTH details.user = r->auth_user_request; #endif diff --git a/src/acl/Arp.cc b/src/acl/Arp.cc index 62ae067c761..ae57a1a15dd 100644 --- a/src/acl/Arp.cc +++ b/src/acl/Arp.cc @@ -115,13 +115,13 @@ ACLARP::match(ACLChecklist *cl) ACLFilledChecklist *checklist = Filled(cl); /* IPv6 does not do ARP */ - if (!checklist->srcAddr().isIPv4()) { - debugs(14, 3, "ACLARP::match: IPv4 Required for ARP Lookups. Skipping " << checklist->srcAddr() ); + if (!checklist->clientAddr().isIPv4()) { + debugs(14, 3, "ACLARP::match: IPv4 Required for ARP Lookups. Skipping " << checklist->clientAddr() ); return 0; } Eui::Eui48 lookingFor; - lookingFor.lookup(checklist->srcAddr()); + lookingFor.lookup(checklist->clientAddr()); return (aclArpData.find(lookingFor) != aclArpData.end()); } diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index 6ad5d64e18d..2c52278064e 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -587,7 +587,7 @@ template class ACLStrategised; int ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { - return data->match(checklist->srcAddr()); + return data->match(checklist->clientAddr()); } int diff --git a/src/acl/Eui64.cc b/src/acl/Eui64.cc index 6d283c90317..6c3a4cdf607 100644 --- a/src/acl/Eui64.cc +++ b/src/acl/Eui64.cc @@ -87,19 +87,19 @@ ACLEui64::match(ACLChecklist *cl) ACLFilledChecklist *checklist = Filled(cl); /* IPv4 does not do EUI-64 (yet) */ - if (!checklist->srcAddr().isIPv6()) { - debugs(14, 3, "ACLEui64::match: IPv6 Required for EUI-64 Lookups. Skipping " << checklist->srcAddr() ); + if (!checklist->clientAddr().isIPv6()) { + debugs(14, 3, "ACLEui64::match: IPv6 Required for EUI-64 Lookups. Skipping " << checklist->clientAddr() ); return 0; } Eui::Eui64 lookingFor; - if (lookingFor.lookup(checklist->srcAddr())) { + if (lookingFor.lookup(checklist->clientAddr())) { bool found = (eui64Data.find(lookingFor) != eui64Data.end()); - debugs(28, 3, checklist->srcAddr() << "' " << (found ? "found" : "NOT found")); + debugs(28, 3, checklist->clientAddr() << "' " << (found ? "found" : "NOT found")); return found; } - debugs(28, 3, checklist->srcAddr() << " NOT found"); + debugs(28, 3, checklist->clientAddr() << " NOT found"); return 0; } diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 2237a2a8790..d635f6a7d3e 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -43,7 +43,7 @@ ACLFilledChecklist::ACLFilledChecklist() : sourceDomainChecked_(false) { my_addr.setEmpty(); - src_addr.setEmpty(); + client_addr.setEmpty(); dst_addr.setEmpty(); rfc931[0] = '\0'; } @@ -153,7 +153,7 @@ void ACLFilledChecklist::forceIndirectAddr() { assert(request); - src_addr = request->indirectClientAddr(); + client_addr = request->indirectClientAddr(); } #endif @@ -161,7 +161,7 @@ void ACLFilledChecklist::forceDirectAddr() { assert(request); - src_addr = request->clientAddr(); + client_addr = request->clientAddr(); } int @@ -239,7 +239,7 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re sourceDomainChecked_(false) { my_addr.setEmpty(); - src_addr.setEmpty(); + client_addr.setEmpty(); dst_addr.setEmpty(); rfc931[0] = '\0'; @@ -267,17 +267,17 @@ ACLFilledChecklist::setClientSideAddresses() if (request) { #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.acl_uses_indirect_client) { - assert(src_addr != request->indirectClientAddr()); - src_addr = request->indirectClientAddr(); + assert(client_addr != request->indirectClientAddr()); + client_addr = request->indirectClientAddr(); } else #endif { - assert(src_addr != request->clientAddr()); - src_addr = request->clientAddr(); + assert(client_addr != request->clientAddr()); + client_addr = request->clientAddr(); } my_addr = request->myAddr(); } else if (clientConnection_) { - src_addr = clientConnection_->remote; + client_addr = clientConnection_->remote; my_addr = clientConnection_->local; } } @@ -320,7 +320,7 @@ void ACLFilledChecklist::snmpDetails(char *snmpCommunity, const Ip::Address &fromAddr, const Ip::Address &localAddr) { snmp_community = snmpCommunity; - src_addr = fromAddr; + client_addr = fromAddr; my_addr = localAddr; } diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 59e1d12d1ea..5b5d1475bb0 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -53,19 +53,19 @@ class ACLFilledChecklist: public ACLChecklist void setClientConnectionDetails(ConnStateData *, Comm::ConnectionPointer conn = nullptr); #if FOLLOW_X_FORWARDED_FOR - /// Configures srcAddr() to always return available indirect client address + /// Configures clientAddr() to always return available indirect client address /// instead of direct client address. void forceIndirectAddr(); #endif - /// Configures srcAddr() to always return direct client address + /// Configures clientAddr() to always return direct client address void forceDirectAddr(); /// a valid client connection manager or nil ConnStateData *clientConnectionManager() const; /// remote/source address of a client-to-Squid connection, direct or indirect - const Ip::Address &srcAddr() const { return src_addr; } + const Ip::Address &clientAddr() const { return client_addr; } /// local/destination address of a client-to-Squid connection const Ip::Address &myAddr() const { return my_addr; } @@ -132,7 +132,11 @@ class ACLFilledChecklist: public ACLChecklist int fd_; /**< may be available when conn_ is not */ bool destinationDomainChecked_; bool sourceDomainChecked_; - Ip::Address src_addr; + /// The client source address, which is either source address of the client-to-Squid TCP + /// connection (direct address) or a Forwarded-For address (indirect address), determined + /// by Squid configuration. The checklist may be configured to force either direct or indirect + /// client address usage, overwriting the default configuration. + Ip::Address client_addr; Ip::Address my_addr; /// not implemented; will cause link failures if used diff --git a/src/acl/MaxConnection.cc b/src/acl/MaxConnection.cc index fbeae3d2e6c..7e46a7a87ce 100644 --- a/src/acl/MaxConnection.cc +++ b/src/acl/MaxConnection.cc @@ -75,7 +75,7 @@ ACLMaxConnection::parse() int ACLMaxConnection::match(ACLChecklist *checklist) { - return clientdbEstablished(Filled(checklist)->srcAddr(), 0) > limit ? 1 : 0; + return clientdbEstablished(Filled(checklist)->clientAddr(), 0) > limit ? 1 : 0; } SBufList diff --git a/src/acl/SourceDomain.cc b/src/acl/SourceDomain.cc index 498f2fa3426..4dcd69385ff 100644 --- a/src/acl/SourceDomain.cc +++ b/src/acl/SourceDomain.cc @@ -28,7 +28,7 @@ SourceDomainLookup::Instance() void SourceDomainLookup::checkForAsync(ACLChecklist *checklist) const { - fqdncache_nbgethostbyaddr(Filled(checklist)->srcAddr(), LookupDone, checklist); + fqdncache_nbgethostbyaddr(Filled(checklist)->clientAddr(), LookupDone, checklist); } void @@ -44,13 +44,13 @@ int ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { const char *fqdn = NULL; - fqdn = fqdncache_gethostbyaddr(checklist->srcAddr(), FQDN_LOOKUP_IF_MISS); + fqdn = fqdncache_gethostbyaddr(checklist->clientAddr(), FQDN_LOOKUP_IF_MISS); if (fqdn) { return data->match(fqdn); } else if (!checklist->sourceDomainChecked()) { /* FIXME: Using AclMatchedName here is not OO correct. Should find a way to the current acl */ - debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << checklist->srcAddr() << "'"); + debugs(28, 3, "aclMatchAcl: Can't yet compare '" << AclMatchedName << "' ACL for '" << checklist->clientAddr() << "'"); if (checklist->goAsync(SourceDomainLookup::Instance())) return -1; // else fall through to "none" match, hiding the lookup failure (XXX) diff --git a/src/acl/SourceIp.cc b/src/acl/SourceIp.cc index 16facc54d75..8a574e1d966 100644 --- a/src/acl/SourceIp.cc +++ b/src/acl/SourceIp.cc @@ -21,7 +21,7 @@ ACLSourceIP::typeString() const int ACLSourceIP::match(ACLChecklist *checklist) { - return ACLIP::match(Filled(checklist)->srcAddr()); + return ACLIP::match(Filled(checklist)->clientAddr()); } ACL * diff --git a/src/auth/Acl.cc b/src/auth/Acl.cc index 6369650a03e..41e99c73b7b 100644 --- a/src/auth/Acl.cc +++ b/src/auth/Acl.cc @@ -57,7 +57,7 @@ AuthenticateAcl(ACLChecklist *ch) /* Note: this fills in auth_user_request when applicable */ const AuthAclState result = Auth::UserRequest::tryToAuthenticateAndSetAuthUser( &checklist->auth_user_request, headertype, request, - checklist->clientConnectionManager(), checklist->srcAddr(), checklist->al); + checklist->clientConnectionManager(), checklist->clientAddr(), checklist->al); switch (result) { case AUTH_ACL_CANNOT_AUTHENTICATE: diff --git a/src/auth/AclMaxUserIp.cc b/src/auth/AclMaxUserIp.cc index b9f92e9cd7b..1390c394177 100644 --- a/src/auth/AclMaxUserIp.cc +++ b/src/auth/AclMaxUserIp.cc @@ -129,7 +129,7 @@ ACLMaxUserIP::match(ACLChecklist *cl) switch (answer) { case ACCESS_ALLOWED: // check for a match - ti = match(checklist->auth_user_request, checklist->srcAddr()); + ti = match(checklist->auth_user_request, checklist->clientAddr()); checklist->auth_user_request = NULL; return ti; From fb296495cda38e6217512ad0366591590737d591 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 25 Apr 2019 17:05:43 +0300 Subject: [PATCH 31/66] Use Musts checks on client_addr/my_addr initialization this make it consistent with clientConnection initialization. --- src/acl/FilledChecklist.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index d635f6a7d3e..cff7197c11d 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -260,25 +260,29 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) } } +static void +InitializeAddress(Ip::Address &addr, const Ip::Address &value) +{ + Must(addr.isEmpty() || addr == value); + if (addr.isEmpty()) + addr = value; +} + /// configures addresses of the client-to-Squid connection void ACLFilledChecklist::setClientSideAddresses() { if (request) { #if FOLLOW_X_FORWARDED_FOR - if (Config.onoff.acl_uses_indirect_client) { - assert(client_addr != request->indirectClientAddr()); - client_addr = request->indirectClientAddr(); - } else + if (Config.onoff.acl_uses_indirect_client) + InitializeAddress(client_addr, request->indirectClientAddr()); + else #endif - { - assert(client_addr != request->clientAddr()); - client_addr = request->clientAddr(); - } - my_addr = request->myAddr(); + InitializeAddress(client_addr, request->clientAddr()); + InitializeAddress(my_addr, request->myAddr()); } else if (clientConnection_) { - client_addr = clientConnection_->remote; - my_addr = clientConnection_->local; + InitializeAddress(client_addr, clientConnection_->remote); + InitializeAddress(my_addr, clientConnection_->local); } } From c3ad73a8b81d1a4b8be04792f61bafaa328b2d10 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sat, 27 Apr 2019 20:51:31 +0300 Subject: [PATCH 32/66] Use new HttpRequest::isSelfInitiated() API ... instead of the low level client_addr::isNoAddr() check. --- src/AccessLogEntry.cc | 1 + src/DelayId.cc | 4 ++-- src/HttpRequest.h | 1 + src/adaptation/ecap/XactionRep.cc | 4 ++-- src/adaptation/icap/ModXact.cc | 4 ++-- src/http.cc | 4 ++-- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index 2fdb80a0436..b99cc3c5155 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -31,6 +31,7 @@ AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const // internally generated requests (and some ICAP) lack client IP if (log_ip.isNoAddr()) { + Must(!request || request->isSelfInitiated()); strncpy(buf, "-", bufsz); return; } diff --git a/src/DelayId.cc b/src/DelayId.cc index 433cf0cd470..ef94861debc 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -71,8 +71,8 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) assert(http); r = http->request; - if (r->clientAddr().isNoAddr()) { - debugs(77, 2, "delayClient: WARNING: Called with 'NO_ADDR' address, ignoring"); + if (r->isSelfInitiated()) { + debugs(77, 2, "ignoring self-initiated requests"); return DelayId(); } diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 16c5128e54c..8e822a6aa7e 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -143,6 +143,7 @@ class HttpRequest: public Http::Message /// this request was initiated by Squid (rather than received on a client connection) void selfInitiated(); + bool isSelfInitiated() const { return selfInitiated_; } /// supply Downloader-specific settings void prepareForDownloader(Downloader *); diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index 3194eba9bff..460237c84bf 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -127,7 +127,7 @@ Adaptation::Ecap::XactionRep::clientIpValue() const Must(request); // TODO: move this logic into HttpRequest::clientIp(bool) and // HttpRequest::clientIpString(bool) and reuse everywhere - if (TheConfig.send_client_ip && request) { + if (TheConfig.send_client_ip && request && !request->isSelfInitiated()) { Ip::Address client_addr; #if FOLLOW_X_FORWARDED_FOR if (TheConfig.use_indirect_client) @@ -135,7 +135,7 @@ Adaptation::Ecap::XactionRep::clientIpValue() const else #endif client_addr = request->clientAddr(); - if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) { + if (!client_addr.isAnyAddr()) { char ntoabuf[MAX_IPSTRLEN] = ""; client_addr.toStr(ntoabuf,MAX_IPSTRLEN); return libecap::Area::FromTempBuffer(ntoabuf, strlen(ntoabuf)); diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index 9155bcadb8a..439696e62d1 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1471,7 +1471,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) makeAllowHeader(buf); - if (TheConfig.send_client_ip && request) { + if (TheConfig.send_client_ip && request && !request->isSelfInitiated()) { Ip::Address client_addr; #if FOLLOW_X_FORWARDED_FOR if (TheConfig.use_indirect_client) @@ -1479,7 +1479,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) else #endif client_addr = request->clientAddr(); - if (!client_addr.isAnyAddr() && !client_addr.isNoAddr()) + if (!client_addr.isAnyAddr()) buf.appendf("X-Client-IP: %s\r\n", client_addr.toStr(ntoabuf,MAX_IPSTRLEN)); } diff --git a/src/http.cc b/src/http.cc index 2dbde983f5c..24e3fd720a3 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1833,7 +1833,7 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, if (strcmp(opt_forwarded_for, "on") == 0) { /** If set to ON - append client IP or 'unknown'. */ - if ( request->clientAddr().isNoAddr() ) + if (request->isSelfInitiated()) strListAdd(&strFwd, "unknown", ','); else strListAdd(&strFwd, request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN), ','); @@ -1844,7 +1844,7 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, /** If set to TRANSPARENT - pass through unchanged. */ } else if (strcmp(opt_forwarded_for, "truncate") == 0) { /** If set to TRUNCATE - drop existing list and replace with client IP or 'unknown'. */ - if ( request->clientAddr().isNoAddr() ) + if (request->isSelfInitiated() ) strFwd = "unknown"; else strFwd = request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN); From a1b057bbbff125ecde3fb1835e9094bcf718bb74 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sun, 28 Apr 2019 12:27:12 +0300 Subject: [PATCH 33/66] Restored the selfInitiaded() (the former isNoAddr()) check for miss_access, incorrectly removed at 7e8819. In that revision I missed the fact that Downloader/ESI requests go through fwdStart() as well. --- src/HttpRequest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 162c23a1499..018e3f1fa3e 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -817,7 +817,7 @@ HttpRequest::setInterceptionFlags(const AccessLogEntryPointer &al) bool HttpRequest::needCheckMissAccess() const { - return !(flags.internalReceived || url.getScheme() == AnyP::PROTO_CACHE_OBJECT); + return !(flags.internalReceived || url.getScheme() == AnyP::PROTO_CACHE_OBJECT || isSelfInitiated()); } char * From deeade5d1f6f57993f28fa34160562838a4ea49e Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sun, 19 May 2019 17:39:17 +0300 Subject: [PATCH 34/66] Self-initiated request should log '-' with '%>p', instead of '0' --- src/HttpRequest.h | 4 +++- src/format/Format.cc | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 8e822a6aa7e..e31097e21ff 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -141,8 +141,10 @@ class HttpRequest: public Http::Message int imslen; - /// this request was initiated by Squid (rather than received on a client connection) + /// mark this request as initiated by Squid (rather than received on a client connection) void selfInitiated(); + + /// whether this request was initiated by Squid (rather than received on a client connection) bool isSelfInitiated() const { return selfInitiated_; } /// supply Downloader-specific settings diff --git a/src/format/Format.cc b/src/format/Format.cc index f92a5b8b968..33856ec7825 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -410,8 +410,10 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_CLIENT_PORT: if (al->request) { - outint = al->request->clientAddr().port(); - doint = 1; + if (!al->request->isSelfInitiated()) { + outint = al->request->clientAddr().port(); + doint = 1; + } } else if (al->tcpClient) { outint = al->tcpClient->remote.port(); doint = 1; From 355856269790513a8495661994bc76823299c45f Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Wed, 22 May 2019 15:48:43 +0300 Subject: [PATCH 35/66] Log any zero '%>p' as '-' At deeade5 this was done only for 'self-initiated' requests. However, since there is probably no special meaning in '0' client port (showing that the port is just uninitialized), it natural to log '-' in all other zero cases also. To make this work, I reworked HttpRequest so that self-initialized requests returned empty client addresses instead of making them 'no-addr' by means of Address::setNoAddr(). The 'no-addr' approach looks to be outdated, lacks any advantage and uselessly complicates the interface. --- src/AccessLogEntry.cc | 3 +-- src/DelayId.cc | 4 ++-- src/HttpRequest.cc | 26 ++++++++++---------------- src/adaptation/ecap/XactionRep.cc | 4 ++-- src/adaptation/icap/ModXact.cc | 4 ++-- src/format/Format.cc | 4 ++-- src/http.cc | 4 ++-- 7 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index b99cc3c5155..482a6179b74 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -30,8 +30,7 @@ AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const log_ip = cache.caddr; // internally generated requests (and some ICAP) lack client IP - if (log_ip.isNoAddr()) { - Must(!request || request->isSelfInitiated()); + if (log_ip.isEmpty()) { strncpy(buf, "-", bufsz); return; } diff --git a/src/DelayId.cc b/src/DelayId.cc index ef94861debc..37309bbce6d 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -71,8 +71,8 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) assert(http); r = http->request; - if (r->isSelfInitiated()) { - debugs(77, 2, "ignoring self-initiated requests"); + if (r->clientAddr().isEmpty()) { + debugs(77, 2, "called with an empty address, ignoring"); return DelayId(); } diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 018e3f1fa3e..9b28e897167 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -741,22 +741,18 @@ HttpRequest::clientConnectionManager() } static const Ip::Address& -NoAddr() +EmptyAddr() { static Ip::Address addr; - if (!addr.isNoAddr()) - addr.setNoAddr(); return addr; } const Ip::Address& HttpRequest::clientAddr() const { - if (selfInitiated_) - return NoAddr(); - if (clientConnection()) - return clientConnection()->remote; - return client_addr; + if (!selfInitiated_) + return clientConnection() ? clientConnection()->remote : client_addr; + return EmptyAddr(); } void @@ -769,20 +765,18 @@ HttpRequest::prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const const Ip::Address& HttpRequest::myAddr() const { - return selfInitiated_ ? NoAddr(): - masterXaction->clientConnection() ? - masterXaction->clientConnection()->local : my_addr; + if (!selfInitiated_) + return masterXaction->clientConnection() ? masterXaction->clientConnection()->local : my_addr; + return EmptyAddr(); } #if FOLLOW_X_FORWARDED_FOR const Ip::Address& HttpRequest::indirectClientAddr() const { - if (selfInitiated_) - return NoAddr(); - if (!indirect_client_addr.isEmpty()) - return indirect_client_addr; - return clientAddr(); + if (!selfInitiated_) + return indirect_client_addr.isEmpty() ? clientAddr() : indirect_client_addr; + return EmptyAddr(); } void diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index 460237c84bf..66983ca89b7 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -127,7 +127,7 @@ Adaptation::Ecap::XactionRep::clientIpValue() const Must(request); // TODO: move this logic into HttpRequest::clientIp(bool) and // HttpRequest::clientIpString(bool) and reuse everywhere - if (TheConfig.send_client_ip && request && !request->isSelfInitiated()) { + if (TheConfig.send_client_ip && request) { Ip::Address client_addr; #if FOLLOW_X_FORWARDED_FOR if (TheConfig.use_indirect_client) @@ -135,7 +135,7 @@ Adaptation::Ecap::XactionRep::clientIpValue() const else #endif client_addr = request->clientAddr(); - if (!client_addr.isAnyAddr()) { + if (!client_addr.isAnyAddr() && !client_addr.isEmpty()) { char ntoabuf[MAX_IPSTRLEN] = ""; client_addr.toStr(ntoabuf,MAX_IPSTRLEN); return libecap::Area::FromTempBuffer(ntoabuf, strlen(ntoabuf)); diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index 439696e62d1..ec738ce8c23 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1471,7 +1471,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) makeAllowHeader(buf); - if (TheConfig.send_client_ip && request && !request->isSelfInitiated()) { + if (TheConfig.send_client_ip && request) { Ip::Address client_addr; #if FOLLOW_X_FORWARDED_FOR if (TheConfig.use_indirect_client) @@ -1479,7 +1479,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) else #endif client_addr = request->clientAddr(); - if (!client_addr.isAnyAddr()) + if (!client_addr.isAnyAddr() && !client_addr.isEmpty()) buf.appendf("X-Client-IP: %s\r\n", client_addr.toStr(ntoabuf,MAX_IPSTRLEN)); } diff --git a/src/format/Format.cc b/src/format/Format.cc index 33856ec7825..cf0ec50c043 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -410,8 +410,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_CLIENT_PORT: if (al->request) { - if (!al->request->isSelfInitiated()) { - outint = al->request->clientAddr().port(); + if (const auto port = al->request->clientAddr().port()) { + outint = port; doint = 1; } } else if (al->tcpClient) { diff --git a/src/http.cc b/src/http.cc index 24e3fd720a3..a15ead3405f 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1833,7 +1833,7 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, if (strcmp(opt_forwarded_for, "on") == 0) { /** If set to ON - append client IP or 'unknown'. */ - if (request->isSelfInitiated()) + if (request->clientAddr().isEmpty()) strListAdd(&strFwd, "unknown", ','); else strListAdd(&strFwd, request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN), ','); @@ -1844,7 +1844,7 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, /** If set to TRANSPARENT - pass through unchanged. */ } else if (strcmp(opt_forwarded_for, "truncate") == 0) { /** If set to TRUNCATE - drop existing list and replace with client IP or 'unknown'. */ - if (request->isSelfInitiated() ) + if (request->clientAddr().isEmpty() ) strFwd = "unknown"; else strFwd = request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN); From a3315b844683f3004a7ab15cec41c4efdb6c3833 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sun, 26 May 2019 00:11:12 +0300 Subject: [PATCH 36/66] Fixing no-addr/empty-addr inconsistencies After 3558562 several HttpRequest methods return 'empty-addr' instead of 'no-addr'. However, this change alone proved to be insufficient, leaving the code in an inconsistent state, because some callers of these methods still kept checking for 'no-addr'. After examining different contexts with 'empty-addr', 'no-addr' and 'any-addr', I came to a conclusion that many of these contexts checked only one of these values (ignoring others), and a few of them even misuse these 'special' addresses. For example, the address availability was determined only by !isAnyAddr() check, forgetting two other possible 'empty-addr' on 'no-addr' values. The solution I selected is that we need to reduce (or even eliminate) the usage of these 'low-level' address methods, namely isEmpty(), isNoAddr() and isAnyAddr() in favor of two new 'higher-level' ones isKnown() and isBindable(). Though many different contexts were affected, there are several 'common' changes among these contexts: * !isAnyAddr(), meaning an address other from 'any-addr' became isKnown(). * !isNoAddr(), meaning an address usable for bind() became isBindable(). * isNoAddr(), meaning am 'unknown address' became !isKnown(). Also: * Fixed getMyHostname(), removing misplaced sa.isAnyAddr(). Before this fix, reverse DNS lookups were always performed, violating the logic and the comment in this method. * Fixed wccp_router directive to accept no_addr, instead of aborting. * Reduced code duplication, moving the duplicated code into dedicated ClientHttpRequest::clientAddrOnError() and Address::adjustSplitStackIPv6(). --- src/AccessLogEntry.cc | 2 +- src/AccessLogEntry.h | 1 - src/DelayId.cc | 4 ++-- src/FwdState.cc | 3 ++- src/HttpRequest.cc | 4 ++-- src/acl/Asn.cc | 5 +--- src/acl/FilledChecklist.cc | 17 +++++++------- src/adaptation/ecap/XactionRep.cc | 2 +- src/adaptation/icap/ModXact.cc | 2 +- src/anyp/Uri.cc | 2 +- src/auth/digest/UserRequest.cc | 7 ------ src/cache_cf.cc | 6 ++--- src/client_side_reply.cc | 38 ++++++++----------------------- src/client_side_reply.h | 2 +- src/client_side_request.cc | 20 ++++++++++------ src/client_side_request.h | 3 +++ src/comm.cc | 2 +- src/dns_internal.cc | 6 ++--- src/esi/Esi.cc | 2 +- src/format/Format.cc | 2 +- src/fqdncache.cc | 3 +-- src/ftp/Parsing.cc | 4 ++-- src/htcp.cc | 13 ++++------- src/http.cc | 4 ++-- src/icmp/net_db.cc | 4 ++-- src/icp_v2.cc | 13 ++++------- src/internal.cc | 3 +-- src/ip/Address.cc | 25 ++++++++++++++++++++ src/ip/Address.h | 17 +++++++++++--- src/log/FormatSquidIcap.cc | 2 +- src/pconn.cc | 2 +- src/peer_select.cc | 12 +++++----- src/redirect.cc | 5 +--- src/servers/FtpServer.cc | 6 ++--- src/snmp_core.cc | 18 ++++----------- src/tools.cc | 4 ++-- src/wccp.cc | 4 ++-- src/wccp2.cc | 4 ++-- 38 files changed, 135 insertions(+), 138 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index 482a6179b74..25bce4bee1c 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -30,7 +30,7 @@ AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const log_ip = cache.caddr; // internally generated requests (and some ICAP) lack client IP - if (log_ip.isEmpty()) { + if (!log_ip.isKnown()) { strncpy(buf, "-", bufsz); return; } diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index a33450bf5e0..9625aebd062 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -130,7 +130,6 @@ class AccessLogEntry: public RefCountable { public: CacheDetails() { - caddr.setNoAddr(); memset(&start_time, 0, sizeof(start_time)); memset(&trTime, 0, sizeof(start_time)); } diff --git a/src/DelayId.cc b/src/DelayId.cc index 37309bbce6d..85292448d99 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -71,8 +71,8 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) assert(http); r = http->request; - if (r->clientAddr().isEmpty()) { - debugs(77, 2, "called with an empty address, ignoring"); + if (!r->clientAddr().isKnown()) { + debugs(77, 2, "called with unknown address, ignoring"); return DelayId(); } diff --git a/src/FwdState.cc b/src/FwdState.cc index 73530ec0dc2..1c4ea0bff76 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -1339,7 +1339,8 @@ void getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) { // skip if an outgoing address is already set. - if (!conn->local.isAnyAddr()) return; + if (conn->local.isKnown()) + return; // ensure that at minimum the wildcard local matches remote protocol if (conn->remote.isIPv4()) diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 9b28e897167..d022f96a984 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -775,7 +775,7 @@ const Ip::Address& HttpRequest::indirectClientAddr() const { if (!selfInitiated_) - return indirect_client_addr.isEmpty() ? clientAddr() : indirect_client_addr; + return indirect_client_addr.isKnown() ? indirect_client_addr : clientAddr(); return EmptyAddr(); } @@ -825,7 +825,7 @@ static const Ip::Address * FindListeningPortAddressInAddress(const Ip::Address *ip) { // FindListeningPortAddress() callers do not want INADDR_ANY addresses - return (ip && !ip->isAnyAddr()) ? ip : nullptr; + return (ip && ip->isKnown()) ? ip : nullptr; } /// a helper for handling PortCfg cases of FindListeningPortAddress() diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index 2c52278064e..4010842ba94 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -143,10 +143,7 @@ asnMatchIp(CbDataList *data, Ip::Address &addr) if (AS_tree_head == NULL) return 0; - if (addr.isNoAddr()) - return 0; - - if (addr.isAnyAddr()) + if (!addr.isKnown()) return 0; m_addr.addr = addr; diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index cff7197c11d..6a4d9e5b6f6 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -261,10 +261,11 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) } static void -InitializeAddress(Ip::Address &addr, const Ip::Address &value) +InitializeClientAddress(Ip::Address &addr, const Ip::Address &value) { - Must(addr.isEmpty() || addr == value); - if (addr.isEmpty()) + //Must(addr.isKnown() || addr == value); + assert(!addr.isKnown() || addr == value); + if (!addr.isKnown()) addr = value; } @@ -275,14 +276,14 @@ ACLFilledChecklist::setClientSideAddresses() if (request) { #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.acl_uses_indirect_client) - InitializeAddress(client_addr, request->indirectClientAddr()); + InitializeClientAddress(client_addr, request->indirectClientAddr()); else #endif - InitializeAddress(client_addr, request->clientAddr()); - InitializeAddress(my_addr, request->myAddr()); + InitializeClientAddress(client_addr, request->clientAddr()); + InitializeClientAddress(my_addr, request->myAddr()); } else if (clientConnection_) { - InitializeAddress(client_addr, clientConnection_->remote); - InitializeAddress(my_addr, clientConnection_->local); + InitializeClientAddress(client_addr, clientConnection_->remote); + InitializeClientAddress(my_addr, clientConnection_->local); } } diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index 66983ca89b7..0a4e088667b 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -135,7 +135,7 @@ Adaptation::Ecap::XactionRep::clientIpValue() const else #endif client_addr = request->clientAddr(); - if (!client_addr.isAnyAddr() && !client_addr.isEmpty()) { + if (client_addr.isKnown()) { char ntoabuf[MAX_IPSTRLEN] = ""; client_addr.toStr(ntoabuf,MAX_IPSTRLEN); return libecap::Area::FromTempBuffer(ntoabuf, strlen(ntoabuf)); diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index ec738ce8c23..45fa604986a 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1479,7 +1479,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) else #endif client_addr = request->clientAddr(); - if (!client_addr.isAnyAddr() && !client_addr.isEmpty()) + if (client_addr.isKnown()) buf.appendf("X-Client-IP: %s\r\n", client_addr.toStr(ntoabuf,MAX_IPSTRLEN)); } diff --git a/src/anyp/Uri.cc b/src/anyp/Uri.cc index c6d68369892..f0948b0b877 100644 --- a/src/anyp/Uri.cc +++ b/src/anyp/Uri.cc @@ -48,7 +48,7 @@ AnyP::Uri::host(const char *src) { hostAddr_.setEmpty(); hostAddr_ = src; - if (hostAddr_.isAnyAddr()) { + if (!hostAddr_.isKnown()) { xstrncpy(host_, src, sizeof(host_)); hostIsNumeric_ = false; } else { diff --git a/src/auth/digest/UserRequest.cc b/src/auth/digest/UserRequest.cc index b11aa34a466..7b472395036 100644 --- a/src/auth/digest/UserRequest.cc +++ b/src/auth/digest/UserRequest.cc @@ -148,13 +148,6 @@ Auth::Digest::UserRequest::authenticate(HttpRequest * request, ConnStateData *, const char *useragent = request->header.getStr(Http::HdrType::USER_AGENT); static Ip::Address last_broken_addr; - static int seen_broken_client = 0; - - if (!seen_broken_client) { - last_broken_addr.setNoAddr(); - seen_broken_client = 1; - } - if (last_broken_addr != request->clientAddr()) { debugs(29, DBG_IMPORTANT, "Digest POST bug detected from " << request->clientAddr() << " using '" << diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 208e4e251ec..f00d5061922 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1456,7 +1456,7 @@ dump_acl_address(StoreEntry * entry, const char *name, Acl::Address * head) char buf[MAX_IPSTRLEN]; for (Acl::Address *l = head; l; l = l->next) { - if (!l->addr.isAnyAddr()) + if (l->addr.isKnown()) storeAppendPrintf(entry, "%s %s", name, l->addr.toStr(buf,MAX_IPSTRLEN)); else storeAppendPrintf(entry, "%s autoselect", name); @@ -3833,10 +3833,10 @@ parsePortCfg(AnyP::PortCfgPointer *head, const char *optionName) } // *_port line should now be fully valid so we can clone it if necessary - if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && s->s.isAnyAddr()) { + if (s->s.needAdjustingSplitStackIPv6()) { // clone the port options from *s to *(s->next) s->next = s->clone(); - s->next->s.setIPv4(); + s->next->s.adjustSplitStackIPv6(); debugs(3, 3, AnyP::UriScheme(s->transport.protocol).image() << "_port: clone wildcard address for split-stack: " << s->s << " and " << s->next->s); } diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index ef010fd1a7d..b9c8c7fce6a 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -53,7 +53,7 @@ CBDATA_CLASS_INIT(clientReplyContext); /* Local functions */ extern "C" CSS clientReplyStatus; -ErrorState *clientBuildError(err_type, Http::StatusCode, char const *, Ip::Address &, HttpRequest *); +ErrorState *clientBuildError(err_type, Http::StatusCode, char const *, const Ip::Address &, HttpRequest *); /* privates */ @@ -103,7 +103,7 @@ clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) : void clientReplyContext::setReplyToError( err_type err, Http::StatusCode status, const HttpRequestMethod& method, char const *uri, - Ip::Address &addr, HttpRequest * failedrequest, const char *unparsedrequest, + const Ip::Address &addr, HttpRequest *failedrequest, const char *unparsedrequest, #if USE_AUTH Auth::UserRequest::Pointer auth_user_request #else @@ -765,9 +765,7 @@ clientReplyContext::processMiss() /// Deny loops if (r->flags.loopDetected) { http->al->http.code = Http::scForbidden; - Ip::Address tmp_noaddr; - tmp_noaddr.setNoAddr(); - err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, nullptr, conn ? conn->remote : tmp_noaddr, http->request); + err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, nullptr, http->clientAddrOnError(), http->request); createStoreEntry(r->method, RequestFlags()); errorAppendEntry(http->storeEntry(), err); triggerInitialStoreRead(); @@ -805,11 +803,8 @@ clientReplyContext::processOnlyIfCachedMiss() { debugs(88, 4, http->request->method << ' ' << http->uri); http->al->http.code = Http::scGatewayTimeout; - Ip::Address tmp_noaddr; - tmp_noaddr.setNoAddr(); ErrorState *err = clientBuildError(ERR_ONLY_IF_CACHED_MISS, Http::scGatewayTimeout, NULL, - http->getConn() ? http->getConn()->clientConnection->remote : tmp_noaddr, - http->request); + http->clientAddrOnError(), http->request); removeClientStoreReference(&sc, http); startError(err); } @@ -982,11 +977,8 @@ clientReplyContext::purgeFoundObject(StoreEntry *entry) if (EBIT_TEST(entry->flags, ENTRY_SPECIAL)) { http->logType.update(LOG_TCP_DENIED); - Ip::Address tmp_noaddr; - tmp_noaddr.setNoAddr(); // TODO: make a global const ErrorState *err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, NULL, - http->getConn() ? http->getConn()->clientConnection->remote : tmp_noaddr, - http->request); + http->clientAddrOnError(), http->request); startError(err); return; // XXX: leaking unused entry if some store does not keep it } @@ -1023,10 +1015,8 @@ clientReplyContext::purgeRequest() if (!Config2.onoff.enable_purge) { http->logType.update(LOG_TCP_DENIED); - Ip::Address tmp_noaddr; - tmp_noaddr.setNoAddr(); ErrorState *err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, NULL, - http->getConn() ? http->getConn()->clientConnection->remote : tmp_noaddr, http->request); + http->clientAddrOnError(), http->request); startError(err); return; } @@ -1960,12 +1950,9 @@ clientReplyContext::next() const void clientReplyContext::sendBodyTooLargeError() { - Ip::Address tmp_noaddr; - tmp_noaddr.setNoAddr(); // TODO: make a global const http->logType.update(LOG_TCP_DENIED_REPLY); ErrorState *err = clientBuildError(ERR_TOO_BIG, Http::scForbidden, NULL, - http->getConn() != NULL ? http->getConn()->clientConnection->remote : tmp_noaddr, - http->request); + http->clientAddrOnError(), http->request); removeClientStoreReference(&(sc), http); HTTPMSGUNLOCK(reply); startError(err); @@ -1977,11 +1964,9 @@ void clientReplyContext::sendPreconditionFailedError() { http->logType.update(LOG_TCP_HIT); - Ip::Address tmp_noaddr; - tmp_noaddr.setNoAddr(); ErrorState *const err = clientBuildError(ERR_PRECONDITION_FAILED, Http::scPreconditionFailed, - NULL, http->getConn() ? http->getConn()->clientConnection->remote : tmp_noaddr, http->request); + NULL, http->clientAddrOnError(), http->request); removeClientStoreReference(&sc, http); HTTPMSGUNLOCK(reply); startError(err); @@ -2090,11 +2075,8 @@ clientReplyContext::processReplyAccessResult(const allow_t &accessAllowed) if (page_id == ERR_NONE) page_id = ERR_ACCESS_DENIED; - Ip::Address tmp_noaddr; - tmp_noaddr.setNoAddr(); err = clientBuildError(page_id, Http::scForbidden, NULL, - http->getConn() != NULL ? http->getConn()->clientConnection->remote : tmp_noaddr, - http->request); + http->clientAddrOnError(), http->request); removeClientStoreReference(&sc, http); @@ -2337,7 +2319,7 @@ clientReplyContext::createStoreEntry(const HttpRequestMethod& m, RequestFlags re ErrorState * clientBuildError(err_type page_id, Http::StatusCode status, char const *url, - Ip::Address &src_addr, HttpRequest * request) + const Ip::Address &src_addr, HttpRequest *request) { ErrorState *err = new ErrorState(page_id, status, request); err->src_addr = src_addr; diff --git a/src/client_side_reply.h b/src/client_side_reply.h index 761adbace79..b7f2d88cf39 100644 --- a/src/client_side_reply.h +++ b/src/client_side_reply.h @@ -50,7 +50,7 @@ class clientReplyContext : public RefCountable, public StoreClient /// replaces current response store entry with the given one void setReplyToStoreEntry(StoreEntry *e, const char *reason); /// builds error using clientBuildError() and calls setReplyToError() below - void setReplyToError(err_type, Http::StatusCode, const HttpRequestMethod&, char const *, Ip::Address &, HttpRequest *, const char *, + void setReplyToError(err_type, Http::StatusCode, const HttpRequestMethod&, char const *, const Ip::Address &, HttpRequest *, const char *, #if USE_AUTH Auth::UserRequest::Pointer); #else diff --git a/src/client_side_request.cc b/src/client_side_request.cc index ac03bd59531..3a57352e6c8 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -84,7 +84,7 @@ static const char *const crlf = "\r\n"; static void clientFollowXForwardedForCheck(allow_t answer, void *data); #endif /* FOLLOW_X_FORWARDED_FOR */ -ErrorState *clientBuildError(err_type, Http::StatusCode, char const *url, Ip::Address &, HttpRequest *); +ErrorState *clientBuildError(err_type, Http::StatusCode, char const *url, const Ip::Address &, HttpRequest *); CBDATA_CLASS_INIT(ClientRequestContext); @@ -787,11 +787,9 @@ ClientRequestContext::clientAccessCheckDone(const allow_t &answer) page_id = ERR_ACCESS_DENIED; } - Ip::Address tmpnoaddr; - tmpnoaddr.setNoAddr(); error = clientBuildError(page_id, status, NULL, - http->getConn() != NULL ? http->getConn()->clientConnection->remote : tmpnoaddr, + http->clientAddrOnError(), http->request ); @@ -1675,6 +1673,16 @@ ClientHttpRequest::clearRequest() absorbLogUri(nullptr); } +const Ip::Address& +ClientHttpRequest::clientAddrOnError() const +{ + if (const auto conn = getConn()) + if (conn->clientConnection) + return conn->clientConnection->remote; + static Ip::Address emptyAddr; + return emptyAddr; +} + /* * doCallouts() - This function controls the order of "callout" * executions, including non-blocking access control checks, the @@ -2148,12 +2156,10 @@ ClientHttpRequest::calloutsError(const err_type error, const int errDetail) // setReplyToError, but it seems unlikely that the errno reflects the // true cause of the error at this point, so I did not pass it. if (calloutContext) { - Ip::Address noAddr; - noAddr.setNoAddr(); ConnStateData * c = getConn(); calloutContext->error = clientBuildError(error, Http::scInternalServerError, NULL, - c != NULL ? c->clientConnection->remote : noAddr, + clientAddrOnError(), request ); #if USE_AUTH diff --git a/src/client_side_request.h b/src/client_side_request.h index 5280f5850bb..33386c9f292 100644 --- a/src/client_side_request.h +++ b/src/client_side_request.h @@ -72,6 +72,9 @@ class ClientHttpRequest } } + /// client address used when creating an error page + const Ip::Address& clientAddrOnError() const; + /// Initializes the current request with the virgin request. /// Call this method when the virgin request becomes known. /// To update the current request later, use resetRequest(). diff --git a/src/comm.cc b/src/comm.cc index 4e27ce3c862..3a1685ac62c 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -468,7 +468,7 @@ comm_apply_flags(int new_socket, if ( (flags & COMM_DOBIND) || addr.port() > 0 || !addr.isAnyAddr() ) { if ( !(flags & COMM_DOBIND) && addr.isAnyAddr() ) debugs(5, DBG_IMPORTANT,"WARNING: Squid is attempting to bind() port " << addr << " without being a listener."); - if ( addr.isNoAddr() ) + if (!addr.isBindable()) debugs(5,0,"CRITICAL: Squid is attempting to bind() port " << addr << "!!"); if (commBind(new_socket, *AI) != Comm::OK) { diff --git a/src/dns_internal.cc b/src/dns_internal.cc index 44e951066a7..9384aa324fd 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -327,7 +327,7 @@ idnsAddNameserver(const char *buf) return; } - if (A.isAnyAddr()) { + if (!A.isKnown()) { debugs(78, DBG_CRITICAL, "WARNING: Squid does not accept " << A << " in DNS server specifications."); A.setLocalhost(); debugs(78, DBG_CRITICAL, "Will be using " << A << " instead, assuming you meant that DNS is running on the same machine"); @@ -887,7 +887,7 @@ idnsInitVC(size_t nsv) Comm::ConnectionPointer conn = new Comm::Connection(); - if (!Config.Addrs.udp_outgoing.isNoAddr()) + if (Config.Addrs.udp_outgoing.isBindable()) conn->setAddrs(Config.Addrs.udp_outgoing, nameservers[nsv].S); else conn->setAddrs(Config.Addrs.udp_incoming, nameservers[nsv].S); @@ -1531,7 +1531,7 @@ Dns::Init(void) if (DnsSocketA < 0 && DnsSocketB < 0) { Ip::Address addrV6; // since we do not want to alter Config.Addrs.udp_* and do not have one of our own. - if (!Config.Addrs.udp_outgoing.isNoAddr()) + if (Config.Addrs.udp_outgoing.isBindable()) addrV6 = Config.Addrs.udp_outgoing; else addrV6 = Config.Addrs.udp_incoming; diff --git a/src/esi/Esi.cc b/src/esi/Esi.cc index ebc1ecdf68c..e409c291ff9 100644 --- a/src/esi/Esi.cc +++ b/src/esi/Esi.cc @@ -1402,7 +1402,7 @@ ESIContext::freeResources () /* don't touch incoming, it's a pointer into buffered anyway */ } -ErrorState *clientBuildError (err_type, Http::StatusCode, char const *, Ip::Address &, HttpRequest *); +ErrorState *clientBuildError(err_type, Http::StatusCode, char const *, const Ip::Address &, HttpRequest *); /* This can ONLY be used before we have sent *any* data to the client */ void diff --git a/src/format/Format.cc b/src/format/Format.cc index cf0ec50c043..7b8774c79b1 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -398,7 +398,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_CLIENT_FQDN: - if (al->cache.caddr.isAnyAddr()) // e.g., ICAP OPTIONS lack client + if (!al->cache.caddr.isKnown()) // e.g., ICAP OPTIONS lack client out = "-"; else out = fqdncache_gethostbyaddr(al->cache.caddr, FQDN_LOOKUP_IF_MISS); diff --git a/src/fqdncache.cc b/src/fqdncache.cc index 4cce397e083..465341777ec 100644 --- a/src/fqdncache.cc +++ b/src/fqdncache.cc @@ -482,9 +482,8 @@ fqdncache_gethostbyaddr(const Ip::Address &addr, int flags) char name[MAX_IPSTRLEN]; fqdncache_entry *f = NULL; - if (addr.isAnyAddr() || addr.isNoAddr()) { + if (!addr.isKnown()) return NULL; - } addr.toStr(name,MAX_IPSTRLEN); ++ FqdncacheStats.requests; diff --git a/src/ftp/Parsing.cc b/src/ftp/Parsing.cc index 279b385bd8e..d5dca8a41c6 100644 --- a/src/ftp/Parsing.cc +++ b/src/ftp/Parsing.cc @@ -32,7 +32,7 @@ Ftp::ParseIpPort(const char *buf, const char *forceIp, Ip::Address &addr) snprintf(ipBuf, sizeof(ipBuf), "%d.%d.%d.%d", h1, h2, h3, h4); addr = ipBuf; - if (addr.isAnyAddr()) + if (!addr.isKnown()) return false; } @@ -68,7 +68,7 @@ Ftp::ParseProtoIpPort(const char *buf, Ip::Address &addr) ip[e - s] = '\0'; addr = ip; - if (addr.isAnyAddr()) + if (!addr.isKnown()) return false; if ((proto == 2) != addr.isIPv6()) // proto ID mismatches address version diff --git a/src/htcp.cc b/src/htcp.cc index 6da2027d83e..2f651c8678b 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -1423,10 +1423,7 @@ htcpOpenPorts(void) fatal("HTCP port cannot be opened."); } /* split-stack for now requires default IPv4-only HTCP */ - if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && htcpIncomingConn->local.isAnyAddr()) { - htcpIncomingConn->local.setIPv4(); - } - + htcpIncomingConn->local.adjustSplitStackIPv6(); AsyncCall::Pointer call = asyncCall(31, 2, "htcpIncomingConnectionOpened", Comm::UdpOpenDialer(&htcpIncomingConnectionOpened)); @@ -1436,7 +1433,7 @@ htcpOpenPorts(void) htcpIncomingConn, Ipc::fdnInHtcpSocket, call); - if (!Config.Addrs.udp_outgoing.isNoAddr()) { + if (Config.Addrs.udp_outgoing.isBindable()) { htcpOutgoingConn = new Comm::Connection; htcpOutgoingConn->local = Config.Addrs.udp_outgoing; htcpOutgoingConn->local.port(Config.Port.htcp); @@ -1446,9 +1443,7 @@ htcpOpenPorts(void) fatal("HTCP port cannot be opened."); } /* split-stack for now requires default IPv4-only HTCP */ - if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && htcpOutgoingConn->local.isAnyAddr()) { - htcpOutgoingConn->local.setIPv4(); - } + htcpOutgoingConn->local.adjustSplitStackIPv6(); enter_suid(); comm_open_listener(SOCK_DGRAM, IPPROTO_UDP, htcpOutgoingConn, "Outgoing HTCP Socket"); @@ -1474,7 +1469,7 @@ htcpIncomingConnectionOpened(const Comm::ConnectionPointer &conn, int) debugs(31, DBG_CRITICAL, "Accepting HTCP messages on " << conn->local); - if (Config.Addrs.udp_outgoing.isNoAddr()) { + if (!Config.Addrs.udp_outgoing.isBindable()) { htcpOutgoingConn = conn; debugs(31, DBG_IMPORTANT, "Sending HTCP messages from " << htcpOutgoingConn->local); } diff --git a/src/http.cc b/src/http.cc index a15ead3405f..8578add1b5c 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1833,7 +1833,7 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, if (strcmp(opt_forwarded_for, "on") == 0) { /** If set to ON - append client IP or 'unknown'. */ - if (request->clientAddr().isEmpty()) + if (!request->clientAddr().isKnown()) strListAdd(&strFwd, "unknown", ','); else strListAdd(&strFwd, request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN), ','); @@ -1844,7 +1844,7 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, /** If set to TRANSPARENT - pass through unchanged. */ } else if (strcmp(opt_forwarded_for, "truncate") == 0) { /** If set to TRUNCATE - drop existing list and replace with client IP or 'unknown'. */ - if (request->clientAddr().isEmpty() ) + if (!request->clientAddr().isKnown() ) strFwd = "unknown"; else strFwd = request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN); diff --git a/src/icmp/net_db.cc b/src/icmp/net_db.cc index c948bdbad10..df5bc6c407e 100644 --- a/src/icmp/net_db.cc +++ b/src/icmp/net_db.cc @@ -779,7 +779,7 @@ netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData) while (size >= rec_sz) { debugs(38, 5, "netdbExchangeHandleReply: in parsing loop, size = " << size); - addr.setAnyAddr(); + addr.setEmpty(); hops = rtt = 0.0; for (o = 0; o < rec_sz;) { @@ -814,7 +814,7 @@ netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData) } } - if (!addr.isAnyAddr() && rtt > 0) + if (addr.isKnown() && rtt > 0) netdbExchangeUpdatePeer(addr, ex->p.get(), rtt, hops); assert(o == rec_sz); diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 2e4b5cbc905..3ced759992d 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -720,10 +720,9 @@ icpOpenPorts(void) debugs(12, DBG_CRITICAL, "ERROR: IPv6 is disabled. " << icpIncomingConn->local << " is not an IPv4 address."); fatal("ICP port cannot be opened."); } + /* split-stack for now requires default IPv4-only ICP */ - if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && icpIncomingConn->local.isAnyAddr()) { - icpIncomingConn->local.setIPv4(); - } + icpIncomingConn->local.adjustSplitStackIPv6(); AsyncCall::Pointer call = asyncCall(12, 2, "icpIncomingConnectionOpened", @@ -734,7 +733,7 @@ icpOpenPorts(void) icpIncomingConn, Ipc::fdnInIcpSocket, call); - if ( !Config.Addrs.udp_outgoing.isNoAddr() ) { + if (Config.Addrs.udp_outgoing.isBindable() ) { icpOutgoingConn = new Comm::Connection; icpOutgoingConn->local = Config.Addrs.udp_outgoing; icpOutgoingConn->local.port(port); @@ -744,9 +743,7 @@ icpOpenPorts(void) fatal("ICP port cannot be opened."); } /* split-stack for now requires default IPv4-only ICP */ - if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && icpOutgoingConn->local.isAnyAddr()) { - icpOutgoingConn->local.setIPv4(); - } + icpOutgoingConn->local.adjustSplitStackIPv6(); enter_suid(); comm_open_listener(SOCK_DGRAM, IPPROTO_UDP, icpOutgoingConn, "Outgoing ICP Port"); @@ -777,7 +774,7 @@ icpIncomingConnectionOpened(const Comm::ConnectionPointer &conn, int) fd_note(conn->fd, "Incoming ICP port"); - if (Config.Addrs.udp_outgoing.isNoAddr()) { + if (!Config.Addrs.udp_outgoing.isBindable()) { icpOutgoingConn = conn; debugs(12, DBG_IMPORTANT, "Sending ICP messages from " << icpOutgoingConn->local); } diff --git a/src/internal.cc b/src/internal.cc index 11fae9bd47f..9b65233c6ea 100644 --- a/src/internal.cc +++ b/src/internal.cc @@ -92,9 +92,8 @@ internalRemoteUri(bool encrypt, const char *host, unsigned short port, const cha /* check for an IP address and format appropriately if found */ Ip::Address test = lc_host; - if ( !test.isAnyAddr() ) { + if (test.isKnown()) test.toHostStr(lc_host,SQUIDHOSTNAMELEN); - } /* * append the domain in order to mirror the requests with appended diff --git a/src/ip/Address.cc b/src/ip/Address.cc index 1a7e357ec97..8a5f4ea9e55 100644 --- a/src/ip/Address.cc +++ b/src/ip/Address.cc @@ -148,6 +148,31 @@ Ip::Address::applyMask(const unsigned int cidrMask, int mtype) return true; } +bool +Ip::Address::isBindable() const +{ + return !isEmpty() && !isNoAddr(); +} + +bool +Ip::Address::isKnown() const +{ + return isBindable() && !isAnyAddr(); +} + +void +Ip::Address::adjustSplitStackIPv6() +{ + if (needAdjustingSplitStackIPv6()) + setIPv4(); +} + +bool +Ip::Address::needAdjustingSplitStackIPv6() const +{ + return Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && isAnyAddr(); +} + bool Ip::Address::isSockAddr() const { diff --git a/src/ip/Address.h b/src/ip/Address.h index 69e807156c4..782f219e5fd 100644 --- a/src/ip/Address.h +++ b/src/ip/Address.h @@ -112,6 +112,12 @@ class Address */ bool isNoAddr() const; + /// whether this address may be used in bind() call + bool isBindable() const; + + /// whether this is an non-empty address other from ANY_ADDR or NO_ADDR + bool isKnown() const; + /** Content-neutral test for whether the specific IP case LOCALHOST is stored. * This is the default content of a new undefined Ip::Address object. \retval true IPv4 127.0.0.1 @@ -134,9 +140,6 @@ class Address */ bool isSiteLocalAuto() const; - /// whether the address is the same as the one created with default constructor - bool isEmpty() const; - /*@}*/ /** Retrieve the Port if stored. @@ -175,6 +178,10 @@ class Address */ bool setIPv4(); + /// applies specific settings for IPV6_SPECIAL_SPLITSTACK type + void adjustSplitStackIPv6(); + bool needAdjustingSplitStackIPv6() const; + /** * Valid results IF and only IF the stored IP address is actually a network bitmask \retval N number of bits which are set in the bitmask stored. @@ -336,6 +343,10 @@ class Address struct sockaddr_in6 mSocketAddr_; private: + + /// whether the address is the same as the one created with default constructor + bool isEmpty() const; + /* Internally used constants */ static const unsigned int STRLEN_IP4A = 16; // aaa.bbb.ccc.ddd\0 static const unsigned int STRLEN_IP4R = 28; // ddd.ccc.bbb.aaa.in-addr.arpa.\0 diff --git a/src/log/FormatSquidIcap.cc b/src/log/FormatSquidIcap.cc index 053bb6e947f..5c049a8ae6b 100644 --- a/src/log/FormatSquidIcap.cc +++ b/src/log/FormatSquidIcap.cc @@ -28,7 +28,7 @@ Log::Format::SquidIcap(const AccessLogEntry::Pointer &al, Logfile * logfile) const char *user = NULL; char tmp[MAX_IPSTRLEN], clientbuf[MAX_IPSTRLEN]; - if (al->cache.caddr.isAnyAddr()) { // ICAP OPTIONS xactions lack client + if (!al->cache.caddr.isKnown()) { // ICAP OPTIONS xactions lack client client = "-"; } else { if (Config.onoff.log_fqdn) diff --git a/src/pconn.cc b/src/pconn.cc index 1793624ee23..7b858ef2318 100644 --- a/src/pconn.cc +++ b/src/pconn.cc @@ -247,7 +247,7 @@ IdleConnList::findUseable(const Comm::ConnectionPointer &aKey) assert(size_); // small optimization: do the constant bool tests only once. - const bool keyCheckAddr = !aKey->local.isAnyAddr(); + const bool keyCheckAddr = aKey->local.isKnown(); const bool keyCheckPort = aKey->local.port() > 0; for (int i=size_-1; i>=0; --i) { diff --git a/src/peer_select.cc b/src/peer_select.cc index 3e6beb30a49..505ab747782 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -660,10 +660,10 @@ PeerSelector::selectSomeNeighborReplies() if ((p = hit)) { code = hit_type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT; } else { - if (!closest_parent_miss.isAnyAddr()) { + if (closest_parent_miss.isKnown()) { p = whichPeer(closest_parent_miss); code = CLOSEST_PARENT_MISS; - } else if (!first_parent_miss.isAnyAddr()) { + } else if (first_parent_miss.isKnown()) { p = whichPeer(first_parent_miss); code = FIRST_PARENT_MISS; } @@ -806,7 +806,7 @@ PeerSelector::handleIcpParentMiss(CachePeer *p, icp_common_t *header) return; /* set FIRST_MISS if there is no CLOSEST parent */ - if (!closest_parent_miss.isAnyAddr()) + if (closest_parent_miss.isKnown()) return; rtt = (tvSubMsec(ping.start, current_time) - p->basetime) / p->weight; @@ -814,7 +814,7 @@ PeerSelector::handleIcpParentMiss(CachePeer *p, icp_common_t *header) if (rtt < 1) rtt = 1; - if (first_parent_miss.isAnyAddr() || rtt < ping.w_rtt) { + if (!first_parent_miss.isKnown() || rtt < ping.w_rtt) { first_parent_miss = p->in_addr; ping.w_rtt = rtt; } @@ -900,7 +900,7 @@ PeerSelector::handleHtcpParentMiss(CachePeer *p, HtcpReplyData *htcp) return; /* set FIRST_MISS if there is no CLOSEST parent */ - if (!closest_parent_miss.isAnyAddr()) + if (closest_parent_miss.isKnown()) return; rtt = (tvSubMsec(ping.start, current_time) - p->basetime) / p->weight; @@ -908,7 +908,7 @@ PeerSelector::handleHtcpParentMiss(CachePeer *p, HtcpReplyData *htcp) if (rtt < 1) rtt = 1; - if (first_parent_miss.isAnyAddr() || rtt < ping.w_rtt) { + if (!first_parent_miss.isKnown() || rtt < ping.w_rtt) { first_parent_miss = p->in_addr; ping.w_rtt = rtt; } diff --git a/src/redirect.cc b/src/redirect.cc index dd0df4ab0dc..d6892c4f997 100644 --- a/src/redirect.cc +++ b/src/redirect.cc @@ -258,12 +258,9 @@ constructHelperQuery(const char *name, helper *hlp, HLPCB *replyHandler, ClientH clientStreamNode *node = (clientStreamNode *)http->client_stream.tail->prev->data; clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); assert (repContext); - Ip::Address tmpnoaddr; - tmpnoaddr.setNoAddr(); repContext->setReplyToError(ERR_GATEWAY_FAILURE, status, http->request->method, NULL, - http->getConn() != NULL && http->getConn()->clientConnection != NULL ? - http->getConn()->clientConnection->remote : tmpnoaddr, + http->clientAddrOnError(), http->request, NULL, #if USE_AUTH diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index fa09a2f849d..ad84be7b67f 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1374,7 +1374,7 @@ Ftp::Server::handleUserRequest(const SBuf &, SBuf ¶ms) // Otherwise (domain, IPv4, [bracketed] IPv6, garbage, etc), use as is. if (host.find(':') != SBuf::npos) { const Ip::Address ipa(host.c_str()); - if (!ipa.isAnyAddr()) { + if (!ipa.isKnown()) { char ipBuf[MAX_IPSTRLEN]; ipa.toHostStr(ipBuf, MAX_IPSTRLEN); host = ipBuf; @@ -1435,7 +1435,7 @@ bool Ftp::Server::createDataConnection(Ip::Address cltAddr) { assert(clientConnection != NULL); - assert(!clientConnection->remote.isAnyAddr()); + assert(!clientConnection->remote.isKnown()); if (cltAddr != clientConnection->remote) { debugs(33, 2, "rogue PORT " << cltAddr << " request? ctrl: " << clientConnection->remote); @@ -1675,7 +1675,7 @@ Ftp::Server::checkDataConnPre() return true; } - if (!dataConn || dataConn->remote.isAnyAddr()) { + if (!dataConn || !dataConn->remote.isKnown()) { debugs(33, 5, "missing " << dataConn); // TODO: use client address and default port instead. setReply(425, "Use PORT or PASV first"); diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 1e7889419ef..f8a6ab26284 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -269,15 +269,13 @@ snmpOpenPorts(void) fatal("SNMP port cannot be opened."); } /* split-stack for now requires IPv4-only SNMP */ - if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && snmpIncomingConn->local.isAnyAddr()) { - snmpIncomingConn->local.setIPv4(); - } + snmpIncomingConn->local.adjustSplitStackIPv6(); AsyncCall::Pointer call = asyncCall(49, 2, "snmpIncomingConnectionOpened", Comm::UdpOpenDialer(&snmpPortOpened)); Ipc::StartListening(SOCK_DGRAM, IPPROTO_UDP, snmpIncomingConn, Ipc::fdnInSnmpSocket, call); - if (!Config.Addrs.snmp_outgoing.isNoAddr()) { + if (Config.Addrs.snmp_outgoing.isBindable()) { snmpOutgoingConn = new Comm::Connection; snmpOutgoingConn->local = Config.Addrs.snmp_outgoing; snmpOutgoingConn->local.port(Config.Port.snmp); @@ -287,9 +285,7 @@ snmpOpenPorts(void) fatal("SNMP port cannot be opened."); } /* split-stack for now requires IPv4-only SNMP */ - if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && snmpOutgoingConn->local.isAnyAddr()) { - snmpOutgoingConn->local.setIPv4(); - } + snmpOutgoingConn->local.adjustSplitStackIPv6(); AsyncCall::Pointer c = asyncCall(49, 2, "snmpOutgoingConnectionOpened", Comm::UdpOpenDialer(&snmpPortOpened)); Ipc::StartListening(SOCK_DGRAM, IPPROTO_UDP, snmpOutgoingConn, Ipc::fdnOutSnmpSocket, c); @@ -771,8 +767,6 @@ client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn aux = client_entry(NULL); if (aux) laddr = *aux; - else - laddr.setAnyAddr(); if (laddr.isIPv4()) size = sizeof(in_addr); @@ -784,7 +778,7 @@ client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn instance = (oid *)xmalloc(sizeof(*name) * (*len + size )); memcpy(instance, name, (sizeof(*name) * (*len))); - if ( !laddr.isAnyAddr() ) { + if (laddr.isKnown() ) { addr2oid(laddr, &instance[ *len]); // the addr *len += size ; } @@ -794,10 +788,8 @@ client_Inst(oid * name, snint * len, mib_tree_entry * current, oid_ParseFn ** Fn aux = client_entry(&laddr); if (aux) laddr = *aux; - else - laddr.setAnyAddr(); - if (!laddr.isAnyAddr()) { + if (laddr.isKnown()) { if (laddr.isIPv4()) newshift = sizeof(in_addr); else diff --git a/src/tools.cc b/src/tools.cc index 582957497df..4f151434fa7 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -424,14 +424,14 @@ getMyHostname(void) host[0] = '\0'; - if (HttpPortList != NULL && sa.isAnyAddr()) + if (HttpPortList != NULL) sa = HttpPortList->s; /* * If the first http_port address has a specific address, try a * reverse DNS lookup on it. */ - if ( !sa.isAnyAddr() ) { + if (sa.isKnown()) { sa.getAddrInfo(AI); /* we are looking for a name. */ diff --git a/src/wccp.cc b/src/wccp.cc index 2ba0ac4a432..0801d8640d6 100644 --- a/src/wccp.cc +++ b/src/wccp.cc @@ -99,7 +99,7 @@ wccpInit(void) last_assign_buckets_change = 0; number_caches = 0; - if (!Config.Wccp.router.isAnyAddr()) + if (Config.Wccp.router.isKnown()) if (!eventFind(wccpHereIam, NULL)) eventAdd("wccpHereIam", wccpHereIam, NULL, 5.0, 1); } @@ -109,7 +109,7 @@ wccpConnectionOpen(void) { debugs(80, 5, "wccpConnectionOpen: Called"); - if (Config.Wccp.router.isAnyAddr()) { + if (!Config.Wccp.router.isKnown()) { debugs(80, 2, "WCCPv1 disabled."); return; } diff --git a/src/wccp2.cc b/src/wccp2.cc index 4674c5aa126..413d8149e87 100644 --- a/src/wccp2.cc +++ b/src/wccp2.cc @@ -669,7 +669,7 @@ wccp2Init(void) /* Calculate the number of routers configured in the config file */ for (s = Config.Wccp2.router; s; s = s->next) { - if (!s->s.isAnyAddr()) { + if (s->s.isKnown()) { /* Increment the counter */ ++wccp2_numrouters; } @@ -829,7 +829,7 @@ wccp2Init(void) /* Add each router. Keep this functionality here to make sure the received_id can be updated in the packet */ for (s = Config.Wccp2.router; s; s = s->next) { - if (!s->s.isAnyAddr()) { + if (s->s.isKnown()) { wccp2_here_i_am_header.length += sizeof(struct wccp2_router_id_element_t); assert(wccp2_here_i_am_header.length <= WCCP_RESPONSE_SIZE); From 25be44406afb9a1453a624715f5a9b7385fdde78 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 28 May 2019 17:44:16 +0300 Subject: [PATCH 37/66] Fixing no-addr/empty-addr inconsistencies, pt 2 One more case fixed. --- tools/cachemgr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cachemgr.cc b/tools/cachemgr.cc index 98a6ae2316f..f58b5b513b5 100644 --- a/tools/cachemgr.cc +++ b/tools/cachemgr.cc @@ -802,7 +802,7 @@ process_request(cachemgr_request * req) S = *gethostbyname(req->hostname); - if ( !S.isAnyAddr() ) { + if (S.isKnown()) { (void) 0; } else if ((S = req->hostname)) (void) 0; From ceae00f7da3b08d7eb89059b032b89d81808c17d Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Fri, 11 Oct 2019 21:40:02 +0300 Subject: [PATCH 38/66] Polishing: better method names, comments, code duplication --- src/AccessLogEntry.cc | 2 +- src/DelayId.cc | 2 +- src/Downloader.cc | 2 +- src/FwdState.cc | 2 +- src/HttpRequest.cc | 20 ++++++-------------- src/HttpRequest.h | 4 ++-- src/MasterXaction.cc | 4 ---- src/MasterXaction.h | 5 +++-- src/acl/Eui64.cc | 2 +- src/acl/FilledChecklist.cc | 7 +++---- src/acl/FilledChecklist.h | 7 ++++--- src/adaptation/ecap/XactionRep.cc | 2 +- src/adaptation/icap/ModXact.cc | 2 +- src/client_side.cc | 8 ++++---- src/client_side_reply.cc | 4 ++-- src/client_side_request.cc | 11 +++++------ src/client_side_request.h | 5 +++-- src/ip/Address.h | 2 ++ src/tests/stub_HttpRequest.cc | 2 +- 19 files changed, 42 insertions(+), 51 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index 25bce4bee1c..df6d1d83cf9 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -21,7 +21,7 @@ AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.log_uses_indirect_client && request) - log_ip = request->indirectClientAddr(); + log_ip = request->furthestClientAddress(); else #endif if (tcpClient) diff --git a/src/DelayId.cc b/src/DelayId.cc index 85292448d99..748e6901c38 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -92,7 +92,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) } #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.delay_pool_uses_indirect_client) - ch.forceIndirectAddr(); + ch.preferIndirectAddr(); else #endif /* FOLLOW_X_FORWARDED_FOR */ ch.forceDirectAddr(); diff --git a/src/Downloader.cc b/src/Downloader.cc index d6415957061..1c539d3baeb 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -128,7 +128,7 @@ Downloader::buildRequest() { const HttpRequestMethod method = Http::METHOD_GET; - // TODO: reuse the original transaction, if available + // TODO: reuse the original master transaction, if available const MasterXaction::Pointer mx = new MasterXaction(initiator_); HttpRequest *const request = HttpRequest::FromUrl(url_.c_str(), mx, method); if (!request) { diff --git a/src/FwdState.cc b/src/FwdState.cc index 18599c44ffc..5ee26bfa726 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -1457,7 +1457,7 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) if (!conn->getPeer() || !conn->getPeer()->options.no_tproxy) { #if FOLLOW_X_FORWARDED_FOR && LINUX_NETFILTER if (Config.onoff.tproxy_uses_indirect_client) - conn->local = request->indirectClientAddr(); + conn->local = request->furthestClientAddress(); else #endif conn->local = request->clientAddr(); diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 9161aef9a0f..e6625285cea 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -118,10 +118,9 @@ HttpRequest::init() forcedBodyContinuation = false; selfInitiated_ = false; - if (clientConnectionManager().valid()) { - if (const auto port = clientConnectionManager()->port) { + if (const auto mgr = clientConnectionManager().valid()) { + if (const auto port = mgr->port) flags.ignoreCc = port->ignore_cc; - } } } @@ -760,19 +759,12 @@ HttpRequest::clientConnectionManager() return noManager; } -static const Ip::Address& -EmptyAddr() -{ - static Ip::Address addr; - return addr; -} - const Ip::Address& HttpRequest::clientAddr() const { if (!selfInitiated_) return clientConnection() ? clientConnection()->remote : client_addr; - return EmptyAddr(); + return Ip::Address::Empty(); } void @@ -787,16 +779,16 @@ HttpRequest::myAddr() const { if (!selfInitiated_) return masterXaction->clientConnection() ? masterXaction->clientConnection()->local : my_addr; - return EmptyAddr(); + return Ip::Address::Empty(); } #if FOLLOW_X_FORWARDED_FOR const Ip::Address& -HttpRequest::indirectClientAddr() const +HttpRequest::furthestClientAddress() const { if (!selfInitiated_) return indirect_client_addr.isKnown() ? indirect_client_addr : clientAddr(); - return EmptyAddr(); + return Ip::Address::Empty(); } void diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 4a6380620ad..5ebeb938769 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -174,8 +174,8 @@ class HttpRequest: public Http::Message Comm::ConnectionPointer clientConnection() const; #if FOLLOW_X_FORWARDED_FOR - /// the indirect client address - const Ip::Address& indirectClientAddr() const; + /// Indirect client address, if available, otherwise clientAddr(). + const Ip::Address& furthestClientAddress() const; void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } /// force using direct client address diff --git a/src/MasterXaction.cc b/src/MasterXaction.cc index 862fed46b31..fe1ebeebdff 100644 --- a/src/MasterXaction.cc +++ b/src/MasterXaction.cc @@ -13,10 +13,6 @@ InstanceIdDefinitions(MasterXaction, "MXID_"); -MasterXaction::MasterXaction(const XactionInitiator anInitiator) : - initiator(anInitiator) -{}; - MasterXaction::MasterXaction(const XactionInitiator anInitiator, ConnStateData *connManager) : initiator(anInitiator), clientConnectionManager_(connManager), diff --git a/src/MasterXaction.h b/src/MasterXaction.h index 8d35498754a..7edb55ad902 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -43,11 +43,12 @@ class MasterXaction : public RefCountable { public: typedef RefCount Pointer; - explicit MasterXaction(const XactionInitiator); + // Creators must call the first constructor they can call (with a non-nil + // pointer). Following this rule maximizes stored information. MasterXaction(const XactionInitiator, ConnStateData *); - MasterXaction(const XactionInitiator, Comm::ConnectionPointer); + explicit MasterXaction(const XactionInitiator anInitiator) : initiator(anInitiator) {} /// the client connection of the transaction, if any Comm::ConnectionPointer clientConnection(); diff --git a/src/acl/Eui64.cc b/src/acl/Eui64.cc index 6c3a4cdf607..bfea58f48ec 100644 --- a/src/acl/Eui64.cc +++ b/src/acl/Eui64.cc @@ -88,7 +88,7 @@ ACLEui64::match(ACLChecklist *cl) /* IPv4 does not do EUI-64 (yet) */ if (!checklist->clientAddr().isIPv6()) { - debugs(14, 3, "ACLEui64::match: IPv6 Required for EUI-64 Lookups. Skipping " << checklist->clientAddr() ); + debugs(14, 3, "ACLEui64::match: IPv6 Required for EUI-64 Lookups. Skipping " << checklist->clientAddr()); return 0; } diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 6a4d9e5b6f6..7dd59b855b1 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -150,10 +150,10 @@ ACLFilledChecklist::clientConnectionManager() const #if FOLLOW_X_FORWARDED_FOR void -ACLFilledChecklist::forceIndirectAddr() +ACLFilledChecklist::preferIndirectAddr() { assert(request); - client_addr = request->indirectClientAddr(); + client_addr = request->furthestClientAddress(); } #endif @@ -263,7 +263,6 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) static void InitializeClientAddress(Ip::Address &addr, const Ip::Address &value) { - //Must(addr.isKnown() || addr == value); assert(!addr.isKnown() || addr == value); if (!addr.isKnown()) addr = value; @@ -276,7 +275,7 @@ ACLFilledChecklist::setClientSideAddresses() if (request) { #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.acl_uses_indirect_client) - InitializeClientAddress(client_addr, request->indirectClientAddr()); + InitializeClientAddress(client_addr, request->furthestClientAddress()); else #endif InitializeClientAddress(client_addr, request->clientAddr()); diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 5b5d1475bb0..dd07b8601fc 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -53,9 +53,9 @@ class ACLFilledChecklist: public ACLChecklist void setClientConnectionDetails(ConnStateData *, Comm::ConnectionPointer conn = nullptr); #if FOLLOW_X_FORWARDED_FOR - /// Configures clientAddr() to always return available indirect client address - /// instead of direct client address. - void forceIndirectAddr(); + /// Instructs clientAddr() to return the indirect client address, if available, + /// or direct client address otherwise. + void preferIndirectAddr(); #endif /// Configures clientAddr() to always return direct client address @@ -137,6 +137,7 @@ class ACLFilledChecklist: public ACLChecklist /// by Squid configuration. The checklist may be configured to force either direct or indirect /// client address usage, overwriting the default configuration. Ip::Address client_addr; + /// the local address of the client connection Ip::Address my_addr; /// not implemented; will cause link failures if used diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index 0a4e088667b..bfe66d4d3c1 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -131,7 +131,7 @@ Adaptation::Ecap::XactionRep::clientIpValue() const Ip::Address client_addr; #if FOLLOW_X_FORWARDED_FOR if (TheConfig.use_indirect_client) - client_addr = request->indirectClientAddr(); + client_addr = request->furthestClientAddress(); else #endif client_addr = request->clientAddr(); diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index be7816d485a..15af40c5c78 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1479,7 +1479,7 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) Ip::Address client_addr; #if FOLLOW_X_FORWARDED_FOR if (TheConfig.use_indirect_client) - client_addr = request->indirectClientAddr(); + client_addr = request->furthestClientAddress(); else #endif client_addr = request->clientAddr(); diff --git a/src/client_side.cc b/src/client_side.cc index 71981d55698..e4fe7e264e0 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1404,7 +1404,7 @@ parseHttpRequest(ConnStateData *csd, const Http1::RequestParserPointer &hp) http->uri = xstrdup(internalLocalUri(NULL, hp->requestUri())); // We just re-wrote the URL. Must replace the Host: header. // But have not parsed there yet!! flag for local-only handling. - http->flags.internalReceived = true; + http->flags.askingForOurInternalResource = true; } else if (csd->port->flags.accelSurrogate) { /* accelerator mode */ @@ -1641,19 +1641,19 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp, if (internalCheck(request->url.path())) { if (internalHostnameIs(request->url.host()) && request->url.port() == getMyPort()) { debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true)); - http->flags.internalReceived = true; + http->flags.askingForOurInternalResource = true; } else if (Config.onoff.global_internal_static && internalStaticCheck(request->url.path())) { debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true) << " (global_internal_static on)"); request->url.setScheme(AnyP::PROTO_HTTP, "http"); request->url.host(internalHostname()); request->url.port(getMyPort()); - http->flags.internalReceived = true; + http->flags.askingForOurInternalResource = true; http->setLogUriToRequestUri(); } else debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true) << " (not this proxy)"); } - request->flags.internalReceived = http->flags.internalReceived; + request->flags.internalReceived = http->flags.askingForOurInternalResource; if (!isFtp) { // XXX: for non-HTTP messages instantiate a different Http::Message child type diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 0b34a108fd4..c1e33581842 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -647,7 +647,7 @@ clientReplyContext::cacheHit(StoreIOBuffer result) http->logType.update(LOG_TCP_MISS); processMiss(); return; - } else if (!http->flags.internalReceived && refreshCheckHTTP(e, r)) { + } else if (!http->flags.askingForOurInternalResource && refreshCheckHTTP(e, r)) { debugs(88, 5, "clientCacheHit: in refreshCheck() block"); /* * We hold a stale copy; it needs to be validated @@ -869,7 +869,7 @@ clientReplyContext::blockedHit() const if (!Config.accessList.sendHit) return false; // hits are not blocked by default - if (http->flags.internalReceived) + if (http->flags.askingForOurInternalResource) return false; // internal content "hits" cannot be blocked if (const HttpReply *rep = http->storeEntry()->getReply()) { diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 10e8871cbcd..a01da4260d6 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -470,7 +470,7 @@ clientFollowXForwardedForCheck(Acl::Answer answer, void *data) request->x_forwarded_for_iterator.cut(l); calloutContext->acl_checklist = clientAclChecklistCreate(Config.accessList.followXFF, http); /* override the default src_addr tested if we have to go deeper than one level into XFF */ - Filled(calloutContext->acl_checklist)->forceIndirectAddr(); + Filled(calloutContext->acl_checklist)->preferIndirectAddr(); calloutContext->acl_checklist->nonBlockingCheck(clientFollowXForwardedForCheck, data); return; } @@ -482,15 +482,15 @@ clientFollowXForwardedForCheck(Acl::Answer answer, void *data) * Ensure that the access log shows the indirect client * instead of the direct client. */ - http->al->cache.caddr = request->indirectClientAddr(); + http->al->cache.caddr = request->furthestClientAddress(); if (ConnStateData *conn = http->getConn()) - conn->log_addr = request->indirectClientAddr(); + conn->log_addr = request->furthestClientAddress(); } request->x_forwarded_for_iterator.clean(); request->flags.done_follow_x_forwarded_for = true; if (answer.conflicted()) { - debugs(28, DBG_CRITICAL, "ERROR: Processing X-Forwarded-For. Stopping at IP address: " << request->indirectClientAddr() ); + debugs(28, DBG_CRITICAL, "ERROR: Processing X-Forwarded-For. Stopping at IP address: " << request->furthestClientAddress()); } /* process actual access ACL as normal. */ @@ -1690,8 +1690,7 @@ ClientHttpRequest::clientAddrOnError() const if (const auto conn = getConn()) if (conn->clientConnection) return conn->clientConnection->remote; - static Ip::Address emptyAddr; - return emptyAddr; + return Ip::Address::Empty(); } /* diff --git a/src/client_side_request.h b/src/client_side_request.h index 33386c9f292..556b4d76996 100644 --- a/src/client_side_request.h +++ b/src/client_side_request.h @@ -127,10 +127,11 @@ class ClientHttpRequest AccessLogEntry::Pointer al; ///< access.log entry struct Flags { - Flags() : accel(false), internalReceived(false), done_copying(false), purging(false) {} + Flags() : accel(false), askingForOurInternalResource(false), done_copying(false), purging(false) {} bool accel; - bool internalReceived; + /// a request with a /squid-internal-... URL referring to this Squid instance + bool askingForOurInternalResource; bool done_copying; bool purging; } flags; diff --git a/src/ip/Address.h b/src/ip/Address.h index 782f219e5fd..16ef75eccc6 100644 --- a/src/ip/Address.h +++ b/src/ip/Address.h @@ -300,6 +300,8 @@ class Address */ static void InitAddr(struct addrinfo *&ai); + static const Address &Empty() { static Address emptyAddr; return emptyAddr; } + /** * Lookup a Host by Name. Equivalent to system call gethostbyname(char*) \param s The textual FQDN of the host being located. diff --git a/src/tests/stub_HttpRequest.cc b/src/tests/stub_HttpRequest.cc index 1a3274adce2..756017b7b07 100644 --- a/src/tests/stub_HttpRequest.cc +++ b/src/tests/stub_HttpRequest.cc @@ -58,7 +58,7 @@ bool HttpRequest::sanityCheckStartLine(const char *, const size_t, Http::StatusC void HttpRequest::hdrCacheInit() STUB bool HttpRequest::inheritProperties(const Http::Message *) STUB_RETVAL(false) #if FOLLOW_X_FORWARDED_FOR -const Ip::Address& HttpRequest::indirectClientAddr() const STUB_RETREF(Ip::Address) +const Ip::Address& HttpRequest::furthestClientAddress() const STUB_RETREF(Ip::Address) #endif const Ip::Address& HttpRequest::clientAddr() const STUB_RETREF(Ip::Address) const Ip::Address& HttpRequest::myAddr() const STUB_RETREF(Ip::Address) From 650b4fc798c0d161e1d7faf90903462872f4cf9d Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 14 Oct 2019 16:48:24 +0300 Subject: [PATCH 39/66] Polishing: method names and descriptions --- src/HttpRequest.cc | 8 ++++---- src/HttpRequest.h | 13 ++++++++----- src/acl/Asn.cc | 2 +- src/client_side_request.cc | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index e6625285cea..2ef80b9e0c6 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -738,11 +738,11 @@ HttpRequest::prepareForDownloader(Downloader *aDownloader) header.putStr(Http::HdrType::HOST, url.host()); header.putTime(Http::HdrType::DATE, squid_curtime); downloader = aDownloader; - selfInitiated(); + markAsSelfInitiated(); } void -HttpRequest::selfInitiated() +HttpRequest::markAsSelfInitiated() { /* Internally created requests cannot have bodies today */ content_length = 0; @@ -762,7 +762,7 @@ HttpRequest::clientConnectionManager() const Ip::Address& HttpRequest::clientAddr() const { - if (!selfInitiated_) + if (!selfInitiated_) // Optimization: Checking clientConnection() would be enough. return clientConnection() ? clientConnection()->remote : client_addr; return Ip::Address::Empty(); } @@ -823,7 +823,7 @@ HttpRequest::setInterceptionFlags(const AccessLogEntryPointer &al) bool HttpRequest::needCheckMissAccess() const { - return !(flags.internalReceived || url.getScheme() == AnyP::PROTO_CACHE_OBJECT || isSelfInitiated()); + return !(flags.internalReceived || url.getScheme() == AnyP::PROTO_CACHE_OBJECT || selfInitiated()); } char * diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 5ebeb938769..ea1177274b0 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -150,10 +150,10 @@ class HttpRequest: public Http::Message int imslen; /// mark this request as initiated by Squid (rather than received on a client connection) - void selfInitiated(); + void markAsSelfInitiated(); /// whether this request was initiated by Squid (rather than received on a client connection) - bool isSelfInitiated() const { return selfInitiated_; } + bool selfInitiated() const { return selfInitiated_; } /// supply Downloader-specific settings void prepareForDownloader(Downloader *); @@ -161,7 +161,7 @@ class HttpRequest: public Http::Message /// specify addresses manually when lacking client connection void prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr); - /// the remote address of the client connection + /// the source address of the client connection const Ip::Address& clientAddr() const; /// the local address of the client connection @@ -170,7 +170,9 @@ class HttpRequest: public Http::Message /// the client connection manager of the underlying transaction, if any CbcPointer &clientConnectionManager(); - /// the client connection of the underlying transaction, if any + /// the client connection of the underlying transaction + /// \retval * client connection that initiated this request (if any) + /// \retval nil for selfInitiated() requests Comm::ConnectionPointer clientConnection() const; #if FOLLOW_X_FORWARDED_FOR @@ -178,7 +180,8 @@ class HttpRequest: public Http::Message const Ip::Address& furthestClientAddress() const; void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } - /// force using direct client address + + /// forces furthestClientAddress() to return a direct client address void ignoreIndirectClientAddr(); #endif diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index 673c92c6913..b5a47665c7b 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -238,7 +238,7 @@ asnCacheStart(int as) asState->request = new HttpRequest(mx); asState->request->url = whoisUrl; asState->request->method = Http::METHOD_GET; - asState->request->selfInitiated(); + asState->request->markAsSelfInitiated(); // XXX: performance regression, c_str() reallocates const auto asres = xstrdup(whoisUrl.absolute().c_str()); diff --git a/src/client_side_request.cc b/src/client_side_request.cc index a01da4260d6..952f8cac9cd 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -375,7 +375,7 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre * objects ? */ - request->selfInitiated(); + request->markAsSelfInitiated(); http->initRequest(request); From 5acff0c363d0a6eac30503e4f6e00120558d08b8 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 28 Oct 2019 16:56:45 +0300 Subject: [PATCH 40/66] Moved several HttpRequest source/client address methods to ALE The work is not completed. --- src/AccessLogEntry.cc | 34 ++++++++++++- src/AccessLogEntry.h | 24 +++++++++ src/DelayId.cc | 4 +- src/FwdState.cc | 37 +++++++------- src/FwdState.h | 8 +-- src/HttpHeaderTools.cc | 8 +-- src/HttpReply.cc | 12 ++--- src/HttpReply.h | 6 +-- src/HttpRequest.cc | 81 +++---------------------------- src/HttpRequest.h | 29 +---------- src/Notes.cc | 3 +- src/PeerPoolMgr.cc | 4 +- src/acl/Asn.cc | 1 - src/acl/FilledChecklist.cc | 15 +++--- src/acl/FilledChecklist.h | 2 +- src/adaptation/AccessCheck.cc | 3 +- src/adaptation/ecap/XactionRep.cc | 4 +- src/adaptation/icap/Launcher.cc | 10 ++-- src/adaptation/icap/Launcher.h | 3 +- src/adaptation/icap/ModXact.cc | 8 +-- src/adaptation/icap/Xaction.cc | 4 +- src/adaptation/icap/icap_log.cc | 2 +- src/auth/UserRequest.cc | 14 +++--- src/auth/UserRequest.h | 4 +- src/auth/basic/UserRequest.cc | 2 +- src/auth/basic/UserRequest.h | 2 +- src/auth/digest/UserRequest.cc | 8 +-- src/auth/digest/UserRequest.h | 2 +- src/auth/negotiate/UserRequest.cc | 2 +- src/auth/negotiate/UserRequest.h | 2 +- src/auth/ntlm/UserRequest.cc | 2 +- src/auth/ntlm/UserRequest.h | 2 +- src/client_side.cc | 34 ++++++------- src/client_side_reply.cc | 8 +-- src/client_side_request.cc | 15 +++--- src/clients/Client.cc | 4 +- src/clients/FtpClient.cc | 2 +- src/comm/TcpAcceptor.cc | 3 +- src/errorpage.cc | 4 +- src/format/Format.cc | 2 +- src/htcp.cc | 15 +++--- src/http.cc | 24 +++++---- src/http.h | 4 +- src/http/Stream.cc | 2 +- src/icp_v2.cc | 5 +- src/ip/Address.h | 6 +-- src/neighbors.cc | 5 +- src/peer_select.cc | 14 +++--- src/peer_sourcehash.cc | 3 +- src/security/PeerConnector.cc | 6 +-- src/servers/FtpServer.cc | 3 +- src/servers/Http1Server.cc | 3 +- src/snmp_core.cc | 2 +- src/ssl/PeekingPeerConnector.cc | 3 +- src/store_client.cc | 4 +- src/tunnel.cc | 7 ++- 56 files changed, 234 insertions(+), 286 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index df6d1d83cf9..f4154e0e484 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -21,7 +21,7 @@ AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.log_uses_indirect_client && request) - log_ip = request->furthestClientAddress(); + log_ip = furthestClientAddress(); else #endif if (tcpClient) @@ -131,3 +131,35 @@ AccessLogEntry::effectiveVirginUrl() const return nullptr; } +const Ip::Address& +AccessLogEntry::clientAddr() const +{ + return tcpClient ? tcpClient->remote : client_addr; +} + +#if FOLLOW_X_FORWARDED_FOR +const Ip::Address& +AccessLogEntry::furthestClientAddress() const +{ + return indirect_client_addr.isKnown() ? indirect_client_addr : clientAddr(); +} + +void +AccessLogEntry::ignoreIndirectClientAddr() +{ + indirect_client_addr.setEmpty(); +} +#endif /* FOLLOW_X_FORWARDED_FOR */ + +void +AccessLogEntry::prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr) +{ + client_addr = fromAddr; + my_addr = localAddr; +} + +const Ip::Address& +AccessLogEntry::myAddr() const +{ + return tcpClient ? tcpClient->local : my_addr; +} diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index 9625aebd062..5b462085b83 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -61,10 +61,34 @@ class AccessLogEntry: public RefCountable void syncNotes(HttpRequest *request); + /// the source address of the client connection + const Ip::Address& clientAddr() const; + +#if FOLLOW_X_FORWARDED_FOR + /// Indirect client address, if available, otherwise clientAddr(). + const Ip::Address& furthestClientAddress() const; + + void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } + + /// forces furthestClientAddress() to return a direct client address + void ignoreIndirectClientAddr(); +#endif + /// specify addresses manually when lacking client connection + void prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr); + + /// the local address of the client connection + const Ip::Address& myAddr() const; + SBuf url; /// TCP/IP level details about the client connection Comm::ConnectionPointer tcpClient; +#if FOLLOW_X_FORWARDED_FOR + Ip::Address indirect_client_addr; ///< calculated client address, after applying X-Forwarded-For rules +#endif + Ip::Address client_addr; ///< source address of a non-TCP (e.g. ICMP) client + Ip::Address my_addr; ///< local address which a non-TCP (e.g., ICMP) client connects to + // TCP/IP level details about the server or peer connection // are stored in hier.tcpServer diff --git a/src/DelayId.cc b/src/DelayId.cc index 748e6901c38..5b4d55a8102 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -71,7 +71,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) assert(http); r = http->request; - if (!r->clientAddr().isKnown()) { + if (!http->al->clientAddr().isKnown()) { debugs(77, 2, "called with unknown address, ignoring"); return DelayId(); } @@ -85,7 +85,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) continue; } - ACLFilledChecklist ch(DelayPools::delay_data[pool].access, r, NULL); + ACLFilledChecklist ch(DelayPools::delay_data[pool].access, r, http->al, nullptr); if (reply) { ch.reply = reply; HTTPMSGLOCK(reply); diff --git a/src/FwdState.cc b/src/FwdState.cc index 5ee26bfa726..a8471f97af5 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -305,13 +305,12 @@ FwdState::~FwdState() void FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, HttpRequest *request, const AccessLogEntryPointer &al) { - if (Config.accessList.miss && request->needCheckMissAccess()) { + if (Config.accessList.miss && !al->clientAddr().isEmpty() && request->needCheckMissAccess()) { // Check if this host is allowed to fetch MISSES from us (miss_access). - ACLFilledChecklist ch(Config.accessList.miss, request, NULL); + ACLFilledChecklist ch(Config.accessList.miss, request, al, nullptr); // TODO: Explain this acl_uses_indirect_client violation in squid.conf. // TODO: Refer to the above squid.conf documentation here. ch.forceDirectAddr(); - ch.al = al; ch.syncAle(request, nullptr); if (ch.fastCheck().denied()) { err_type page_id; @@ -906,11 +905,11 @@ void FwdState::syncWithServerConn(const char *host) { if (Ip::Qos::TheConfig.isAclTosActive()) - Ip::Qos::setSockTos(serverConn, GetTosToServer(request)); + Ip::Qos::setSockTos(serverConn, GetTosToServer(request, al)); #if SO_MARK if (Ip::Qos::TheConfig.isAclNfmarkActive()) - Ip::Qos::setSockNfmark(serverConn, GetNfmarkToServer(request)); + Ip::Qos::setSockNfmark(serverConn, GetNfmarkToServer(request, al)); #endif syncHierNote(serverConn, host); @@ -1020,7 +1019,7 @@ FwdState::connectStart() entry->mem_obj->checkUrlChecksum(); #endif - GetMarkingsToServer(request, *serverDestinations[0]); + GetMarkingsToServer(request, *serverDestinations[0], al); const AsyncCall::Pointer connector = commCbCall(17,3, "fwdConnectDoneWrapper", CommConnectCbPtrFun(fwdConnectDoneWrapper, this)); const auto connTimeout = connectingTimeout(serverDestinations[0]); @@ -1332,8 +1331,7 @@ FwdState::pconnPop(const Comm::ConnectionPointer &dest, const char *domain) { bool retriable = checkRetriable(); if (!retriable && Config.accessList.serverPconnForNonretriable) { - ACLFilledChecklist ch(Config.accessList.serverPconnForNonretriable, request, NULL); - ch.al = al; + ACLFilledChecklist ch(Config.accessList.serverPconnForNonretriable, request, al, nullptr); ch.syncAle(request, nullptr); retriable = ch.fastCheck().allowed(); } @@ -1442,7 +1440,7 @@ aclFindNfMarkConfig(acl_nfmark * head, ACLChecklist * ch) } void -getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) +getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn, AccessLogEntry::Pointer al) { // skip if an outgoing address is already set. if (conn->local.isKnown()) @@ -1457,10 +1455,10 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) if (!conn->getPeer() || !conn->getPeer()->options.no_tproxy) { #if FOLLOW_X_FORWARDED_FOR && LINUX_NETFILTER if (Config.onoff.tproxy_uses_indirect_client) - conn->local = request->furthestClientAddress(); + conn->local = al->furthestClientAddress(); else #endif - conn->local = request->clientAddr(); + conn->local = al->clientAddr(); conn->local.port(0); // let OS pick the source port to prevent address clashes // some flags need setting on the socket to use this address conn->flags |= COMM_DOBIND; @@ -1474,9 +1472,10 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) return; // anything will do. } - ACLFilledChecklist ch(NULL, request, NULL); + ACLFilledChecklist ch(NULL, request, al, nullptr); ch.dst_peer_name = conn->getPeer() ? conn->getPeer()->name : NULL; ch.dst_addr = conn->remote; + // TODO: ch.syncAle(request, nullptr); // TODO use the connection details in ACL. // needs a bit of rework in ACLFilledChecklist to use Comm::Connection instead of ConnStateData @@ -1495,31 +1494,31 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn) } tos_t -GetTosToServer(HttpRequest * request) +GetTosToServer(HttpRequest * request, const AccessLogEntry::Pointer &al) { - ACLFilledChecklist ch(NULL, request, NULL); + ACLFilledChecklist ch(NULL, request, al, nullptr); return aclMapTOS(Ip::Qos::TheConfig.tosToServer, &ch); } nfmark_t -GetNfmarkToServer(HttpRequest * request) +GetNfmarkToServer(HttpRequest * request, const AccessLogEntry::Pointer &al) { - ACLFilledChecklist ch(NULL, request, NULL); + ACLFilledChecklist ch(nullptr, request, al, nullptr); const auto mc = aclFindNfMarkConfig(Ip::Qos::TheConfig.nfmarkToServer, &ch); return mc.mark; } void -GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn) +GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn, const AccessLogEntry::Pointer &al) { // Get the server side TOS and Netfilter mark to be set on the connection. if (Ip::Qos::TheConfig.isAclTosActive()) { - conn.tos = GetTosToServer(request); + conn.tos = GetTosToServer(request, al); debugs(17, 3, "from " << conn.local << " tos " << int(conn.tos)); } #if SO_MARK && USE_LIBCAP - conn.nfmark = GetNfmarkToServer(request); + conn.nfmark = GetNfmarkToServer(request, al); debugs(17, 3, "from " << conn.local << " netfilter mark " << conn.nfmark); #else conn.nfmark = 0; diff --git a/src/FwdState.h b/src/FwdState.h index 8722fd41e0f..230893cd60c 100644 --- a/src/FwdState.h +++ b/src/FwdState.h @@ -44,16 +44,16 @@ class CertValidationResponse; * Returns the TOS value that we should be setting on the connection * to the server, based on the ACL. */ -tos_t GetTosToServer(HttpRequest * request); +tos_t GetTosToServer(HttpRequest *request, const AccessLogEntry::Pointer &al); /** * Returns the Netfilter mark value that we should be setting on the * connection to the server, based on the ACL. */ -nfmark_t GetNfmarkToServer(HttpRequest * request); +nfmark_t GetNfmarkToServer(HttpRequest *request, const AccessLogEntry::Pointer &al); /// Sets initial TOS value and Netfilter for the future outgoing connection. -void GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn); +void GetMarkingsToServer(HttpRequest *request, Comm::Connection &conn, const AccessLogEntry::Pointer &); class HelperReply; @@ -184,7 +184,7 @@ class FwdState: public RefCountable, public PeerSelectionInitiator PconnRace pconnRace; ///< current pconn race state }; -void getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn); +void getOutgoingAddress(HttpRequest *request, Comm::ConnectionPointer conn, AccessLogEntry::Pointer); #endif /* SQUID_FORWARD_H */ diff --git a/src/HttpHeaderTools.cc b/src/HttpHeaderTools.cc index f2cded7add3..4c9b3c5d550 100644 --- a/src/HttpHeaderTools.cc +++ b/src/HttpHeaderTools.cc @@ -273,7 +273,7 @@ httpHeaderQuoteString(const char *raw) * \retval 1 Header has no access controls to test */ static int -httpHdrMangle(HttpHeaderEntry * e, HttpRequest * request, HeaderManglers *hms) +httpHdrMangle(HttpHeaderEntry *e, HttpRequest * request, HeaderManglers *hms, const AccessLogEntryPointer &al) { int retval; @@ -287,7 +287,7 @@ httpHdrMangle(HttpHeaderEntry * e, HttpRequest * request, HeaderManglers *hms) return 1; } - ACLFilledChecklist checklist(hm->access_list, request, NULL); + ACLFilledChecklist checklist(hm->access_list, request, al, nullptr); if (checklist.fastCheck().allowed()) { /* aclCheckFast returns true for allow. */ @@ -335,7 +335,7 @@ httpHdrMangleList(HttpHeader *l, HttpRequest *request, const AccessLogEntryPoint if (hms) { int headers_deleted = 0; while ((e = l->getEntry(&p))) { - if (0 == httpHdrMangle(e, request, hms)) + if (0 == httpHdrMangle(e, request, hms, al)) l->delAt(p, headers_deleted); } @@ -476,7 +476,7 @@ HeaderManglers::find(const HttpHeaderEntry &e) const void httpHdrAdd(HttpHeader *heads, HttpRequest *request, const AccessLogEntryPointer &al, HeaderWithAclList &headersAdd) { - ACLFilledChecklist checklist(NULL, request, NULL); + ACLFilledChecklist checklist(nullptr, request, al, nullptr); for (HeaderWithAclList::const_iterator hwa = headersAdd.begin(); hwa != headersAdd.end(); ++hwa) { if (!hwa->aclList || checklist.fastCheck(hwa->aclList).allowed()) { diff --git a/src/HttpReply.cc b/src/HttpReply.cc index c63fccdf303..16500cac586 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -510,17 +510,17 @@ HttpReply::expectingBody(const HttpRequestMethod& req_method, int64_t& theSize) } bool -HttpReply::receivedBodyTooLarge(HttpRequest& request, int64_t receivedSize) +HttpReply::receivedBodyTooLarge(HttpRequest& request, int64_t receivedSize, const AccessLogEntry::Pointer &al) { - calcMaxBodySize(request); + calcMaxBodySize(request, al); debugs(58, 3, HERE << receivedSize << " >? " << bodySizeMax); return bodySizeMax >= 0 && receivedSize > bodySizeMax; } bool -HttpReply::expectedBodyTooLarge(HttpRequest& request) +HttpReply::expectedBodyTooLarge(HttpRequest& request, const AccessLogEntry::Pointer &al) { - calcMaxBodySize(request); + calcMaxBodySize(request, al); debugs(58, 7, HERE << "bodySizeMax=" << bodySizeMax); if (bodySizeMax < 0) // no body size limit @@ -539,7 +539,7 @@ HttpReply::expectedBodyTooLarge(HttpRequest& request) } void -HttpReply::calcMaxBodySize(HttpRequest& request) const +HttpReply::calcMaxBodySize(HttpRequest& request, const AccessLogEntry::Pointer &al) const { // hack: -2 is used as "we have not calculated max body size yet" state if (bodySizeMax != -2) // already tried @@ -550,7 +550,7 @@ HttpReply::calcMaxBodySize(HttpRequest& request) const if (!Config.ReplyBodySize) return; - ACLFilledChecklist ch(NULL, &request, NULL); + ACLFilledChecklist ch(nullptr, &request, al, nullptr); // XXX: cont-cast becomes irrelevant when checklist is HttpReply::Pointer ch.reply = const_cast(this); HTTPMSGLOCK(ch.reply); diff --git a/src/HttpReply.h b/src/HttpReply.h index 6f0be1ee9ba..da5f78f67fa 100644 --- a/src/HttpReply.h +++ b/src/HttpReply.h @@ -91,12 +91,12 @@ class HttpReply: public Http::Message /** Checks whether received body exceeds known maximum size. * Requires a prior call to calcMaxBodySize(). */ - bool receivedBodyTooLarge(HttpRequest&, int64_t receivedBodySize); + bool receivedBodyTooLarge(HttpRequest&, int64_t receivedBodySize, const AccessLogEntry::Pointer &); /** Checks whether expected body exceeds known maximum size. * Requires a prior call to calcMaxBodySize(). */ - bool expectedBodyTooLarge(HttpRequest& request); + bool expectedBodyTooLarge(HttpRequest& request, const AccessLogEntry::Pointer &); int validatorsMatch (HttpReply const *other) const; @@ -147,7 +147,7 @@ class HttpReply: public Http::Message /** Calculates and stores maximum body size if needed. * Used by receivedBodyTooLarge() and expectedBodyTooLarge(). */ - void calcMaxBodySize(HttpRequest& request) const; + void calcMaxBodySize(HttpRequest& request, const AccessLogEntry::Pointer &al) const; String removeStaleWarningValues(const String &value); diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 2ef80b9e0c6..f1585c88030 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -116,7 +116,6 @@ HttpRequest::init() #endif rangeOffsetLimit = -2; //a value of -2 means not checked yet forcedBodyContinuation = false; - selfInitiated_ = false; if (const auto mgr = clientConnectionManager().valid()) { if (const auto port = mgr->port) @@ -257,8 +256,6 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) sources = aReq->sources; - selfInitiated_ = aReq->selfInitiated_; - return true; } @@ -619,7 +616,7 @@ HttpRequest::recordLookup(const Dns::LookupDetails &dns) } int64_t -HttpRequest::getRangeOffsetLimit() +HttpRequest::getRangeOffsetLimit(const AccessLogEntry::Pointer &al) { /* -2 is the starting value of rangeOffsetLimit. * If it is -2, that means we haven't checked it yet. @@ -629,7 +626,7 @@ HttpRequest::getRangeOffsetLimit() rangeOffsetLimit = 0; // default value for rangeOffsetLimit - ACLFilledChecklist ch(NULL, this, NULL); + ACLFilledChecklist ch(nullptr, this, al, nullptr); for (AclSizeLimit *l = Config.rangeOffsetLimit; l; l = l -> next) { /* if there is no ACL list or if the ACLs listed match use this limit value */ @@ -738,78 +735,26 @@ HttpRequest::prepareForDownloader(Downloader *aDownloader) header.putStr(Http::HdrType::HOST, url.host()); header.putTime(Http::HdrType::DATE, squid_curtime); downloader = aDownloader; - markAsSelfInitiated(); -} - -void -HttpRequest::markAsSelfInitiated() -{ - /* Internally created requests cannot have bodies today */ - content_length = 0; - http_ver = Http::ProtocolVersion(); - selfInitiated_ = true; } +// XXX: move this method to ALE CbcPointer & HttpRequest::clientConnectionManager() { - if (!selfInitiated_) - return masterXaction->clientConnectionManager(); - static CbcPointer noManager; - return noManager; -} - -const Ip::Address& -HttpRequest::clientAddr() const -{ - if (!selfInitiated_) // Optimization: Checking clientConnection() would be enough. - return clientConnection() ? clientConnection()->remote : client_addr; - return Ip::Address::Empty(); + return masterXaction->clientConnectionManager(); } -void -HttpRequest::prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr) -{ - client_addr = fromAddr; - my_addr = localAddr; -} - -const Ip::Address& -HttpRequest::myAddr() const -{ - if (!selfInitiated_) - return masterXaction->clientConnection() ? masterXaction->clientConnection()->local : my_addr; - return Ip::Address::Empty(); -} - -#if FOLLOW_X_FORWARDED_FOR -const Ip::Address& -HttpRequest::furthestClientAddress() const -{ - if (!selfInitiated_) - return indirect_client_addr.isKnown() ? indirect_client_addr : clientAddr(); - return Ip::Address::Empty(); -} - -void -HttpRequest::ignoreIndirectClientAddr() -{ - indirect_client_addr.setEmpty(); -} -#endif /* FOLLOW_X_FORWARDED_FOR */ - void HttpRequest::setInterceptionFlags(const AccessLogEntryPointer &al) { - if (const auto connection = clientConnection()) { + if (const auto connection = al->tcpClient) { flags.intercepted = ((connection->flags & COMM_INTERCEPTION) != 0); flags.interceptTproxy = ((connection->flags & COMM_TRANSPARENT) != 0 ) ; const auto port = clientConnectionManager()->port; const bool proxyProtocolPort = port ? port->flags.proxySurrogate : false; if (flags.interceptTproxy && !proxyProtocolPort) { if (Config.accessList.spoof_client_ip) { - ACLFilledChecklist *checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, connection->rfc931); - checklist->al = al; + ACLFilledChecklist *checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, al, connection->rfc931); checklist->syncAle(this, nullptr); flags.spoofClientIp = checklist->fastCheck().allowed(); delete checklist; @@ -823,7 +768,7 @@ HttpRequest::setInterceptionFlags(const AccessLogEntryPointer &al) bool HttpRequest::needCheckMissAccess() const { - return !(flags.internalReceived || url.getScheme() == AnyP::PROTO_CACHE_OBJECT || selfInitiated()); + return !(flags.internalReceived || url.getScheme() == AnyP::PROTO_CACHE_OBJECT); } char * @@ -875,18 +820,8 @@ FindListeningPortAddress(const HttpRequest *callerRequest, const AccessLogEntry return ip; /* handle non-intercepted cases that were not handled above */ - ip = FindListeningPortAddressInConn(request->clientConnection()); + ip = FindListeningPortAddressInConn(ale->tcpClient); if (!ip && ale) ip = FindListeningPortAddressInConn(ale->tcpClient); return ip; // may still be nil } - -Comm::ConnectionPointer -HttpRequest::clientConnection() const -{ - if (!selfInitiated_) - return masterXaction->clientConnection(); - static Comm::ConnectionPointer noConnection; - return noConnection; -} - diff --git a/src/HttpRequest.h b/src/HttpRequest.h index ea1177274b0..f78f0ed6690 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -149,42 +149,15 @@ class HttpRequest: public Http::Message int imslen; - /// mark this request as initiated by Squid (rather than received on a client connection) - void markAsSelfInitiated(); - /// whether this request was initiated by Squid (rather than received on a client connection) bool selfInitiated() const { return selfInitiated_; } /// supply Downloader-specific settings void prepareForDownloader(Downloader *); - /// specify addresses manually when lacking client connection - void prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr); - - /// the source address of the client connection - const Ip::Address& clientAddr() const; - - /// the local address of the client connection - const Ip::Address& myAddr() const; - /// the client connection manager of the underlying transaction, if any CbcPointer &clientConnectionManager(); - /// the client connection of the underlying transaction - /// \retval * client connection that initiated this request (if any) - /// \retval nil for selfInitiated() requests - Comm::ConnectionPointer clientConnection() const; - -#if FOLLOW_X_FORWARDED_FOR - /// Indirect client address, if available, otherwise clientAddr(). - const Ip::Address& furthestClientAddress() const; - - void indirectClientAddr(const Ip::Address &addr) { indirect_client_addr = addr; } - - /// forces furthestClientAddress() to return a direct client address - void ignoreIndirectClientAddr(); -#endif - HierarchyLogEntry hier; int dnsWait; ///< sum of DNS lookup delays in milliseconds, for %dt @@ -259,7 +232,7 @@ class HttpRequest: public Http::Message /// forgets about the cached Range header (for a reason) void ignoreRange(const char *reason); - int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */ + int64_t getRangeOffsetLimit(const AccessLogEntry::Pointer &); /* the result of this function gets cached in rangeOffsetLimit */ /// \returns existing non-empty transaction annotations, /// creates and returns empty annotations otherwise diff --git a/src/Notes.cc b/src/Notes.cc index 1e0232c17f0..ff3adf2eb96 100644 --- a/src/Notes.cc +++ b/src/Notes.cc @@ -68,8 +68,7 @@ Note::addValue(const char *value, const bool quoted, const char *descr, const Va bool Note::match(HttpRequest *request, HttpReply *reply, const AccessLogEntry::Pointer &al, SBuf &matched) { - ACLFilledChecklist ch(nullptr, request, nullptr); - ch.al = al; + ACLFilledChecklist ch(nullptr, request, al, nullptr); ch.reply = reply; ch.syncAle(request, nullptr); if (reply) diff --git a/src/PeerPoolMgr.cc b/src/PeerPoolMgr.cc index 3c5d0799ae2..ba9a9c64645 100644 --- a/src/PeerPoolMgr.cc +++ b/src/PeerPoolMgr.cc @@ -222,8 +222,8 @@ PeerPoolMgr::openNewConnection() conn->remote.port(peer->http_port); conn->peerType = STANDBY_POOL; // should be reset by peerSelect() conn->setPeer(peer); - getOutgoingAddress(request.getRaw(), conn); - GetMarkingsToServer(request.getRaw(), *conn); + getOutgoingAddress(request.getRaw(), conn, nullptr); + GetMarkingsToServer(request.getRaw(), *conn, nullptr); const int ctimeout = peerConnectTimeout(peer); typedef CommCbMemFunT Dialer; diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index b5a47665c7b..d0761f2c28f 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -238,7 +238,6 @@ asnCacheStart(int as) asState->request = new HttpRequest(mx); asState->request->url = whoisUrl; asState->request->method = Http::METHOD_GET; - asState->request->markAsSelfInitiated(); // XXX: performance regression, c_str() reallocates const auto asres = xstrdup(whoisUrl.absolute().c_str()); diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 7dd59b855b1..cc46637a060 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -153,7 +153,7 @@ void ACLFilledChecklist::preferIndirectAddr() { assert(request); - client_addr = request->furthestClientAddress(); + client_addr = al->furthestClientAddress(); } #endif @@ -161,7 +161,7 @@ void ACLFilledChecklist::forceDirectAddr() { assert(request); - client_addr = request->clientAddr(); + client_addr = al->clientAddr(); } int @@ -219,7 +219,7 @@ ACLFilledChecklist::markSourceDomainChecked() * *not* delete the list. After the callback function returns, * checkCallback() will delete the list (i.e., self). */ -ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_request, const char *ident): +ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_request, const AccessLogEntry::Pointer &ale, const char *ident): dst_rdns(NULL), request(NULL), reply(NULL), @@ -232,6 +232,7 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re #if USE_OPENSSL sslErrors(NULL), #endif + al(ale), requestErrorType(ERR_MAX), connectionManager_(nullptr), fd_(-1), @@ -256,7 +257,7 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) HTTPMSGLOCK(request); setClientConnectionDetails(request->clientConnectionManager().get()); if (!clientConnectionManager()) // could not take the connection from the connection manager - setClientConnection(request->clientConnection()); + setClientConnection(al->tcpClient); } } @@ -275,11 +276,11 @@ ACLFilledChecklist::setClientSideAddresses() if (request) { #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.acl_uses_indirect_client) - InitializeClientAddress(client_addr, request->furthestClientAddress()); + InitializeClientAddress(client_addr, al->furthestClientAddress()); else #endif - InitializeClientAddress(client_addr, request->clientAddr()); - InitializeClientAddress(my_addr, request->myAddr()); + InitializeClientAddress(client_addr, al->clientAddr()); + InitializeClientAddress(my_addr, al->myAddr()); } else if (clientConnection_) { InitializeClientAddress(client_addr, clientConnection_->remote); InitializeClientAddress(my_addr, clientConnection_->local); diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index dd07b8601fc..0848eea6914 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -36,7 +36,7 @@ class ACLFilledChecklist: public ACLChecklist public: ACLFilledChecklist(); - ACLFilledChecklist(const acl_access *, HttpRequest *, const char *ident = nullptr); + ACLFilledChecklist(const acl_access *, HttpRequest *, const AccessLogEntry::Pointer &, const char *ident = nullptr); ~ACLFilledChecklist(); /// Configure client request-related fields for the first time. diff --git a/src/adaptation/AccessCheck.cc b/src/adaptation/AccessCheck.cc index 8d847769d35..959b920f712 100644 --- a/src/adaptation/AccessCheck.cc +++ b/src/adaptation/AccessCheck.cc @@ -131,10 +131,9 @@ Adaptation::AccessCheck::checkCandidates() if (AccessRule *r = FindRule(topCandidate())) { /* BUG 2526: what to do when r->acl is empty?? */ // XXX: we do not have access to conn->rfc931 here. - acl_checklist = new ACLFilledChecklist(r->acl, filter.request, dash_str); + acl_checklist = new ACLFilledChecklist(r->acl, filter.request, filter.al, dash_str); if ((acl_checklist->reply = filter.reply)) HTTPMSGLOCK(acl_checklist->reply); - acl_checklist->al = filter.al; acl_checklist->syncAle(filter.request, nullptr); acl_checklist->nonBlockingCheck(AccessCheckCallbackWrapper, this); return; diff --git a/src/adaptation/ecap/XactionRep.cc b/src/adaptation/ecap/XactionRep.cc index bfe66d4d3c1..59c0e4ae927 100644 --- a/src/adaptation/ecap/XactionRep.cc +++ b/src/adaptation/ecap/XactionRep.cc @@ -131,10 +131,10 @@ Adaptation::Ecap::XactionRep::clientIpValue() const Ip::Address client_addr; #if FOLLOW_X_FORWARDED_FOR if (TheConfig.use_indirect_client) - client_addr = request->furthestClientAddress(); + client_addr = al->furthestClientAddress(); else #endif - client_addr = request->clientAddr(); + client_addr = al->clientAddr(); if (client_addr.isKnown()) { char ntoabuf[MAX_IPSTRLEN] = ""; client_addr.toStr(ntoabuf,MAX_IPSTRLEN); diff --git a/src/adaptation/icap/Launcher.cc b/src/adaptation/icap/Launcher.cc index 563ab4e924e..ea63995cde2 100644 --- a/src/adaptation/icap/Launcher.cc +++ b/src/adaptation/icap/Launcher.cc @@ -141,7 +141,7 @@ bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info return true; ACLFilledChecklist *cl = - new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, dash_str); + new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, info.al, dash_str); cl->reply = info.icapReply; HTTPMSGLOCK(cl->reply); @@ -153,11 +153,12 @@ bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info /* ICAPXactAbortInfo */ Adaptation::Icap::XactAbortInfo::XactAbortInfo(HttpRequest *anIcapRequest, - HttpReply *anIcapReply, bool beRetriable, bool beRepeatable): + HttpReply *anIcapReply, bool beRetriable, bool beRepeatable, const AccessLogEntry::Pointer &ale): icapRequest(anIcapRequest), icapReply(anIcapReply), isRetriable(beRetriable), - isRepeatable(beRepeatable) + isRepeatable(beRepeatable), + al(ale) { if (icapRequest) HTTPMSGLOCK(icapRequest); @@ -169,7 +170,8 @@ Adaptation::Icap::XactAbortInfo::XactAbortInfo(const Adaptation::Icap::XactAbort icapRequest(i.icapRequest), icapReply(i.icapReply), isRetriable(i.isRetriable), - isRepeatable(i.isRepeatable) + isRepeatable(i.isRepeatable), + al(i.al) { if (icapRequest) HTTPMSGLOCK(icapRequest); diff --git a/src/adaptation/icap/Launcher.h b/src/adaptation/icap/Launcher.h index c3c24d1ed4a..a0268e837be 100644 --- a/src/adaptation/icap/Launcher.h +++ b/src/adaptation/icap/Launcher.h @@ -83,7 +83,7 @@ class XactAbortInfo { public: XactAbortInfo(HttpRequest *anIcapRequest, HttpReply *anIcapReply, - bool beRetriable, bool beRepeatable); + bool beRetriable, bool beRepeatable, const AccessLogEntry::Pointer &); XactAbortInfo(const XactAbortInfo &); ~XactAbortInfo(); @@ -95,6 +95,7 @@ class XactAbortInfo HttpReply *icapReply; bool isRetriable; bool isRepeatable; + AccessLogEntry::Pointer al; private: XactAbortInfo &operator =(const XactAbortInfo &); // undefined diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index 15af40c5c78..e551f4d3834 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1331,7 +1331,7 @@ void Adaptation::Icap::ModXact::finalizeLogInfo() const Adaptation::Icap::ServiceRep &s = service(); al.icap.reqMethod = s.cfg().method; - al.cache.caddr = virgin_request_->clientAddr(); + al.cache.caddr = al.clientAddr(); // XXX: should we use the virgin client addr (as the old code did)? al.request = virgin_request_; HTTPMSGLOCK(al.request); @@ -1475,14 +1475,14 @@ void Adaptation::Icap::ModXact::makeRequestHeaders(MemBuf &buf) makeAllowHeader(buf); - if (TheConfig.send_client_ip && request) { + if (TheConfig.send_client_ip) { Ip::Address client_addr; #if FOLLOW_X_FORWARDED_FOR if (TheConfig.use_indirect_client) - client_addr = request->furthestClientAddress(); + client_addr = al.furthestClientAddress(); else #endif - client_addr = request->clientAddr(); + client_addr = al.clientAddr(); if (client_addr.isKnown()) buf.appendf("X-Client-IP: %s\r\n", client_addr.toStr(ntoabuf,MAX_IPSTRLEN)); } diff --git a/src/adaptation/icap/Xaction.cc b/src/adaptation/icap/Xaction.cc index c91e7e1021b..8f7e541c4bc 100644 --- a/src/adaptation/icap/Xaction.cc +++ b/src/adaptation/icap/Xaction.cc @@ -217,7 +217,7 @@ Adaptation::Icap::Xaction::dnsLookupDone(const ipcache_addrs *ia) connection = new Comm::Connection; connection->remote = ia->current(); connection->remote.port(s.cfg().port); - getOutgoingAddress(NULL, connection); + getOutgoingAddress(nullptr, connection, nullptr); // TODO: service bypass status may differ from that of a transaction typedef CommCbMemFunT ConnectDialer; @@ -620,7 +620,7 @@ void Adaptation::Icap::Xaction::tellQueryAborted() { if (theInitiator.set()) { Adaptation::Icap::XactAbortInfo abortInfo(icapRequest, icapReply.getRaw(), - retriable(), repeatable()); + retriable(), repeatable(), alep); Launcher *launcher = dynamic_cast(theInitiator.get()); // launcher may be nil if initiator is invalid CallJobHere1(91,5, CbcPointer(launcher), diff --git a/src/adaptation/icap/icap_log.cc b/src/adaptation/icap/icap_log.cc index 5a9c1102998..e69844b1d11 100644 --- a/src/adaptation/icap/icap_log.cc +++ b/src/adaptation/icap/icap_log.cc @@ -60,7 +60,7 @@ icapLogRotate() void icapLogLog(AccessLogEntry::Pointer &al) { if (IcapLogfileStatus == LOG_ENABLE) { - ACLFilledChecklist checklist(NULL, al->adapted_request, NULL); + ACLFilledChecklist checklist(nullptr, al->adapted_request, al, nullptr); if (al->reply) { checklist.reply = al->reply; HTTPMSGLOCK(checklist.reply); diff --git a/src/auth/UserRequest.cc b/src/auth/UserRequest.cc index 48cdbd19071..c0ddf581f02 100644 --- a/src/auth/UserRequest.cc +++ b/src/auth/UserRequest.cc @@ -219,11 +219,11 @@ Auth::UserRequest::connLastHeader() * This is basically a handle approach. */ static void -authenticateAuthenticateUser(Auth::UserRequest::Pointer auth_user_request, HttpRequest * request, ConnStateData * conn, Http::HdrType type) +authenticateAuthenticateUser(Auth::UserRequest::Pointer auth_user_request, HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &al) { assert(auth_user_request.getRaw() != NULL); - auth_user_request->authenticate(request, conn, type); + auth_user_request->authenticate(request, conn, type, al); } static Auth::UserRequest::Pointer @@ -383,7 +383,7 @@ Auth::UserRequest::authenticate(Auth::UserRequest::Pointer * auth_user_request, if (!authenticateUserAuthenticated(*auth_user_request)) { /* User not logged in. Try to log them in */ - authenticateAuthenticateUser(*auth_user_request, request, conn, headertype); + authenticateAuthenticateUser(*auth_user_request, request, conn, headertype, al); switch ((*auth_user_request)->direction()) { @@ -462,10 +462,10 @@ Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer * } static Auth::ConfigVector & -schemesConfig(HttpRequest *request, HttpReply *rep) +schemesConfig(HttpRequest *request, HttpReply *rep, const AccessLogEntryPointer &al) { if (!Auth::TheConfig.schemeLists.empty() && Auth::TheConfig.schemeAccess) { - ACLFilledChecklist ch(NULL, request, NULL); + ACLFilledChecklist ch(nullptr, request, al, nullptr); ch.reply = rep; HTTPMSGLOCK(ch.reply); const auto answer = ch.fastCheck(Auth::TheConfig.schemeAccess); @@ -476,7 +476,7 @@ schemesConfig(HttpRequest *request, HttpReply *rep) } void -Auth::UserRequest::AddReplyAuthHeader(HttpReply * rep, Auth::UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal) +Auth::UserRequest::AddReplyAuthHeader(HttpReply * rep, Auth::UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal, const AccessLogEntryPointer &al) /* send the auth types we are configured to support (and have compiled in!) */ { Http::HdrType type; @@ -512,7 +512,7 @@ Auth::UserRequest::AddReplyAuthHeader(HttpReply * rep, Auth::UserRequest::Pointe auth_user_request->user()->config->fixHeader(auth_user_request, rep, type, request); else { /* call each configured & running auth scheme */ - Auth::ConfigVector &configs = schemesConfig(request, rep); + Auth::ConfigVector &configs = schemesConfig(request, rep, al); for (auto *scheme : configs) { if (scheme->active()) { if (auth_user_request != NULL && auth_user_request->scheme()->type() == scheme->type()) diff --git a/src/auth/UserRequest.h b/src/auth/UserRequest.h index 7f0f0b64bd4..53b3ea80f96 100644 --- a/src/auth/UserRequest.h +++ b/src/auth/UserRequest.h @@ -126,7 +126,7 @@ class UserRequest : public RefCountable */ bool valid() const; - virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type) = 0; + virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &al) = 0; /* template method - what needs to be done next? advertise schemes, challenge, handle error, nothing? */ virtual Direction module_direction() = 0; @@ -165,7 +165,7 @@ class UserRequest : public RefCountable static AuthAclState tryToAuthenticateAndSetAuthUser(UserRequest::Pointer *aUR, Http::HdrType, HttpRequest *, ConnStateData *, const Ip::Address &, AccessLogEntry::Pointer &); /// Add the appropriate [Proxy-]Authenticate header to the given reply - static void AddReplyAuthHeader(HttpReply * rep, UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal); + static void AddReplyAuthHeader(HttpReply * rep, UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal, const AccessLogEntryPointer &al); /** Start an asynchronous helper lookup to verify the user credentials * diff --git a/src/auth/basic/UserRequest.cc b/src/auth/basic/UserRequest.cc index 2b3fa53d78e..9846af9840d 100644 --- a/src/auth/basic/UserRequest.cc +++ b/src/auth/basic/UserRequest.cc @@ -49,7 +49,7 @@ Auth::Basic::UserRequest::credentialsStr() /* log a basic user in */ void -Auth::Basic::UserRequest::authenticate(HttpRequest *, ConnStateData *, Http::HdrType) +Auth::Basic::UserRequest::authenticate(HttpRequest *, ConnStateData *, Http::HdrType, AccessLogEntry::Pointer &) { assert(user() != NULL); diff --git a/src/auth/basic/UserRequest.h b/src/auth/basic/UserRequest.h index dcb168ebfca..60557cff04a 100644 --- a/src/auth/basic/UserRequest.h +++ b/src/auth/basic/UserRequest.h @@ -33,7 +33,7 @@ class UserRequest : public Auth::UserRequest virtual ~UserRequest() { assert(LockCount()==0); } virtual int authenticated() const; - virtual void authenticate(HttpRequest * request, ConnStateData *conn, Http::HdrType type); + virtual void authenticate(HttpRequest * request, ConnStateData *conn, Http::HdrType type, AccessLogEntry::Pointer &); virtual Auth::Direction module_direction(); virtual void startHelperLookup(HttpRequest * request, AccessLogEntry::Pointer &al, AUTHCB *, void *); virtual const char *credentialsStr(); diff --git a/src/auth/digest/UserRequest.cc b/src/auth/digest/UserRequest.cc index 78b461910ea..ac184a238cc 100644 --- a/src/auth/digest/UserRequest.cc +++ b/src/auth/digest/UserRequest.cc @@ -78,7 +78,7 @@ Auth::Digest::UserRequest::credentialsStr() /** log a digest user in */ void -Auth::Digest::UserRequest::authenticate(HttpRequest * request, ConnStateData *, Http::HdrType) +Auth::Digest::UserRequest::authenticate(HttpRequest * request, ConnStateData *, Http::HdrType, AccessLogEntry::Pointer &al) { HASHHEX SESSIONKEY; HASHHEX HA2 = ""; @@ -148,13 +148,13 @@ Auth::Digest::UserRequest::authenticate(HttpRequest * request, ConnStateData *, const char *useragent = request->header.getStr(Http::HdrType::USER_AGENT); static Ip::Address last_broken_addr; - if (last_broken_addr != request->clientAddr()) { + if (last_broken_addr != al->clientAddr()) { debugs(29, DBG_IMPORTANT, "Digest POST bug detected from " << - request->clientAddr() << " using '" << + al->clientAddr() << " using '" << (useragent ? useragent : "-") << "'. Please upgrade browser. See Bug #630 for details."); - last_broken_addr = request->clientAddr(); + last_broken_addr = al->clientAddr(); } } } else { diff --git a/src/auth/digest/UserRequest.h b/src/auth/digest/UserRequest.h index 78e5ee10c20..ad31f3c6df0 100644 --- a/src/auth/digest/UserRequest.h +++ b/src/auth/digest/UserRequest.h @@ -34,7 +34,7 @@ class UserRequest : public Auth::UserRequest virtual ~UserRequest(); virtual int authenticated() const; - virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type); + virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &al); virtual Direction module_direction(); virtual void addAuthenticationInfoHeader(HttpReply * rep, int accel); #if WAITING_FOR_TE diff --git a/src/auth/negotiate/UserRequest.cc b/src/auth/negotiate/UserRequest.cc index 568fd33e5a0..c5b8e4007c6 100644 --- a/src/auth/negotiate/UserRequest.cc +++ b/src/auth/negotiate/UserRequest.cc @@ -182,7 +182,7 @@ Auth::Negotiate::UserRequest::releaseAuthServer() } void -Auth::Negotiate::UserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, Http::HdrType type) +Auth::Negotiate::UserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &) { /* Check that we are in the client side, where we can generate * auth challenges */ diff --git a/src/auth/negotiate/UserRequest.h b/src/auth/negotiate/UserRequest.h index 66d90403356..29750bc7fa4 100644 --- a/src/auth/negotiate/UserRequest.h +++ b/src/auth/negotiate/UserRequest.h @@ -32,7 +32,7 @@ class UserRequest : public Auth::UserRequest UserRequest(); virtual ~UserRequest(); virtual int authenticated() const; - virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type); + virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &); virtual Direction module_direction(); virtual void startHelperLookup(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB *, void *); virtual const char *credentialsStr(); diff --git a/src/auth/ntlm/UserRequest.cc b/src/auth/ntlm/UserRequest.cc index 0115d70f0ad..0889998c2e7 100644 --- a/src/auth/ntlm/UserRequest.cc +++ b/src/auth/ntlm/UserRequest.cc @@ -175,7 +175,7 @@ Auth::Ntlm::UserRequest::releaseAuthServer() } void -Auth::Ntlm::UserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, Http::HdrType type) +Auth::Ntlm::UserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &) { /* Check that we are in the client side, where we can generate * auth challenges */ diff --git a/src/auth/ntlm/UserRequest.h b/src/auth/ntlm/UserRequest.h index 170dbf05eeb..56e3de7a428 100644 --- a/src/auth/ntlm/UserRequest.h +++ b/src/auth/ntlm/UserRequest.h @@ -32,7 +32,7 @@ class UserRequest : public Auth::UserRequest UserRequest(); virtual ~UserRequest(); virtual int authenticated() const; - virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type); + virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &); virtual Auth::Direction module_direction(); virtual void startHelperLookup(HttpRequest *req, AccessLogEntry::Pointer &al, AUTHCB *, void *); virtual const char *credentialsStr(); diff --git a/src/client_side.cc b/src/client_side.cc index e4fe7e264e0..9361be9af7e 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -436,7 +436,8 @@ ClientHttpRequest::logRequest() al->syncNotes(request); } - ACLFilledChecklist checklist(NULL, request, NULL); + ACLFilledChecklist checklist(nullptr, request, al, nullptr); + // no need checklist.syncAle(): already synced if (al->reply) { checklist.reply = al->reply; @@ -448,15 +449,13 @@ ClientHttpRequest::logRequest() al->adapted_request = request; HTTPMSGLOCK(al->adapted_request); } - // no need checklist.syncAle(): already synced - checklist.al = al; + checklist.setClientConnectionDetails(getConn()); accessLogLog(al, &checklist); bool updatePerformanceCounters = true; if (Config.accessList.stats_collection) { - ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, NULL); - statsCheck.al = al; + ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, al, nullptr); statsCheck.setClientConnectionDetails(getConn()); if (al->reply) { statsCheck.reply = al->reply; @@ -1515,8 +1514,7 @@ bool ConnStateData::serveDelayedError(Http::Stream *context) bool allowDomainMismatch = false; if (Config.ssl_client.cert_error) { - ACLFilledChecklist check(Config.ssl_client.cert_error, request, dash_str); - check.al = http->al; + ACLFilledChecklist check(Config.ssl_client.cert_error, request, http->al, dash_str); check.setClientConnectionDetails(this); check.sslErrors = new Security::CertErrors(Security::CertError(SQUID_X509_V_ERR_DOMAIN_MISMATCH, srvCert)); check.syncAle(request, http->log_uri); @@ -1561,8 +1559,8 @@ bool clientTunnelOnError(ConnStateData *conn, Http::StreamPointer &context, HttpRequest::Pointer &request, const HttpRequestMethod& method, err_type requestError) { if (conn->mayTunnelUnsupportedProto()) { - ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request.getRaw(), nullptr); - checklist.al = (context && context->http) ? context->http->al : nullptr; + const auto ale = (context && context->http) ? context->http->al : nullptr; + ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request.getRaw(), ale, nullptr); checklist.requestErrorType = requestError; checklist.setClientConnectionDetails(conn); ClientHttpRequest *http = context ? context->http : nullptr; @@ -1809,7 +1807,7 @@ ConnStateData::proxyProtocolValidateClient() if (!Config.accessList.proxyProtocol) return proxyProtocolError("PROXY client not permitted by default ACL"); - ACLFilledChecklist ch(Config.accessList.proxyProtocol, NULL, clientConnection->rfc931); + ACLFilledChecklist ch(Config.accessList.proxyProtocol, nullptr, nullptr, clientConnection->rfc931); ch.setClientConnectionDetails(this); if (!ch.fastCheck().allowed()) @@ -2252,7 +2250,7 @@ ConnStateData::whenClientIpKnown() #if USE_IDENT if (Ident::TheConfig.identLookup) { - ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, NULL, NULL); + ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, nullptr, nullptr, nullptr); identChecklist.setClientConnectionDetails(this); if (identChecklist.fastCheck().allowed()) Ident::Start(clientConnection, clientIdentDone, this); @@ -2269,7 +2267,7 @@ ConnStateData::whenClientIpKnown() const auto &pools = ClientDelayPools::Instance()->pools; if (pools.size()) { - ACLFilledChecklist ch(NULL, NULL, NULL); + ACLFilledChecklist ch(nullptr, nullptr, nullptr, nullptr); ch.setClientConnectionDetails(this); // TODO: we check early to limit error response bandwith but we @@ -2616,7 +2614,7 @@ ConnStateData::postHttpsAccept() request->url.host(clientConnection->local.toStr(ip, sizeof(ip))); request->url.port(clientConnection->local.port()); - ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, NULL); + ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, nullptr, nullptr); acl_checklist->setClientConnectionDetails(this); // Build a local AccessLogEntry to allow requiresAle() acls work acl_checklist->al = new AccessLogEntry; @@ -2703,7 +2701,7 @@ void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &cer if (X509 *mimicCert = sslServerBump->serverCert.get()) certProperties.mimicCert.resetAndLock(mimicCert); - ACLFilledChecklist checklist(NULL, sslServerBump->request.getRaw(), + ACLFilledChecklist checklist(nullptr, sslServerBump->request.getRaw(), nullptr, // XXX clientConnection != NULL ? clientConnection->rfc931 : dash_str); checklist.setClientConnectionDetails(this); checklist.sslErrors = cbdataReference(sslServerBump->sslErrors()); @@ -3094,8 +3092,7 @@ ConnStateData::startPeekAndSplice() sslServerBump->step = Ssl::bumpStep2; // Run a accessList check to check if want to splice or continue bumping - ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, sslServerBump->request.getRaw(), nullptr); - acl_checklist->al = http ? http->al : nullptr; + ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, sslServerBump->request.getRaw(), http ? http->al : nullptr, nullptr); acl_checklist->setClientConnectionDetails(this); //acl_checklist->src_addr = params.conn->remote; //acl_checklist->my_addr = s->s; @@ -3536,7 +3533,7 @@ varyEvaluateMatch(StoreEntry * entry, HttpRequest * request) ACLFilledChecklist * clientAclChecklistCreate(const acl_access * acl, ClientHttpRequest * http) { - const auto checklist = new ACLFilledChecklist(acl, nullptr, nullptr); + const auto checklist = new ACLFilledChecklist(acl, nullptr, http->al, nullptr); clientAclChecklistFill(*checklist, http); return checklist; } @@ -3545,9 +3542,8 @@ void clientAclChecklistFill(ACLFilledChecklist &checklist, ClientHttpRequest *http) { checklist.setRequest(http->request); - checklist.al = http->al; checklist.syncAle(http->request, http->log_uri); - + checklist.al = http->al; // TODO: If http->getConn is always http->request->clientConnectionManager, // then call setIdent() inside checklist.setRequest(). Otherwise, restore // USE_IDENT lost in commit 94439e4. diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index c1e33581842..9cf23b8b9e0 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -1319,7 +1319,7 @@ clientReplyContext::replyStatus() } // XXX: Should this be checked earlier? We could return above w/o checking. - if (reply->receivedBodyTooLarge(*http->request, http->out.offset - 4096)) { + if (reply->receivedBodyTooLarge(*http->request, http->out.offset - 4096, http->al)) { /* 4096 is a margin for the HTTP headers included in out.offset */ debugs(88, 5, "clientReplyStatus: client reply body is too large"); return STREAM_FAILED; @@ -1539,9 +1539,9 @@ clientReplyContext::buildReplyHeader() * data on 407/401 responses, and do not check the accel state on 401/407 * responses */ - Auth::UserRequest::AddReplyAuthHeader(reply, request->auth_user_request, request, 0, 1); + Auth::UserRequest::AddReplyAuthHeader(reply, request->auth_user_request, request, 0, 1, http->al); } else if (request->auth_user_request != NULL) - Auth::UserRequest::AddReplyAuthHeader(reply, request->auth_user_request, request, http->flags.accel, 0); + Auth::UserRequest::AddReplyAuthHeader(reply, request->auth_user_request, request, http->flags.accel, 0, http->al); #endif /* Append X-Cache */ @@ -2030,7 +2030,7 @@ clientReplyContext::processReplyAccess () } /** Check for reply to big error */ - if (reply->expectedBodyTooLarge(*http->request)) { + if (reply->expectedBodyTooLarge(*http->request, http->al)) { sendBodyTooLargeError(); return; } diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 952f8cac9cd..e3acc28f38d 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -375,8 +375,6 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre * objects ? */ - request->markAsSelfInitiated(); - http->initRequest(request); /* optional - skip the access check ? */ @@ -466,7 +464,7 @@ clientFollowXForwardedForCheck(Acl::Answer answer, void *data) --l; asciiaddr = p+l; if ((addr = asciiaddr)) { - request->indirectClientAddr(addr); + http->al->indirectClientAddr(addr); request->x_forwarded_for_iterator.cut(l); calloutContext->acl_checklist = clientAclChecklistCreate(Config.accessList.followXFF, http); /* override the default src_addr tested if we have to go deeper than one level into XFF */ @@ -482,15 +480,15 @@ clientFollowXForwardedForCheck(Acl::Answer answer, void *data) * Ensure that the access log shows the indirect client * instead of the direct client. */ - http->al->cache.caddr = request->furthestClientAddress(); + http->al->cache.caddr = http->al->furthestClientAddress(); if (ConnStateData *conn = http->getConn()) - conn->log_addr = request->furthestClientAddress(); + conn->log_addr = http->al->furthestClientAddress(); } request->x_forwarded_for_iterator.clean(); request->flags.done_follow_x_forwarded_for = true; if (answer.conflicted()) { - debugs(28, DBG_CRITICAL, "ERROR: Processing X-Forwarded-For. Stopping at IP address: " << request->furthestClientAddress()); + debugs(28, DBG_CRITICAL, "ERROR: Processing X-Forwarded-For. Stopping at IP address: " << http->al->furthestClientAddress()); } /* process actual access ACL as normal. */ @@ -672,7 +670,7 @@ ClientRequestContext::clientAccessCheck() http->request->header.has(Http::HdrType::X_FORWARDED_FOR)) { /* we always trust the direct client address for actual use */ - http->request->ignoreIndirectClientAddr(); + http->al->ignoreIndirectClientAddr(); /* setup the XFF iterator for processing */ http->request->x_forwarded_for_iterator = http->request->header.getList(Http::HdrType::X_FORWARDED_FOR); @@ -1807,8 +1805,7 @@ ClientHttpRequest::doCallouts() // Set appropriate MARKs and CONNMARKs if needed. if (getConn() && Comm::IsConnOpen(getConn()->clientConnection)) { - ACLFilledChecklist ch(nullptr, request, nullptr); - ch.al = calloutContext->http->al; + ACLFilledChecklist ch(nullptr, request, calloutContext->http->al, nullptr); ch.setClientConnectionDetails(getConn()); ch.syncAle(request, log_uri); diff --git a/src/clients/Client.cc b/src/clients/Client.cc index 776fa3f3d31..e1f022d9f74 100644 --- a/src/clients/Client.cc +++ b/src/clients/Client.cc @@ -520,7 +520,7 @@ Client::blockCaching() if (const Acl::Tree *acl = Config.accessList.storeMiss) { // This relatively expensive check is not in StoreEntry::checkCachable: // That method lacks HttpRequest and may be called too many times. - ACLFilledChecklist ch(acl, originalRequest().getRaw()); + ACLFilledChecklist ch(acl, originalRequest().getRaw(), fwd->al, nullptr); ch.reply = const_cast(entry->getReply()); // ACLFilledChecklist API bug HTTPMSGLOCK(ch.reply); if (!ch.fastCheck().allowed()) { // when in doubt, block @@ -911,7 +911,7 @@ Client::noteAdaptationAclCheckDone(Adaptation::ServiceGroupPointer group) // TODO: Should non-ICAP and ICAP REPMOD pre-cache paths check this? // That check now only happens on REQMOD pre-cache and REPMOD post-cache, in processReplyAccess(). - if (virginReply()->expectedBodyTooLarge(*request)) { + if (virginReply()->expectedBodyTooLarge(*request, fwd->al)) { sendBodyIsTooLargeError(); return; } diff --git a/src/clients/FtpClient.cc b/src/clients/FtpClient.cc index 34a6f448801..f8878ee5ed5 100644 --- a/src/clients/FtpClient.cc +++ b/src/clients/FtpClient.cc @@ -704,7 +704,7 @@ Ftp::Client::sendPassive() default: { bool doEpsv = true; if (Config.accessList.ftp_epsv) { - ACLFilledChecklist checklist(Config.accessList.ftp_epsv, fwd->request, NULL); + ACLFilledChecklist checklist(Config.accessList.ftp_epsv, fwd->request, fwd->al, nullptr); doEpsv = checklist.fastCheck().allowed(); } if (!doEpsv) { diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index 0ab9413fca5..1b6e0c735c8 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -262,9 +262,8 @@ logAcceptError(const Comm::ConnectionPointer &conn) al->tcpClient = conn; al->url = "error:accept-client-connection"; al->setVirginUrlForMissingRequest(al->url); - ACLFilledChecklist ch(nullptr, nullptr, nullptr); + ACLFilledChecklist ch(nullptr, nullptr, al, nullptr); ch.setClientConnectionDetails(nullptr, conn); - ch.al = al; accessLogLog(al, &ch); } diff --git a/src/errorpage.cc b/src/errorpage.cc index f2fe289a305..55c973f6104 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -688,7 +688,7 @@ ErrorState::ErrorState(err_type t, Http::StatusCode status, HttpRequest * req, c if (req) { request = req; - src_addr = req->clientAddr(); + src_addr = ale->clientAddr(); } ale = anAle; @@ -703,7 +703,7 @@ ErrorState::ErrorState(HttpRequest * req, HttpReply *errorReply) : if (req) { request = req; - src_addr = req->clientAddr(); + src_addr = ale->clientAddr(); } } diff --git a/src/format/Format.cc b/src/format/Format.cc index 566b8e8bee7..941454e03a0 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -427,7 +427,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_CLIENT_PORT: if (al->request) { - if (const auto port = al->request->clientAddr().port()) { + if (const auto port = al->clientAddr().port()) { outint = port; doint = 1; } diff --git a/src/htcp.cc b/src/htcp.cc index 2f651c8678b..1822d5a8e99 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -122,6 +122,9 @@ struct _htcpAuthHeader { static Comm::ConnectionPointer htcpOutgoingConn; static Comm::ConnectionPointer htcpIncomingConn; +static void +htcpSyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const int opcode, const char *url); + class htcpSpecifier : public RefCountable, public StoreClient { MEMPROXY_CLASS(htcpSpecifier); @@ -134,11 +137,11 @@ class htcpSpecifier : public RefCountable, public StoreClient const Ip::Address &from() const { assert(request); - return request->clientAddr(); + return al->clientAddr(); } - void setAddresses(Ip::Address &from) { - assert(request); - request->prepareForConnectionlessProtocol(from, htcpIncomingConn->local); + void setAddresses(Ip::Address &fromAddr) { + htcpSyncAle(al, fromAddr, dhdr->opcode, uri); + al->prepareForConnectionlessProtocol(fromAddr, htcpIncomingConn->local); } void setDataHeader(htcpDataHeader *aDataHeader) { dhdr = aDataHeader; @@ -800,7 +803,7 @@ htcpAccessAllowed(acl_access * acl, const htcpSpecifier::Pointer &s, Ip::Address if (!acl) return false; - ACLFilledChecklist checklist(acl, s->request.getRaw(), nullptr); + ACLFilledChecklist checklist(acl, s->request.getRaw(), s->al, nullptr); return checklist.fastCheck().allowed(); } @@ -1194,8 +1197,8 @@ htcpHandleClr(htcpDataHeader * hdr, char *buf, int sz, Ip::Address &from) htcpLogHtcp(from, hdr->opcode, LOG_UDP_INVALID, dash_str, nullptr); return; } else { - s->setAddresses(from); s->setDataHeader(hdr); + s->setAddresses(from); } if (!s->request) { diff --git a/src/http.cc b/src/http.cc index bf40e88399e..973cb646d23 100644 --- a/src/http.cc +++ b/src/http.cc @@ -802,8 +802,7 @@ HttpStateData::handle1xx(HttpReply *reply) #if USE_HTTP_VIOLATIONS // check whether the 1xx response forwarding is allowed by squid.conf if (Config.accessList.reply) { - ACLFilledChecklist ch(Config.accessList.reply, originalRequest().getRaw()); - ch.al = fwd->al; + ACLFilledChecklist ch(Config.accessList.reply, originalRequest().getRaw(), fwd->al); ch.reply = reply; ch.syncAle(originalRequest().getRaw(), nullptr); HTTPMSGLOCK(ch.reply); @@ -1468,7 +1467,7 @@ HttpStateData::processReplyBody() Ip::Address client_addr; // XXX: Remove as unused. Why was it added? if (request->flags.spoofClientIp) - client_addr = request->clientAddr(); + client_addr = ale()->clientAddr(); auto serverConnectionSaved = serverConnection; fwd->unregister(serverConnection); @@ -1796,7 +1795,7 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, request->etag.termedBuf())); } - bool we_do_ranges = decideIfWeDoRanges (request); + bool we_do_ranges = decideIfWeDoRanges (request, al); String strConnection (hdr_in->getList(Http::HdrType::CONNECTION)); @@ -1849,10 +1848,10 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, if (strcmp(opt_forwarded_for, "on") == 0) { /** If set to ON - append client IP or 'unknown'. */ - if (!request->clientAddr().isKnown()) + if (!al->clientAddr().isKnown()) strListAdd(&strFwd, "unknown", ','); else - strListAdd(&strFwd, request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN), ','); + strListAdd(&strFwd, al->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN), ','); } else if (strcmp(opt_forwarded_for, "off") == 0) { /** If set to OFF - append 'unknown'. */ strListAdd(&strFwd, "unknown", ','); @@ -1860,10 +1859,10 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, /** If set to TRANSPARENT - pass through unchanged. */ } else if (strcmp(opt_forwarded_for, "truncate") == 0) { /** If set to TRUNCATE - drop existing list and replace with client IP or 'unknown'. */ - if (!request->clientAddr().isKnown() ) + if (!al->clientAddr().isKnown() ) strFwd = "unknown"; else - strFwd = request->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN); + strFwd = al->clientAddr().toStr(ntoabuf, MAX_IPSTRLEN); } if (strFwd.size() > 0) hdr_out->putStr(Http::HdrType::X_FORWARDED_FOR, strFwd.termedBuf()); @@ -2129,7 +2128,7 @@ copyOneHeaderFromClientsideRequestToUpstreamRequest(const HttpHeaderEntry *e, co } bool -HttpStateData::decideIfWeDoRanges (HttpRequest * request) +HttpStateData::decideIfWeDoRanges (HttpRequest * request, const AccessLogEntryPointer &al) { bool result = true; /* decide if we want to do Ranges ourselves @@ -2143,7 +2142,7 @@ HttpStateData::decideIfWeDoRanges (HttpRequest * request) * the server and fetch only the requested content) */ - int64_t roffLimit = request->getRangeOffsetLimit(); + int64_t roffLimit = request->getRangeOffsetLimit(al); if (NULL == request->range || !request->flags.cachable || request->range->offsetLimitExceeded(roffLimit) || request->flags.connectionAuth) @@ -2351,8 +2350,7 @@ HttpStateData::finishingBrokenPost() return false; } - ACLFilledChecklist ch(Config.accessList.brokenPosts, originalRequest().getRaw()); - ch.al = fwd->al; + ACLFilledChecklist ch(Config.accessList.brokenPosts, originalRequest().getRaw(), fwd->al); ch.syncAle(originalRequest().getRaw(), nullptr); if (!ch.fastCheck().allowed()) { debugs(11, 5, HERE << "didn't match brokenPosts"); @@ -2428,7 +2426,7 @@ HttpStateData::handleMoreRequestBodyAvailable() if (flags.headers_parsed && !flags.abuse_detected) { flags.abuse_detected = true; - debugs(11, DBG_IMPORTANT, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << request->clientAddr() << "' -> '" << entry->url() << "'" ); + debugs(11, DBG_IMPORTANT, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << ale()->clientAddr() << "' -> '" << entry->url() << "'" ); if (virginReply()->sline.status() == Http::scInvalidHeader) { closeServer(); diff --git a/src/http.h b/src/http.h index 6d282d5944d..95816d56e0f 100644 --- a/src/http.h +++ b/src/http.h @@ -107,6 +107,8 @@ class HttpStateData : public Client void abortTransaction(const char *reason) { abortAll(reason); } // abnormal termination + AccessLogEntry::Pointer ale() { assert(fwd); assert(fwd->al); return fwd->al; } + /** * determine if read buffer can have space made available * for a read. @@ -135,7 +137,7 @@ class HttpStateData : public Client void httpTimeout(const CommTimeoutCbParams ¶ms); mb_size_t buildRequestPrefix(MemBuf * mb); - static bool decideIfWeDoRanges (HttpRequest * orig_request); + static bool decideIfWeDoRanges (HttpRequest * orig_request, const AccessLogEntryPointer &al); bool peerSupportsConnectionPinning() const; /// Parser being used at present to parse the HTTP/ICY server response. diff --git a/src/http/Stream.cc b/src/http/Stream.cc index 1cd7c68deb8..6639aeec9c8 100644 --- a/src/http/Stream.cc +++ b/src/http/Stream.cc @@ -422,7 +422,7 @@ Http::Stream::buildRangeHeader(HttpReply *rep) HttpRequest *request = http->request; assert(request->range); /* check if we still want to do ranges */ - int64_t roffLimit = request->getRangeOffsetLimit(); + int64_t roffLimit = request->getRangeOffsetLimit(http->al); auto contentRange = rep ? rep->contentRange() : nullptr; if (!rep) diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 3ced759992d..6bd52583adf 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -87,6 +87,7 @@ icpSyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const char *url, al->cache.start_time.tv_sec -= delay; al->cache.trTime.tv_sec = delay; al->cache.trTime.tv_usec = 0; + al->prepareForConnectionlessProtocol(caddr, icpIncomingConn->local); } /** @@ -471,7 +472,7 @@ icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request) if (!Config.accessList.icp) return false; - ACLFilledChecklist checklist(Config.accessList.icp, icp_request, NULL); + ACLFilledChecklist checklist(Config.accessList.icp, icp_request, nullptr, nullptr); // XXX: supply ALE return checklist.fastCheck().allowed(); } @@ -497,8 +498,6 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp); if ((result = HttpRequest::FromUrl(url, mx)) == NULL) icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); - else - result->prepareForConnectionlessProtocol(from, icpIncomingConn->local); return result; diff --git a/src/ip/Address.h b/src/ip/Address.h index 16ef75eccc6..2f8f405e759 100644 --- a/src/ip/Address.h +++ b/src/ip/Address.h @@ -327,6 +327,9 @@ class Address void getSockAddr(struct sockaddr_in6 &) const; void getInAddr(struct in6_addr &) const; + /// whether the address is the same as the one created with default constructor + bool isEmpty() const; + private: /* Conversion for dual-type internals */ @@ -346,9 +349,6 @@ class Address private: - /// whether the address is the same as the one created with default constructor - bool isEmpty() const; - /* Internally used constants */ static const unsigned int STRLEN_IP4A = 16; // aaa.bbb.ccc.ddd\0 static const unsigned int STRLEN_IP4R = 28; // ddd.ccc.bbb.aaa.in-addr.arpa.\0 diff --git a/src/neighbors.cc b/src/neighbors.cc index 1a0d3e2bc9a..fb3f0245207 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -166,8 +166,7 @@ peerAllowedToUse(const CachePeer * p, PeerSelector * ps) if (p->access == NULL) return true; - ACLFilledChecklist checklist(p->access, request, NULL); - checklist.al = ps->al; + ACLFilledChecklist checklist(p->access, request, ps->al, nullptr); checklist.syncAle(request, nullptr); return checklist.fastCheck().allowed(); } @@ -1341,7 +1340,7 @@ peerProbeConnect(CachePeer *p, const bool reprobeIfBusy) conn->remote = p->addresses[i]; conn->remote.port(p->http_port); conn->setPeer(p); - getOutgoingAddress(NULL, conn); + getOutgoingAddress(nullptr, conn, nullptr); ++ p->testing_now; diff --git a/src/peer_select.cc b/src/peer_select.cc index 6e2739d5807..19c7b4c4180 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -286,10 +286,10 @@ PeerSelector::resolveSelected() const bool choseDirect = fs && fs->code == HIER_DIRECT; if (isIntercepted && useOriginalDst && choseDirect) { // check the client is still around before using any of its details - if (req->clientConnection()) { + if (al->tcpClient) { // construct a "result" adding the ORIGINAL_DST to the set instead of DIRECT Comm::ConnectionPointer p = new Comm::Connection(); - p->remote = req->clientConnection()->local; + p->remote = al->tcpClient->local; fs->code = ORIGINAL_DST; // fs->code is DIRECT. This fixes the display. handlePath(p, *fs); } @@ -383,7 +383,7 @@ PeerSelector::noteIp(const Ip::Address &ip) // for TPROXY spoofing, we must skip unusable addresses if (request->flags.spoofClientIp && !(peer && peer->options.no_tproxy) ) { - if (ip.isIPv4() != request->clientAddr().isIPv4()) + if (ip.isIPv4() != al->clientAddr().isIPv4()) return; // cannot spoof the client address on this link } @@ -475,8 +475,7 @@ PeerSelector::selectMore() if (always_direct == ACCESS_DUNNO) { debugs(44, 3, "direct = " << DirectStr[direct] << " (always_direct to be checked)"); /** check always_direct; */ - ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, NULL); - ch->al = al; + ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, al, nullptr); acl_checklist = ch; acl_checklist->syncAle(request, nullptr); acl_checklist->nonBlockingCheck(CheckAlwaysDirectDone, this); @@ -484,8 +483,7 @@ PeerSelector::selectMore() } else if (never_direct == ACCESS_DUNNO) { debugs(44, 3, "direct = " << DirectStr[direct] << " (never_direct to be checked)"); /** check never_direct; */ - ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.NeverDirect, request, NULL); - ch->al = al; + ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.NeverDirect, request, al, nullptr); acl_checklist = ch; acl_checklist->syncAle(request, nullptr); acl_checklist->nonBlockingCheck(CheckNeverDirectDone, this); @@ -1024,7 +1022,7 @@ PeerSelector::handlePath(const Comm::ConnectionPointer &path, FwdServer &fs) path->setPeer(fs._peer.get()); // check for a configured outgoing address for this destination... - getOutgoingAddress(request, path); + getOutgoingAddress(request, path, al); debugs(44, 2, id << " found " << path << ", destination #" << foundPaths << " for " << url()); } else debugs(44, 2, id << " found pinned, destination #" << foundPaths << " for " << url()); diff --git a/src/peer_sourcehash.cc b/src/peer_sourcehash.cc index bb75e1e0a84..8d3b056f07c 100644 --- a/src/peer_sourcehash.cc +++ b/src/peer_sourcehash.cc @@ -159,9 +159,8 @@ peerSourceHashSelectParent(PeerSelector *ps) return NULL; assert(ps); - HttpRequest *request = ps->request; - key = request->clientAddr().toStr(ntoabuf, sizeof(ntoabuf)); + key = ps->al->clientAddr().toStr(ntoabuf, sizeof(ntoabuf)); /* calculate hash key */ debugs(39, 2, "peerSourceHashSelectParent: Calculating hash for " << key); diff --git a/src/security/PeerConnector.cc b/src/security/PeerConnector.cc index f088371b2b0..b01878e825b 100644 --- a/src/security/PeerConnector.cc +++ b/src/security/PeerConnector.cc @@ -130,8 +130,7 @@ Security::PeerConnector::initialize(Security::SessionPointer &serverSession) // Create the ACL check list now, while we have access to more info. // The list is used in ssl_verify_cb() and is freed in ssl_free(). if (acl_access *acl = ::Config.ssl_client.cert_error) { - ACLFilledChecklist *check = new ACLFilledChecklist(acl, request.getRaw(), dash_str); - check->al = al; + ACLFilledChecklist *check = new ACLFilledChecklist(acl, request.getRaw(), al, dash_str); check->syncAle(request.getRaw(), nullptr); // check->fd(fd); XXX: need client FD here SSL_set_ex_data(serverSession.get(), ssl_ex_index_cert_error_check, check); @@ -310,8 +309,7 @@ Security::PeerConnector::sslCrtvdCheckForErrors(Ssl::CertValidationResponse cons { ACLFilledChecklist *check = NULL; if (acl_access *acl = ::Config.ssl_client.cert_error) { - check = new ACLFilledChecklist(acl, request.getRaw(), dash_str); - check->al = al; + check = new ACLFilledChecklist(acl, request.getRaw(), al, dash_str); check->syncAle(request.getRaw(), nullptr); } diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index ad84be7b67f..d3ab42c0664 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1542,8 +1542,7 @@ Ftp::Server::handleUploadRequest(String &, String &) if (Config.accessList.forceRequestBodyContinuation) { ClientHttpRequest *http = pipeline.front()->http; HttpRequest *request = http->request; - ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, NULL); - bodyContinuationCheck.al = http->al; + ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, http->al, nullptr); bodyContinuationCheck.setClientConnectionDetails(this); bodyContinuationCheck.syncAle(request, http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index 5376e6d1cc1..5175e7b0382 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -255,8 +255,7 @@ Http::One::Server::processParsedRequest(Http::StreamPointer &context) } if (Config.accessList.forceRequestBodyContinuation) { - ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), NULL); - bodyContinuationCheck.al = http->al; + ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), http->al, nullptr); bodyContinuationCheck.setClientConnectionDetails(this); bodyContinuationCheck.syncAle(request.getRaw(), http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { diff --git a/src/snmp_core.cc b/src/snmp_core.cc index f8a6ab26284..490445b1304 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -394,7 +394,7 @@ snmpDecodePacket(SnmpRequest * rq) /* Check if we have explicit permission to access SNMP data. * default (set above) is to deny all */ if (Community) { - ACLFilledChecklist checklist(Config.accessList.snmp, NULL, NULL); + ACLFilledChecklist checklist(Config.accessList.snmp, nullptr, nullptr, nullptr); checklist.snmpDetails(reinterpret_cast(Community), rq->from, snmpIncomingConn->local); if (checklist.fastCheck().allowed() && (snmp_coexist_V2toV1(PDU))) { rq->community = Community; diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index a6a56f65680..458c0b9196a 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -56,8 +56,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSplice() ACLFilledChecklist *acl_checklist = new ACLFilledChecklist( ::Config.accessList.ssl_bump, - request.getRaw(), NULL); - acl_checklist->al = al; + request.getRaw(), al, nullptr); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpNone)); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpPeek)); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpStare)); diff --git a/src/store_client.cc b/src/store_client.cc index ae0e8a0509e..58c4fc71225 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -56,7 +56,7 @@ StoreClient::onCollapsingPath() const if (!Config.accessList.collapsedForwardingAccess) return true; - ACLFilledChecklist checklist(Config.accessList.collapsedForwardingAccess, nullptr, nullptr); + ACLFilledChecklist checklist(Config.accessList.collapsedForwardingAccess, nullptr, nullptr, nullptr); fillChecklist(checklist); return checklist.fastCheck().allowed(); } @@ -859,7 +859,7 @@ CheckQuickAbortIsReasonable(StoreEntry * entry) return false; } - if (mem->request && mem->request->range && mem->request->getRangeOffsetLimit() < 0) { + if (mem->request && mem->request->range && mem->request->getRangeOffsetLimit(nullptr) < 0) { // XXX supply ALE /* Don't abort if the admin has configured range_ofset -1 to download fully for caching. */ debugs(90, 3, "quick-abort? NO admin configured range replies to full-download"); return false; diff --git a/src/tunnel.cc b/src/tunnel.cc index e2083dbf0d8..b1a4fa3a28c 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -934,13 +934,12 @@ tunnelStart(ClientHttpRequest * http) HttpRequest *request = http->request; char *url = http->uri; - if (Config.accessList.miss && request->needCheckMissAccess()) { + if (Config.accessList.miss && !tunnelState->al->clientAddr().isEmpty() && request->needCheckMissAccess()) { /* * Check if this host is allowed to fetch MISSES from us (miss_access) * default is to allow. */ - ACLFilledChecklist ch(Config.accessList.miss, request, NULL); - ch.al = http->al; + ACLFilledChecklist ch(Config.accessList.miss, request, http->al, nullptr); ch.syncAle(request, http->log_uri); if (ch.fastCheck().denied()) { debugs(26, 4, HERE << "MISS access forbidden."); @@ -1105,7 +1104,7 @@ TunnelStateData::startConnecting() debugs(26, 3, "to " << dest); assert(dest != nullptr); - GetMarkingsToServer(request.getRaw(), *dest); + GetMarkingsToServer(request.getRaw(), *dest, al); const time_t connectTimeout = dest->connectTimeout(startTime); AsyncCall::Pointer call = commCbCall(26,3, "tunnelConnectDone", CommConnectCbPtrFun(tunnelConnectDone, this)); From 38f9123049be8e92c02eecc452862d264a3d0cdd Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 29 Oct 2019 21:32:27 +0300 Subject: [PATCH 41/66] Initialize ErrorState::ale before its first usage --- src/errorpage.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/errorpage.cc b/src/errorpage.cc index 55c973f6104..25cbe1a6946 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -681,6 +681,8 @@ ErrorState::ErrorState(err_type t) : ErrorState::ErrorState(err_type t, Http::StatusCode status, HttpRequest * req, const AccessLogEntry::Pointer &anAle) : ErrorState(t) { + ale = anAle; + if (page_id >= ERR_MAX && ErrorDynamicPages[page_id - ERR_MAX]->page_redirect != Http::scNone) httpStatus = ErrorDynamicPages[page_id - ERR_MAX]->page_redirect; else @@ -690,8 +692,6 @@ ErrorState::ErrorState(err_type t, Http::StatusCode status, HttpRequest * req, c request = req; src_addr = ale->clientAddr(); } - - ale = anAle; } ErrorState::ErrorState(HttpRequest * req, HttpReply *errorReply) : From 4e2c7602252ecfb44d613bf658aa483d68fbf092 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Wed, 30 Oct 2019 15:52:25 +0300 Subject: [PATCH 42/66] ICAP ALE: copy the HTTP client address from master ALE thus resolving an XXX (and restoring the original behavior). --- src/AccessLogEntry.cc | 7 ------- src/AccessLogEntry.h | 7 +++++-- src/adaptation/icap/ModXact.cc | 3 ++- src/htcp.cc | 3 ++- src/icp_v2.cc | 3 ++- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index f4154e0e484..7431ffb3d51 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -151,13 +151,6 @@ AccessLogEntry::ignoreIndirectClientAddr() } #endif /* FOLLOW_X_FORWARDED_FOR */ -void -AccessLogEntry::prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr) -{ - client_addr = fromAddr; - my_addr = localAddr; -} - const Ip::Address& AccessLogEntry::myAddr() const { diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index 5b462085b83..9521a59f4a6 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -73,8 +73,11 @@ class AccessLogEntry: public RefCountable /// forces furthestClientAddress() to return a direct client address void ignoreIndirectClientAddr(); #endif - /// specify addresses manually when lacking client connection - void prepareForConnectionlessProtocol(const Ip::Address &fromAddr, const Ip::Address &localAddr); + /// specify the source client address manually when lacking client connection + void setClientAddr(const Ip::Address &fromAddr) { client_addr = fromAddr; } + + /// specify the local address manually when lacking client connection + void setMyAddr(const Ip::Address &localAddr) { my_addr = localAddr; } /// the local address of the client connection const Ip::Address& myAddr() const; diff --git a/src/adaptation/icap/ModXact.cc b/src/adaptation/icap/ModXact.cc index e551f4d3834..3923ca66a59 100644 --- a/src/adaptation/icap/ModXact.cc +++ b/src/adaptation/icap/ModXact.cc @@ -1331,7 +1331,8 @@ void Adaptation::Icap::ModXact::finalizeLogInfo() const Adaptation::Icap::ServiceRep &s = service(); al.icap.reqMethod = s.cfg().method; - al.cache.caddr = al.clientAddr(); // XXX: should we use the virgin client addr (as the old code did)? + al.cache.caddr = alMaster->clientAddr(); + al.setClientAddr(alMaster->clientAddr()); al.request = virgin_request_; HTTPMSGLOCK(al.request); diff --git a/src/htcp.cc b/src/htcp.cc index 1822d5a8e99..591e0beaf99 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -141,7 +141,8 @@ class htcpSpecifier : public RefCountable, public StoreClient } void setAddresses(Ip::Address &fromAddr) { htcpSyncAle(al, fromAddr, dhdr->opcode, uri); - al->prepareForConnectionlessProtocol(fromAddr, htcpIncomingConn->local); + al->setClientAddr(fromAddr); + al->setMyAddr(htcpIncomingConn->local); } void setDataHeader(htcpDataHeader *aDataHeader) { dhdr = aDataHeader; diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 6bd52583adf..86394a2e3c2 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -87,7 +87,8 @@ icpSyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const char *url, al->cache.start_time.tv_sec -= delay; al->cache.trTime.tv_sec = delay; al->cache.trTime.tv_usec = 0; - al->prepareForConnectionlessProtocol(caddr, icpIncomingConn->local); + al->setClientAddr(caddr); + al->setMyAddr(icpIncomingConn->local); } /** From 15b01eb2098fd69d5e52c645310cc0660dedd58e Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Wed, 30 Oct 2019 18:04:58 +0300 Subject: [PATCH 43/66] Supply ALE to icp_access checks thus resolving an XXX. --- src/ICP.h | 7 +++++-- src/icp_v2.cc | 34 +++++++++++++++++++--------------- src/icp_v3.cc | 11 +++++++---- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/ICP.h b/src/ICP.h index f5a8ad47709..54f886db705 100644 --- a/src/ICP.h +++ b/src/ICP.h @@ -65,9 +65,12 @@ class ICPState: public StoreClient { public: - ICPState(icp_common_t &aHeader, HttpRequest *aRequest); + ICPState(icp_common_t &aHeader, HttpRequest *aRequest, const AccessLogEntryPointer &); virtual ~ICPState(); + /// creates ALE (if nil), always overwriting its fields with the supplied parameters + static void SyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const char *url, int len, int delay); + icp_common_t header; HttpRequest *request; int fd; @@ -94,7 +97,7 @@ extern Ip::Address theIcpPublicHostID; HttpRequest* icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from); /// \ingroup ServerProtocolICPAPI -bool icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request); +bool icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const AccessLogEntryPointer &al); /// \ingroup ServerProtocolICPAPI void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from, AccessLogEntryPointer); diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 86394a2e3c2..30650bfea43 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -72,8 +72,8 @@ static LogTags_ot icpLogFromICPCode(icp_opcode); static int icpUdpSend(int fd, const Ip::Address &to, icp_common_t * msg, int delay, AccessLogEntryPointer al); -static void -icpSyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const char *url, int len, int delay) +void +ICPState::SyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const char *url, int len, int delay) { if (!al) al = new AccessLogEntry(); @@ -141,11 +141,12 @@ icp_common_t::getOpCode() const /* ICPState */ -ICPState::ICPState(icp_common_t &aHeader, HttpRequest *aRequest): +ICPState::ICPState(icp_common_t &aHeader, HttpRequest *aRequest, const AccessLogEntryPointer &ale): header(aHeader), request(aRequest), fd(-1), - url(NULL) + url(nullptr), + al(ale) { HTTPMSGLOCK(request); } @@ -174,7 +175,7 @@ ICPState::confirmAndPrepHit(const StoreEntry &e) LogTags * ICPState::loggingTags() { - // calling icpSyncAle(LOG_TAG_NONE) here would not change cache.code + // calling SyncAle(LOG_TAG_NONE) here would not change cache.code if (!al) al = new AccessLogEntry(); return &al->cache.code; @@ -184,7 +185,7 @@ void ICPState::fillChecklist(ACLFilledChecklist &checklist) const { checklist.setRequest(request); - icpSyncAle(al, from, url, 0, 0); + SyncAle(al, from, url, 0, 0); checklist.al = al; } @@ -197,8 +198,8 @@ class ICP2State: public ICPState { public: - ICP2State(icp_common_t & aHeader, HttpRequest *aRequest): - ICPState(aHeader, aRequest),rtt(0),src_rtt(0),flags(0) {} + ICP2State(icp_common_t &aHeader, HttpRequest *aRequest, const AccessLogEntryPointer &ale): + ICPState(aHeader, aRequest, ale), rtt(0), src_rtt(0), flags(0) {} ~ICP2State(); virtual void created(StoreEntry * newEntry) override; @@ -252,9 +253,9 @@ icpLogIcp(const Ip::Address &caddr, const LogTags_ot logcode, const int len, con { assert(logcode != LOG_TAG_NONE); - // Optimization: No premature (ALE creation in) icpSyncAle(). + // Optimization: No premature (ALE creation in) SyncAle(). if (al) { - icpSyncAle(al, caddr, url, len, delay); + ICPState::SyncAle(al, caddr, url, len, delay); al->cache.code.update(logcode); } @@ -268,7 +269,7 @@ icpLogIcp(const Ip::Address &caddr, const LogTags_ot logcode, const int len, con if (!al) { // The above attempt to optimize ALE creation has failed. We do need it. - icpSyncAle(al, caddr, url, len, delay); + ICPState::SyncAle(al, caddr, url, len, delay); al->cache.code.update(logcode); } clientdbUpdate(caddr, al->cache.code, AnyP::PROTO_ICP, len); @@ -467,13 +468,13 @@ icpDenyAccess(Ip::Address &from, char *url, int reqnum, int fd) } bool -icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request) +icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const AccessLogEntryPointer &al) { /* absent any explicit rules, we deny all */ if (!Config.accessList.icp) return false; - ACLFilledChecklist checklist(Config.accessList.icp, icp_request, nullptr, nullptr); // XXX: supply ALE + ACLFilledChecklist checklist(Config.accessList.icp, icp_request, al, nullptr); return checklist.fastCheck().allowed(); } @@ -519,7 +520,10 @@ doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header) HTTPMSGLOCK(icp_request); - if (!icpAccessAllowed(from, icp_request)) { + AccessLogEntryPointer al = new AccessLogEntry(); + ICPState::SyncAle(al, from, url, 0, 0); + + if (!icpAccessAllowed(from, icp_request, al)) { icpDenyAccess(from, url, header.reqnum, fd); HTTPMSGUNLOCK(icp_request); return; @@ -536,7 +540,7 @@ doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header) #endif /* USE_ICMP */ /* The peer is allowed to use this cache */ - ICP2State *state = new ICP2State(header, icp_request); + auto state = new ICP2State(header, icp_request, al); state->fd = fd; state->from = from; state->url = xstrdup(url); diff --git a/src/icp_v3.cc b/src/icp_v3.cc index acb19bdc924..c4260be79b9 100644 --- a/src/icp_v3.cc +++ b/src/icp_v3.cc @@ -24,8 +24,8 @@ class ICP3State: public ICPState { public: - ICP3State(icp_common_t &aHeader, HttpRequest *aRequest) : - ICPState(aHeader, aRequest) {} + ICP3State(icp_common_t &aHeader, HttpRequest *aRequest, const AccessLogEntryPointer &ale) : + ICPState(aHeader, aRequest, ale) {} ~ICP3State(); void created (StoreEntry *newEntry); @@ -42,14 +42,17 @@ doV3Query(int fd, Ip::Address &from, char *buf, icp_common_t header) if (!icp_request) return; - if (!icpAccessAllowed(from, icp_request)) { + AccessLogEntryPointer al = new AccessLogEntry(); + ICPState::SyncAle(al, from, url, 0, 0); + + if (!icpAccessAllowed(from, icp_request, al)) { icpDenyAccess (from, url, header.reqnum, fd); delete icp_request; return; } /* The peer is allowed to use this cache */ - ICP3State *state = new ICP3State (header, icp_request); + auto state = new ICP3State(header, icp_request, al); state->fd = fd; state->from = from; state->url = xstrdup(url); From 3dd9cdcdbb310956e2f3ea2614eae97c83afedca Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Wed, 30 Oct 2019 19:43:22 +0300 Subject: [PATCH 44/66] Supply range_offset_limit check with ALE thus resolving an XXX. --- src/store_client.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/store_client.cc b/src/store_client.cc index 58c4fc71225..0c9dbb7aa18 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -10,9 +10,12 @@ #include "squid.h" #include "acl/FilledChecklist.h" +#include "client_side.h" +#include "client_side_request.h" #include "event.h" #include "globals.h" #include "HttpReply.h" +#include "http/Stream.h" #include "HttpRequest.h" #include "MemBuf.h" #include "MemObject.h" @@ -859,10 +862,20 @@ CheckQuickAbortIsReasonable(StoreEntry * entry) return false; } - if (mem->request && mem->request->range && mem->request->getRangeOffsetLimit(nullptr) < 0) { // XXX supply ALE - /* Don't abort if the admin has configured range_ofset -1 to download fully for caching. */ - debugs(90, 3, "quick-abort? NO admin configured range replies to full-download"); - return false; + if (const auto req = mem->request) { + if (req->range) { + AccessLogEntry::Pointer al; + if (const auto mgr = req->masterXaction->clientConnectionManager().valid()) { + if (const auto stream = mgr->pipeline.front()) { + if (stream->http) + al = stream->http->al; + } + } + if (req->getRangeOffsetLimit(al) < 0) { + debugs(90, 3, "quick-abort? NO admin configured range replies to full-download"); + return false; + } + } } if (curlen > expectlen) { From 3e3f2abadb059abdcef937b1a093c0b2b7b79b01 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 31 Oct 2019 00:55:22 +0300 Subject: [PATCH 45/66] Moved HttpRequest::clientConnectionManager() into ALE --- src/AccessLogEntry.cc | 10 +++++++ src/AccessLogEntry.h | 9 +++++++ src/FwdState.cc | 18 ++++++------- src/HttpRequest.cc | 23 +++-------------- src/HttpRequest.h | 7 +---- src/acl/FilledChecklist.cc | 6 ++--- src/auth/UserRequest.cc | 2 +- src/client_side_reply.cc | 6 ++--- src/client_side_request.cc | 11 ++++---- src/clients/FtpRelay.cc | 14 +++++----- src/external_acl.cc | 2 +- src/format/Format.cc | 46 ++++++++++++++++----------------- src/http.cc | 6 ++--- src/peer_select.cc | 6 ++--- src/ssl/PeekingPeerConnector.cc | 26 +++++++++---------- src/tunnel.cc | 13 ++++++---- 16 files changed, 104 insertions(+), 101 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index 7431ffb3d51..d908c859ca1 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -8,7 +8,9 @@ #include "squid.h" #include "AccessLogEntry.h" +#include "client_side.h" #include "HttpReply.h" +#include "http/Stream.h" #include "HttpRequest.h" #include "proxyp/Header.h" #include "SquidConfig.h" @@ -156,3 +158,11 @@ AccessLogEntry::myAddr() const { return tcpClient ? tcpClient->local : my_addr; } + +ConnStateData * +AccessLogEntry::pinnedConnection() +{ + if (clientConnectionManager().valid() && clientConnectionManager()->pinning.pinned) + return clientConnectionManager().get(); + return nullptr; +} diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index 9521a59f4a6..3dd551fb6cc 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -10,6 +10,7 @@ #define SQUID_HTTPACCESSLOGENTRY_H #include "anyp/PortCfg.h" +#include "base/CbcPointer.h" #include "base/RefCount.h" #include "comm/Connection.h" #include "HierarchyLogEntry.h" @@ -35,6 +36,7 @@ class HttpReply; class HttpRequest; class CustomLog; +class ConnStateData; class AccessLogEntry: public RefCountable { @@ -82,6 +84,12 @@ class AccessLogEntry: public RefCountable /// the local address of the client connection const Ip::Address& myAddr() const; + /// the client connection manager of the underlying transaction, if any + CbcPointer &clientConnectionManager() { return clientConnectionManager_; } + void setClientConnectionManager(const CbcPointer &aMgr) { clientConnectionManager_ = aMgr; } + + ConnStateData *pinnedConnection(); + SBuf url; /// TCP/IP level details about the client connection @@ -276,6 +284,7 @@ class AccessLogEntry: public RefCountable /// Client URI (or equivalent) for effectiveVirginUrl() when HttpRequest is /// missing. This member is ignored unless the request member is nil. SBuf virginUrlForMissingRequest_; + CbcPointer clientConnectionManager_; }; class ACLChecklist; diff --git a/src/FwdState.cc b/src/FwdState.cc index a8471f97af5..a054b799267 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -254,8 +254,8 @@ FwdState::completed() errorAppendEntry(entry, err); err = NULL; #if USE_OPENSSL - if (request->flags.sslPeek && request->clientConnectionManager().valid()) { - CallJobHere1(17, 4, request->clientConnectionManager(), ConnStateData, + if (request->flags.sslPeek && al->clientConnectionManager().valid()) { + CallJobHere1(17, 4, al->clientConnectionManager(), ConnStateData, ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(Comm::ConnectionPointer(nullptr), request)); } #endif @@ -443,7 +443,7 @@ FwdState::fail(ErrorState * errorState) pconnRace = raceHappened; } - if (ConnStateData *pinned_connection = request->pinnedConnection()) { + if (auto pinned_connection = al->pinnedConnection()) { pinned_connection->pinning.zeroReply = true; debugs(17, 4, "zero reply on pinned connection"); } @@ -868,7 +868,7 @@ void FwdState::successfullyConnectedToPeer() { // should reach ConnStateData before the dispatched Client job starts - CallJobHere1(17, 4, request->clientConnectionManager(), ConnStateData, + CallJobHere1(17, 4, al->clientConnectionManager(), ConnStateData, ConnStateData::notePeerConnection, serverConnection()); if (serverConnection()->getPeer()) @@ -961,9 +961,9 @@ FwdState::connectStart() // server is not established/pinned so they must be excluded. We can // recognize step1 bumping by nil ConnStateData::serverBump(). #if USE_OPENSSL - const auto clientFirstBump = request->clientConnectionManager().valid() && - (request->clientConnectionManager()->sslBumpMode == Ssl::bumpClientFirst || - (request->clientConnectionManager()->sslBumpMode == Ssl::bumpBump && !request->clientConnectionManager()->serverBump()) + const auto clientFirstBump = al->clientConnectionManager().valid() && + (al->clientConnectionManager()->sslBumpMode == Ssl::bumpClientFirst || + (al->clientConnectionManager()->sslBumpMode == Ssl::bumpBump && !al->clientConnectionManager()->serverBump()) ); #else const auto clientFirstBump = false; @@ -1038,7 +1038,7 @@ FwdState::usePinned() assert(!serverDestinations.empty()); assert(!serverDestinations[0]); - const auto connManager = request->pinnedConnection(); + const auto connManager = al->pinnedConnection(); debugs(17, 7, "connection manager: " << connManager); // the client connection may close while we get here, nullifying connManager @@ -1125,7 +1125,7 @@ FwdState::dispatch() #if USE_OPENSSL if (request->flags.sslPeek) { - CallJobHere1(17, 4, request->clientConnectionManager(), ConnStateData, + CallJobHere1(17, 4, al->clientConnectionManager(), ConnStateData, ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(serverConnection(), request)); unregister(serverConn); // async call owns it now complete(); // destroys us diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index f1585c88030..9e53ef526ec 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -117,7 +117,7 @@ HttpRequest::init() rangeOffsetLimit = -2; //a value of -2 means not checked yet forcedBodyContinuation = false; - if (const auto mgr = clientConnectionManager().valid()) { + if (const auto mgr = masterXaction->clientConnectionManager().valid()) { if (const auto port = mgr->port) flags.ignoreCc = port->ignore_cc; } @@ -680,14 +680,6 @@ HttpRequest::parseHeader(const char *buffer, const size_t size) return header.parse(buffer, size, clen); } -ConnStateData * -HttpRequest::pinnedConnection() -{ - if (clientConnectionManager().valid() && clientConnectionManager()->pinning.pinned) - return clientConnectionManager().get(); - return NULL; -} - const SBuf HttpRequest::storeId() { @@ -716,12 +708,12 @@ HttpRequest::notes() } void -UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const &helperNotes) +UpdateRequestNotes(HttpRequest &request, NotePairs const &helperNotes) { // Tag client connection if the helper responded with clt_conn_tag=tag. const char *cltTag = "clt_conn_tag"; if (const char *connTag = helperNotes.findFirst(cltTag)) { - if (csd) { + if (auto csd = request.masterXaction->clientConnectionManager().get()) { csd->notes()->remove(cltTag); csd->notes()->add(cltTag, connTag); } @@ -737,20 +729,13 @@ HttpRequest::prepareForDownloader(Downloader *aDownloader) downloader = aDownloader; } -// XXX: move this method to ALE -CbcPointer & -HttpRequest::clientConnectionManager() -{ - return masterXaction->clientConnectionManager(); -} - void HttpRequest::setInterceptionFlags(const AccessLogEntryPointer &al) { if (const auto connection = al->tcpClient) { flags.intercepted = ((connection->flags & COMM_INTERCEPTION) != 0); flags.interceptTproxy = ((connection->flags & COMM_TRANSPARENT) != 0 ) ; - const auto port = clientConnectionManager()->port; + const auto port = al->clientConnectionManager()->port; const bool proxyProtocolPort = port ? port->flags.proxySurrogate : false; if (flags.interceptTproxy && !proxyProtocolPort) { if (Config.accessList.spoof_client_ip) { diff --git a/src/HttpRequest.h b/src/HttpRequest.h index f78f0ed6690..3064049f6fd 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -155,9 +155,6 @@ class HttpRequest: public Http::Message /// supply Downloader-specific settings void prepareForDownloader(Downloader *); - /// the client connection manager of the underlying transaction, if any - CbcPointer &clientConnectionManager(); - HierarchyLogEntry hier; int dnsWait; ///< sum of DNS lookup delays in milliseconds, for %dt @@ -215,8 +212,6 @@ class HttpRequest: public Http::Message static HttpRequest * FromUrl(const char * url, const MasterXaction::Pointer &, const HttpRequestMethod &method = Http::METHOD_GET); - ConnStateData *pinnedConnection(); - /** * Returns the current StoreID for the request as a nul-terminated char*. * Always returns the current id for the request @@ -278,7 +273,7 @@ class ConnStateData; /** * Updates ConnStateData ids and HttpRequest notes from helpers received notes. */ -void UpdateRequestNotes(ConnStateData *csd, HttpRequest &request, NotePairs const ¬es); +void UpdateRequestNotes(HttpRequest &request, NotePairs const ¬es); /// \returns listening/*_port address used by the client connection (or nil) /// nil parameter(s) indicate missing caller information and are handled safely diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index cc46637a060..0d4eae28233 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -246,6 +246,9 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re changeAcl(A); setRequest(http_request); + setClientConnectionDetails(al->clientConnectionManager().get()); + if (!clientConnectionManager()) // could not take the connection from the connection manager + setClientConnection(al->tcpClient); setIdent(ident); } @@ -255,9 +258,6 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) if (httpRequest) { request = httpRequest; HTTPMSGLOCK(request); - setClientConnectionDetails(request->clientConnectionManager().get()); - if (!clientConnectionManager()) // could not take the connection from the connection manager - setClientConnection(al->tcpClient); } } diff --git a/src/auth/UserRequest.cc b/src/auth/UserRequest.cc index c0ddf581f02..90aaa682e31 100644 --- a/src/auth/UserRequest.cc +++ b/src/auth/UserRequest.cc @@ -244,7 +244,7 @@ authTryGetUser(Auth::UserRequest::Pointer auth_user_request, ConnStateData * con // workaround by using anything already set in HttpRequest // OR use new and rely on a later Sync copying these to AccessLogEntry - UpdateRequestNotes(conn, *request, res->user()->notes); + UpdateRequestNotes(*request, res->user()->notes); } return res; diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 9cf23b8b9e0..05713c6fb31 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -350,7 +350,7 @@ clientReplyContext::processExpired() debugs(88, 5, "lastmod " << entry->lastModified()); http->storeEntry(entry); assert(http->out.offset == 0); - assert(http->request->clientConnectionManager() == http->getConn()); + assert(http->al->clientConnectionManager() == http->getConn()); if (collapsedRevalidation != crSlave) { /* @@ -785,7 +785,7 @@ clientReplyContext::processMiss() return; } - assert(r->clientConnectionManager() == http->getConn()); + assert(http->al->clientConnectionManager() == http->getConn()); /** Start forwarding to get the new object from network */ FwdState::Start(conn, http->storeEntry(), r, http->al); @@ -1583,7 +1583,7 @@ clientReplyContext::buildReplyHeader() // We do not really have to close, but we pretend we are a tunnel. debugs(88, 3, "clientBuildReplyHeader: bumped reply forces close"); request->flags.proxyKeepalive = false; - } else if (request->pinnedConnection() && !reply->persistent()) { + } else if (http->al->pinnedConnection() && !reply->persistent()) { // The peer wants to close the pinned connection debugs(88, 3, "pinned reply forces close"); request->flags.proxyKeepalive = false; diff --git a/src/client_side_request.cc b/src/client_side_request.cc index e3acc28f38d..2f406810c75 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -168,6 +168,7 @@ ClientHttpRequest::ClientHttpRequest(ConnStateData * aConn) : { setConn(aConn); al = new AccessLogEntry; + al->setClientConnectionManager(aConn); al->cache.start_time = current_time; if (aConn) { al->tcpClient = clientConnection = aConn->clientConnection; @@ -972,7 +973,7 @@ clientCheckPinning(ClientHttpRequest * http) request->flags.connectionProxyAuth = true; } // These should already be linked correctly. - assert(request->clientConnectionManager() == http_conn); + assert(http->al->clientConnectionManager() == http_conn); } } @@ -1004,9 +1005,9 @@ clientCheckPinning(ClientHttpRequest * http) } } } - if (may_pin && !request->pinnedConnection()) { + if (may_pin && !http->al->pinnedConnection()) { // These should already be linked correctly. Just need the ServerConnection to pinn. - assert(request->clientConnectionManager() == http_conn); + assert(http->al->clientConnectionManager() == http_conn); } } } @@ -1184,7 +1185,7 @@ ClientRequestContext::clientRedirectDone(const Helper::Reply &reply) if (http->al) http->al->syncNotes(old_request); - UpdateRequestNotes(http->getConn(), *old_request, reply.notes); + UpdateRequestNotes(*old_request, reply.notes); switch (reply.result) { case Helper::TimedOut: @@ -1302,7 +1303,7 @@ ClientRequestContext::clientStoreIdDone(const Helper::Reply &reply) if (http->al) http->al->syncNotes(old_request); - UpdateRequestNotes(http->getConn(), *old_request, reply.notes); + UpdateRequestNotes(*old_request, reply.notes); switch (reply.result) { case Helper::Unknown: diff --git a/src/clients/FtpRelay.cc b/src/clients/FtpRelay.cc index b45ec1ad60f..a768e88702e 100644 --- a/src/clients/FtpRelay.cc +++ b/src/clients/FtpRelay.cc @@ -201,7 +201,7 @@ Ftp::Relay::serverComplete() { stopOriginWait(ctrl.replycode); - CbcPointer &mgr = fwd->request->clientConnectionManager(); + auto &mgr = fwd->al->clientConnectionManager(); if (mgr.valid()) { if (Comm::IsConnOpen(ctrl.conn)) { debugs(9, 7, "completing FTP server " << ctrl.conn << @@ -227,7 +227,7 @@ Ftp::Relay::serverComplete() Ftp::MasterState & Ftp::Relay::updateMaster() { - const auto &mgr = fwd->request->clientConnectionManager(); + const auto &mgr = fwd->al->clientConnectionManager(); if (mgr.valid()) { if (Ftp::Server *srv = dynamic_cast(mgr.get())) return *srv->master; @@ -340,7 +340,7 @@ Ftp::Relay::processReplyBody() void Ftp::Relay::handleControlReply() { - if (!request->clientConnectionManager().valid()) { + if (!fwd->al->clientConnectionManager().valid()) { debugs(9, 5, "client connection gone"); closeServer(); return; @@ -400,7 +400,7 @@ Ftp::Relay::forwardPreliminaryReply(const PreliminaryCb cb) const AsyncCall::Pointer call = JobCallback(11, 3, CbDialer, this, Ftp::Relay::proceedAfterPreliminaryReply); - CallJobHere1(9, 4, request->clientConnectionManager(), ConnStateData, + CallJobHere1(9, 4, fwd->al->clientConnectionManager(), ConnStateData, ConnStateData::sendControlMsg, HttpControlMsg(reply, call)); } @@ -548,7 +548,7 @@ Ftp::Relay::sendCommand() SENT_COMMAND; if (state == SENT_DATA_REQUEST) { - CbcPointer &mgr = fwd->request->clientConnectionManager(); + CbcPointer &mgr = fwd->al->clientConnectionManager(); if (mgr.valid()) { if (Ftp::Server *srv = dynamic_cast(mgr.get())) { typedef NullaryMemFunT CbDialer; @@ -633,7 +633,7 @@ Ftp::Relay::readDataReply() bool Ftp::Relay::startDirTracking() { - if (!fwd->request->clientConnectionManager()->port->ftp_track_dirs) + if (!fwd->al->clientConnectionManager()->port->ftp_track_dirs) return false; debugs(9, 5, "start directory tracking"); @@ -770,7 +770,7 @@ void Ftp::Relay::stopOriginWait(int code) { if (originWaitInProgress) { - if (const auto mgr = fwd->request->clientConnectionManager().valid()) { + if (const auto mgr = fwd->al->clientConnectionManager().valid()) { if (const auto srv = dynamic_cast(mgr)) { typedef UnaryMemFunT CbDialer; AsyncCall::Pointer call = asyncCall(11, 3, "Ftp::Server::stopWaitingForOrigin", diff --git a/src/external_acl.cc b/src/external_acl.cc index b5a79d63145..fc8f555c04f 100644 --- a/src/external_acl.cc +++ b/src/external_acl.cc @@ -590,7 +590,7 @@ copyResultsFromEntry(HttpRequest *req, const ExternalACLEntryPointer &entry) req->extacl_message = entry->message; // attach the helper kv-pair to the transaction - UpdateRequestNotes(req->clientConnectionManager().get(), *req, entry->notes); + UpdateRequestNotes(*req, entry->notes); } } diff --git a/src/format/Format.cc b/src/format/Format.cc index 941454e03a0..f73c796d4d7 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -440,9 +440,9 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_CLIENT_EUI: #if USE_SQUID_EUI // TODO make the ACL checklist have a direct link to any TCP details. - if (al->request && al->request->clientConnectionManager().valid() && - al->request->clientConnectionManager()->clientConnection) { - const auto &conn = al->request->clientConnectionManager()->clientConnection; + if (al->clientConnectionManager().valid() && + al->clientConnectionManager()->clientConnection) { + const auto &conn = al->clientConnectionManager()->clientConnection; if (conn->remote.isIPv4()) conn->remoteEui48.encode(tmp, sizeof(tmp)); else @@ -454,10 +454,10 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_CLIENT_EUI48: #if USE_SQUID_EUI - if (al->request && al->request->clientConnectionManager().valid() && - al->request->clientConnectionManager()->clientConnection && - al->request->clientConnectionManager()->clientConnection->remote.isIPv4()) { - al->request->clientConnectionManager()->clientConnection->remoteEui48.encode(tmp, sizeof(tmp)); + if (al->clientConnectionManager().valid() && + al->clientConnectionManager()->clientConnection && + al->clientConnectionManager()->clientConnection->remote.isIPv4()) { + al->clientConnectionManager()->clientConnection->remoteEui48.encode(tmp, sizeof(tmp)); out = tmp; } #endif @@ -465,10 +465,10 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_CLIENT_EUI64: #if USE_SQUID_EUI - if (al->request && al->request->clientConnectionManager().valid() && - al->request->clientConnectionManager()->clientConnection && - !al->request->clientConnectionManager()->clientConnection->remote.isIPv4()) { - al->request->clientConnectionManager()->clientConnection->remoteEui64.encode(tmp, sizeof(tmp)); + if (al->clientConnectionManager().valid() && + al->clientConnectionManager()->clientConnection && + !al->clientConnectionManager()->clientConnection->remote.isIPv4()) { + al->clientConnectionManager()->clientConnection->remoteEui64.encode(tmp, sizeof(tmp)); out = tmp; } #endif @@ -556,8 +556,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_CLIENT_HANDSHAKE: - if (al->request && al->request->clientConnectionManager().valid()) { - const auto &handshake = al->request->clientConnectionManager()->preservedClientData; + if (al->clientConnectionManager().valid()) { + const auto &handshake = al->clientConnectionManager()->preservedClientData; if (const auto rawLength = handshake.length()) { // add 1 byte to optimize the c_str() conversion below char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1); @@ -1220,7 +1220,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CERT_RAW: if (al->request) { - ConnStateData *conn = al->request->clientConnectionManager().get(); + const auto conn = al->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) { sb = sslGetUserCertificatePEM(ssl); @@ -1232,7 +1232,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CERTCHAIN_RAW: if (al->request) { - ConnStateData *conn = al->request->clientConnectionManager().get(); + const auto conn = al->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (const auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) { sb = sslGetUserCertificatePEM(ssl); @@ -1244,7 +1244,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CERT: if (al->request) { - const auto conn = al->request->clientConnectionManager().get(); + const auto conn = al->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) out = sslGetUserAttribute(ssl, fmt->data.header.header); @@ -1254,7 +1254,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_USER_CA_CERT: if (al->request) { - const auto conn = al->request->clientConnectionManager().get(); + const auto conn = al->clientConnectionManager().get(); if (conn && Comm::IsConnOpen(conn->clientConnection)) { if (auto ssl = fd_table[conn->clientConnection->fd].ssl.get()) out = sslGetCAAttribute(ssl, fmt->data.header.header); @@ -1281,8 +1281,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_SSL_CLIENT_SNI: - if (al->request && al->request->clientConnectionManager().valid()) { - if (const auto conn = al->request->clientConnectionManager().get()) { + if (al->clientConnectionManager().valid()) { + if (const auto conn = al->clientConnectionManager().get()) { if (!conn->tlsClientSni().isEmpty()) { sb = conn->tlsClientSni(); out = sb.c_str(); @@ -1292,8 +1292,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_SSL_SERVER_CERT_ERRORS: - if (al->request && al->request->clientConnectionManager().valid()) { - if (const auto srvBump = al->request->clientConnectionManager()->serverBump()) { + if (al->clientConnectionManager().valid()) { + if (const auto srvBump = al->clientConnectionManager()->serverBump()) { const char *separator = fmt->data.string ? fmt->data.string : ":"; for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) { if (!sb.isEmpty()) @@ -1314,8 +1314,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_SERVER_CERT_ISSUER: case LFT_SSL_SERVER_CERT_SUBJECT: case LFT_SSL_SERVER_CERT_WHOLE: - if (al->request && al->request->clientConnectionManager().valid()) { - if (const auto srvBump = al->request->clientConnectionManager()->serverBump()) { + if (al->clientConnectionManager().valid()) { + if (const auto srvBump = al->clientConnectionManager()->serverBump()) { if (X509 *serverCert = srvBump->serverCert.get()) { if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT) out = Ssl::GetX509UserAttribute(serverCert, "DN"); diff --git a/src/http.cc b/src/http.cc index 973cb646d23..b64252b06b2 100644 --- a/src/http.cc +++ b/src/http.cc @@ -820,7 +820,7 @@ HttpStateData::handle1xx(HttpReply *reply) typedef NullaryMemFunT CbDialer; const AsyncCall::Pointer cb = JobCallback(11, 3, CbDialer, this, HttpStateData::proceedAfter1xx); - CallJobHere1(11, 4, request->clientConnectionManager(), ConnStateData, + CallJobHere1(11, 4, fwd->al->clientConnectionManager(), ConnStateData, ConnStateData::sendControlMsg, HttpControlMsg(msg, cb)); // If the call is not fired, then the Sink is gone, and HttpStateData // will terminate due to an aborted store entry or another similar error. @@ -1481,8 +1481,8 @@ HttpStateData::processReplyBody() } if (ispinned) { - if (request->clientConnectionManager().valid()) { - CallJobHere1(11, 4, request->clientConnectionManager(), + if (fwd->al->clientConnectionManager().valid()) { + CallJobHere1(11, 4, fwd->al->clientConnectionManager(), ConnStateData, notePinnedConnectionBecameIdle, ConnStateData::PinnedIdleContext(serverConnectionSaved, request)); diff --git a/src/peer_select.cc b/src/peer_select.cc index 19c7b4c4180..7391a79fb5b 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -559,11 +559,11 @@ void PeerSelector::selectPinned() { // TODO: Avoid all repeated calls. Relying on PING_DONE is not enough. - if (!request->pinnedConnection()) + if (!al->pinnedConnection()) return; - if (Comm::IsConnOpen(request->pinnedConnection()->validatePinnedConnection(request))) { - const auto pear = request->pinnedConnection()->pinnedPeer(); + if (Comm::IsConnOpen(al->pinnedConnection()->validatePinnedConnection(request))) { + const auto pear = al->pinnedConnection()->pinnedPeer(); const bool usePinned = pear ? peerAllowedToUse(pear, this) : (direct != DIRECT_NO); if (usePinned) { addSelection(pear, PINNED); diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index 458c0b9196a..781bb8ccaed 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -23,7 +23,7 @@ CBDATA_NAMESPACED_CLASS_INIT(Ssl, PeekingPeerConnector); -void switchToTunnel(HttpRequest *request, Comm::ConnectionPointer & clientConn, Comm::ConnectionPointer &srvConn); +void switchToTunnel(HttpRequest *request, const AccessLogEntryPointer &al, Comm::ConnectionPointer &srvConn); void Ssl::PeekingPeerConnector::cbCheckForPeekAndSpliceDone(Acl::Answer answer, void *data) @@ -46,7 +46,7 @@ void Ssl::PeekingPeerConnector::checkForPeekAndSplice() { // Mark Step3 of bumping - if (const auto manager = request->clientConnectionManager().valid()) { + if (const auto manager = al->clientConnectionManager().valid()) { if (const auto serverBump = manager->serverBump()) { serverBump->step = Ssl::bumpStep3; } @@ -84,9 +84,9 @@ Ssl::PeekingPeerConnector::checkForPeekAndSpliceMatched(const Ssl::BumpMode acti Ssl::BumpMode finalAction = action; Must(finalAction == Ssl::bumpSplice || finalAction == Ssl::bumpBump || finalAction == Ssl::bumpTerminate); // Record final decision - if (request->clientConnectionManager().valid()) { - request->clientConnectionManager()->sslBumpMode = finalAction; - request->clientConnectionManager()->serverBump()->act.step3 = finalAction; + if (al->clientConnectionManager().valid()) { + al->clientConnectionManager()->sslBumpMode = finalAction; + al->clientConnectionManager()->serverBump()->act.step3 = finalAction; } al->ssl.bumpMode = finalAction; @@ -113,7 +113,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSpliceMatched(const Ssl::BumpMode acti Ssl::BumpMode Ssl::PeekingPeerConnector::checkForPeekAndSpliceGuess() const { - if (const auto csd = request->clientConnectionManager().valid()) { + if (const auto csd = al->clientConnectionManager().valid()) { const Ssl::BumpMode currentMode = csd->sslBumpMode; if (currentMode == Ssl::bumpStare) { debugs(83,5, "default to bumping after staring"); @@ -139,7 +139,7 @@ Ssl::PeekingPeerConnector::initialize(Security::SessionPointer &serverSession) if (!Security::PeerConnector::initialize(serverSession)) return false; - if (const auto csd = request->clientConnectionManager().valid()) { + if (const auto csd = al->clientConnectionManager().valid()) { // client connection is required in the case we need to splice // or terminate client and server connections @@ -211,11 +211,11 @@ void Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error) { // Check the list error with - if (!request->clientConnectionManager().valid() || !fd_table[serverConnection()->fd].ssl) + if (!al->clientConnectionManager().valid() || !fd_table[serverConnection()->fd].ssl) return; // remember the server certificate from the ErrorDetail object - if (const auto serverBump = request->clientConnectionManager()->serverBump()) { + if (const auto serverBump = al->clientConnectionManager()->serverBump()) { if (!serverBump->serverCert.get()) { // remember the server certificate from the ErrorDetail object if (error && error->detail && error->detail->peerCert()) @@ -229,7 +229,7 @@ Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error) // For intercepted connections, set the host name to the server // certificate CN. Otherwise, we just hope that CONNECT is using // a user-entered address (a host name or a user-entered IP). - const auto isConnectRequest = !request->clientConnectionManager()->port->flags.isIntercepted(); + const auto isConnectRequest = !al->clientConnectionManager()->port->flags.isIntercepted(); if (request->flags.sslPeek && !isConnectRequest) { if (X509 *srvX509 = serverBump->serverCert.get()) { if (const char *name = Ssl::CommonHostName(srvX509)) { @@ -244,7 +244,7 @@ Ssl::PeekingPeerConnector::noteNegotiationDone(ErrorState *error) if (!error) { serverCertificateVerified(); if (splice) { - switchToTunnel(request.getRaw(), clientConn, serverConn); + switchToTunnel(request.getRaw(), al, serverConn); tunnelInsteadOfNegotiating(); } } @@ -318,7 +318,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() if (serverCertificateHandled) return; - if (const auto csd = request->clientConnectionManager().valid()) { + if (const auto csd = al->clientConnectionManager().valid()) { const int fd = serverConnection()->fd; Security::SessionPointer session(fd_table[fd].ssl); Security::CertPointer serverCert(SSL_get_peer_certificate(session.get())); @@ -337,7 +337,7 @@ Ssl::PeekingPeerConnector::handleServerCertificate() void Ssl::PeekingPeerConnector::serverCertificateVerified() { - if (const auto csd = request->clientConnectionManager().valid()) { + if (const auto csd = al->clientConnectionManager().valid()) { Security::CertPointer serverCert; if(Ssl::ServerBump *serverBump = csd->serverBump()) serverCert.resetAndLock(serverBump->serverCert.get()); diff --git a/src/tunnel.cc b/src/tunnel.cc index b1a4fa3a28c..ea2984ef27c 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1003,10 +1003,10 @@ TunnelStateData::connectedToPeer(Security::EncryptorAnswer &answer) } static Comm::ConnectionPointer -borrowPinnedConnection(HttpRequest *request) +borrowPinnedConnection(HttpRequest *request, const AccessLogEntryPointer &al) { // pinned_connection may become nil after a pconn race - if (ConnStateData *pinned_connection = request ? request->pinnedConnection() : nullptr) { + if (auto pinned_connection = al->pinnedConnection()) { Comm::ConnectionPointer serverConn = pinned_connection->borrowPinnedConnection(request); return serverConn; } @@ -1117,7 +1117,7 @@ TunnelStateData::startConnecting() void TunnelStateData::usePinned() { - const auto serverConn = borrowPinnedConnection(request.getRaw()); + const auto serverConn = borrowPinnedConnection(request.getRaw(), al); debugs(26,7, "pinned peer connection: " << serverConn); if (!Comm::IsConnOpen(serverConn)) { // a PINNED path failure is fatal; do not wait for more paths @@ -1148,15 +1148,18 @@ TunnelStateData::Connection::setDelayId(DelayId const &newDelay) #if USE_OPENSSL void -switchToTunnel(HttpRequest *request, Comm::ConnectionPointer &clientConn, Comm::ConnectionPointer &srvConn) +switchToTunnel(HttpRequest *request, const AccessLogEntryPointer &al, Comm::ConnectionPointer &srvConn) { + const auto clientConn = al->tcpClient; + Must(clientConn); + debugs(26,5, "Revert to tunnel FD " << clientConn->fd << " with FD " << srvConn->fd); /* Create state structure. */ ++statCounter.server.all.requests; ++statCounter.server.other.requests; - const auto conn = request->clientConnectionManager().get(); + const auto conn = al->clientConnectionManager().get(); Must(conn); Http::StreamPointer context = conn->pipeline.front(); Must(context && context->http); From 0ff8d0f7f660ee02c660e12edcb5b1846b60c361 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 31 Oct 2019 22:14:10 +0300 Subject: [PATCH 46/66] Do not pass ALE to icap_retry We cannot do this right now because this check list is already configured with icapRequest, which is different from the request provided within the ALE. Undid the previous branch change. Note that even without ALE (conveying addresses), icap_retry checks in the branch code should work as before (when these addresses were passed via HttpRequest itself), because icapRequest lacks any client_connection/client_address/my_address information. --- src/adaptation/icap/Launcher.cc | 12 ++++++------ src/adaptation/icap/Launcher.h | 3 +-- src/adaptation/icap/Xaction.cc | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/adaptation/icap/Launcher.cc b/src/adaptation/icap/Launcher.cc index ea63995cde2..03de09d3782 100644 --- a/src/adaptation/icap/Launcher.cc +++ b/src/adaptation/icap/Launcher.cc @@ -140,8 +140,10 @@ bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info if (info.icapReply->sline.status() == Http::scNone) // failed to parse the reply; I/O err return true; + // XXX: we cannot simply pass Xaction::al here, because icapRequest and al->request + // represent different objects ACLFilledChecklist *cl = - new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, info.al, dash_str); + new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, nullptr, dash_str); cl->reply = info.icapReply; HTTPMSGLOCK(cl->reply); @@ -153,12 +155,11 @@ bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info /* ICAPXactAbortInfo */ Adaptation::Icap::XactAbortInfo::XactAbortInfo(HttpRequest *anIcapRequest, - HttpReply *anIcapReply, bool beRetriable, bool beRepeatable, const AccessLogEntry::Pointer &ale): + HttpReply *anIcapReply, bool beRetriable, bool beRepeatable): icapRequest(anIcapRequest), icapReply(anIcapReply), isRetriable(beRetriable), - isRepeatable(beRepeatable), - al(ale) + isRepeatable(beRepeatable) { if (icapRequest) HTTPMSGLOCK(icapRequest); @@ -170,8 +171,7 @@ Adaptation::Icap::XactAbortInfo::XactAbortInfo(const Adaptation::Icap::XactAbort icapRequest(i.icapRequest), icapReply(i.icapReply), isRetriable(i.isRetriable), - isRepeatable(i.isRepeatable), - al(i.al) + isRepeatable(i.isRepeatable) { if (icapRequest) HTTPMSGLOCK(icapRequest); diff --git a/src/adaptation/icap/Launcher.h b/src/adaptation/icap/Launcher.h index a0268e837be..c3c24d1ed4a 100644 --- a/src/adaptation/icap/Launcher.h +++ b/src/adaptation/icap/Launcher.h @@ -83,7 +83,7 @@ class XactAbortInfo { public: XactAbortInfo(HttpRequest *anIcapRequest, HttpReply *anIcapReply, - bool beRetriable, bool beRepeatable, const AccessLogEntry::Pointer &); + bool beRetriable, bool beRepeatable); XactAbortInfo(const XactAbortInfo &); ~XactAbortInfo(); @@ -95,7 +95,6 @@ class XactAbortInfo HttpReply *icapReply; bool isRetriable; bool isRepeatable; - AccessLogEntry::Pointer al; private: XactAbortInfo &operator =(const XactAbortInfo &); // undefined diff --git a/src/adaptation/icap/Xaction.cc b/src/adaptation/icap/Xaction.cc index 8f7e541c4bc..4597224a1df 100644 --- a/src/adaptation/icap/Xaction.cc +++ b/src/adaptation/icap/Xaction.cc @@ -620,7 +620,7 @@ void Adaptation::Icap::Xaction::tellQueryAborted() { if (theInitiator.set()) { Adaptation::Icap::XactAbortInfo abortInfo(icapRequest, icapReply.getRaw(), - retriable(), repeatable(), alep); + retriable(), repeatable()); Launcher *launcher = dynamic_cast(theInitiator.get()); // launcher may be nil if initiator is invalid CallJobHere1(91,5, CbcPointer(launcher), From 379d0fce6001743019c343f1ceb3f05af4be774f Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 4 Nov 2019 14:19:52 +0300 Subject: [PATCH 47/66] Moved HttpRequest::downloader into ALE --- src/AccessLogEntry.h | 10 ++++++++++ src/Downloader.cc | 3 ++- src/HttpRequest.cc | 6 +----- src/HttpRequest.h | 8 ++------ src/security/PeerConnector.cc | 8 ++++---- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index 3dd551fb6cc..2c39a0a1aa4 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -37,6 +37,7 @@ class HttpReply; class HttpRequest; class CustomLog; class ConnStateData; +class Downloader; class AccessLogEntry: public RefCountable { @@ -88,6 +89,10 @@ class AccessLogEntry: public RefCountable CbcPointer &clientConnectionManager() { return clientConnectionManager_; } void setClientConnectionManager(const CbcPointer &aMgr) { clientConnectionManager_ = aMgr; } + /// the Downloader of the underlying transaction, if any + CbcPointer &downloader() { return downloader_; } + void setDownloader(const CbcPointer &aDownloader) { downloader_ = aDownloader; } + ConnStateData *pinnedConnection(); SBuf url; @@ -284,7 +289,12 @@ class AccessLogEntry: public RefCountable /// Client URI (or equivalent) for effectiveVirginUrl() when HttpRequest is /// missing. This member is ignored unless the request member is nil. SBuf virginUrlForMissingRequest_; + + /// the client connection manager of this ALE transaction, if any CbcPointer clientConnectionManager_; + + /// the Downloader of this ALE transaction, if any + CbcPointer downloader_; }; class ACLChecklist; diff --git a/src/Downloader.cc b/src/Downloader.cc index 1c539d3baeb..a986062aeec 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -135,7 +135,7 @@ Downloader::buildRequest() debugs(33, 5, "Invalid URI: " << url_); return false; //earlyError(...) } - request->prepareForDownloader(this); + request->prepareForDownloader(); debugs(11, 2, "HTTP Client Downloader " << this << "/" << id); debugs(11, 2, "HTTP Client REQUEST:\n---------\n" << @@ -143,6 +143,7 @@ Downloader::buildRequest() "\n----------"); ClientHttpRequest *const http = new ClientHttpRequest(nullptr); + http->al->setDownloader(this); http->initRequest(request); http->req_sz = 0; // XXX: performance regression. c_str() reallocates diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 9e53ef526ec..d7beb38ca59 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -16,7 +16,6 @@ #include "client_side.h" #include "client_side_request.h" #include "dns/LookupDetails.h" -#include "Downloader.h" #include "err_detail_type.h" #include "globals.h" #include "gopher.h" @@ -250,8 +249,6 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) forcedBodyContinuation = aReq->forcedBodyContinuation; - downloader = aReq->downloader; - theNotes = aReq->theNotes; sources = aReq->sources; @@ -722,11 +719,10 @@ UpdateRequestNotes(HttpRequest &request, NotePairs const &helperNotes) } void -HttpRequest::prepareForDownloader(Downloader *aDownloader) +HttpRequest::prepareForDownloader() { header.putStr(Http::HdrType::HOST, url.host()); header.putTime(Http::HdrType::DATE, squid_curtime); - downloader = aDownloader; } void diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 3064049f6fd..12f02a1050c 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -38,7 +38,6 @@ class AccessLogEntry; typedef RefCount AccessLogEntryPointer; class CachePeer; class ConnStateData; -class Downloader; /* Http Request */ void httpRequestPack(void *obj, Packable *p); @@ -152,8 +151,8 @@ class HttpRequest: public Http::Message /// whether this request was initiated by Squid (rather than received on a client connection) bool selfInitiated() const { return selfInitiated_; } - /// supply Downloader-specific settings - void prepareForDownloader(Downloader *); + /// configure with Downloader-specific settings + void prepareForDownloader(); HierarchyLogEntry hier; @@ -219,9 +218,6 @@ class HttpRequest: public Http::Message */ const SBuf storeId(); - /// The Downloader object which initiated the HTTP request if any - CbcPointer downloader; - /// the master transaction this request belongs to. Never nil. MasterXaction::Pointer masterXaction; diff --git a/src/security/PeerConnector.cc b/src/security/PeerConnector.cc index b01878e825b..dcbae9136f1 100644 --- a/src/security/PeerConnector.cc +++ b/src/security/PeerConnector.cc @@ -629,7 +629,7 @@ Security::PeerConnector::startCertDownloading(SBuf &url) "Security::PeerConnector::certDownloadingDone", PeerConnectorCertDownloaderDialer(&Security::PeerConnector::certDownloadingDone, this)); - const Downloader *csd = (request ? dynamic_cast(request->downloader.valid()) : nullptr); + const auto csd = al->downloader().get(); Downloader *dl = new Downloader(url, certCallback, XactionInitiator::initCertFetcher, csd ? csd->nestedLevel() + 1 : 1); AsyncJob::Start(dl); } @@ -684,9 +684,9 @@ Security::PeerConnector::checkForMissingCertificates() // certificate located in an SSL site which requires to download a // a missing certificate (... from an SSL site which requires to ...). - const Downloader *csd = (request ? request->downloader.get() : nullptr); - if (csd && csd->nestedLevel() >= MaxNestedDownloads) - return false; + if (const auto csd = al->downloader().get()) + if (csd->nestedLevel() >= MaxNestedDownloads) + return false; const int fd = serverConnection()->fd; Security::SessionPointer session(fd_table[fd].ssl); From a5edd7b0e1c5eb44a08735e7526b52d42bcfccbd Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 4 Nov 2019 16:56:16 +0300 Subject: [PATCH 48/66] Removing HttpRequest address-related leftovers and polishing --- src/Downloader.cc | 2 +- src/FwdState.cc | 2 +- src/HttpRequest.cc | 14 ++------------ src/HttpRequest.h | 17 ++--------------- 4 files changed, 6 insertions(+), 29 deletions(-) diff --git a/src/Downloader.cc b/src/Downloader.cc index a986062aeec..f1cc0e06a56 100644 --- a/src/Downloader.cc +++ b/src/Downloader.cc @@ -135,7 +135,7 @@ Downloader::buildRequest() debugs(33, 5, "Invalid URI: " << url_); return false; //earlyError(...) } - request->prepareForDownloader(); + request->prepForDownloader(); debugs(11, 2, "HTTP Client Downloader " << this << "/" << id); debugs(11, 2, "HTTP Client REQUEST:\n---------\n" << diff --git a/src/FwdState.cc b/src/FwdState.cc index a054b799267..f05a54727d2 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -1472,7 +1472,7 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn, AccessLo return; // anything will do. } - ACLFilledChecklist ch(NULL, request, al, nullptr); + ACLFilledChecklist ch(nullptr, request, al, nullptr); ch.dst_peer_name = conn->getPeer() ? conn->getPeer()->name : NULL; ch.dst_addr = conn->remote; // TODO: ch.syncAle(request, nullptr); diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index d7beb38ca59..89b54b77b56 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -85,8 +85,6 @@ HttpRequest::init() ims = -1; imslen = 0; lastmod = -1; - client_addr.setEmpty(); - my_addr.setEmpty(); body_pipe = NULL; // hier dnsWait = -1; @@ -104,9 +102,6 @@ HttpRequest::init() extacl_log = null_string; extacl_message = null_string; pstate = Http::Message::psReadyToParseStartLine; -#if FOLLOW_X_FORWARDED_FOR - indirect_client_addr.setEmpty(); -#endif /* FOLLOW_X_FORWARDED_FOR */ #if USE_ADAPTATION adaptHistory_ = NULL; #endif @@ -220,12 +215,6 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) if (!aReq) return false; - client_addr = aReq->client_addr; -#if FOLLOW_X_FORWARDED_FOR - indirect_client_addr = aReq->indirect_client_addr; -#endif - my_addr = aReq->my_addr; - dnsWait = aReq->dnsWait; #if USE_ADAPTATION @@ -719,10 +708,11 @@ UpdateRequestNotes(HttpRequest &request, NotePairs const &helperNotes) } void -HttpRequest::prepareForDownloader() +HttpRequest::prepForDownloader() { header.putStr(Http::HdrType::HOST, url.host()); header.putTime(Http::HdrType::DATE, squid_curtime); + debugs(11, 4, this); } void diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 12f02a1050c..c4c432b346b 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -93,6 +93,8 @@ class HttpRequest: public Http::Message void prepForPeering(const CachePeer &peer); /// get ready to be sent directly to an origin server, excluding originserver void prepForDirect(); + /// configure with Downloader-specific settings + void prepForDownloader(); void recordLookup(const Dns::LookupDetails &detail); @@ -148,12 +150,6 @@ class HttpRequest: public Http::Message int imslen; - /// whether this request was initiated by Squid (rather than received on a client connection) - bool selfInitiated() const { return selfInitiated_; } - - /// configure with Downloader-specific settings - void prepareForDownloader(); - HierarchyLogEntry hier; int dnsWait; ///< sum of DNS lookup delays in milliseconds, for %dt @@ -246,15 +242,6 @@ class HttpRequest: public Http::Message /// and(or) by annotate_transaction/annotate_client ACLs. NotePairs::Pointer theNotes; - Ip::Address client_addr; ///< source address of a non-TCP (e.g. ICMP) client - Ip::Address my_addr; ///< local address which a non-TCP (e.g., ICMP) client connects to -#if FOLLOW_X_FORWARDED_FOR - Ip::Address indirect_client_addr; ///< calculated client address, after applying X-Forwarded-For rules -#endif - - /// whether this request was spawned by Squid itself - bool selfInitiated_; - protected: virtual void packFirstLineInto(Packable * p, bool full_uri) const; From 37e3f53c4f684153fa04ea619954bd7dab7b02d7 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Fri, 8 Nov 2019 21:15:44 +0300 Subject: [PATCH 49/66] Added missing ACLFilledChecklist::syncAle() after construction Previous commits provided ALE in several contexts, so we need to 'sync' ALE there. Also I fixed few old contexts which lacked syncAle(), such as UrnState::fillChecklist(). --- src/DelayId.cc | 1 + src/FwdState.cc | 3 +++ src/HttpHeaderTools.cc | 2 ++ src/HttpReply.cc | 1 + src/HttpRequest.cc | 1 + src/ICP.h | 2 +- src/acl/FilledChecklist.cc | 1 + src/auth/UserRequest.cc | 1 + src/client_side.cc | 10 ++++++++-- src/clients/Client.cc | 1 + src/clients/FtpClient.cc | 1 + src/htcp.cc | 21 +++++++++------------ src/icp_v2.cc | 8 ++++---- src/icp_v3.cc | 5 ++--- src/urn.cc | 1 + 15 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index 5b4d55a8102..ac5e08939b6 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -86,6 +86,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) } ACLFilledChecklist ch(DelayPools::delay_data[pool].access, r, http->al, nullptr); + ch.syncAle(r, http->log_uri); if (reply) { ch.reply = reply; HTTPMSGLOCK(reply); diff --git a/src/FwdState.cc b/src/FwdState.cc index f05a54727d2..cde2257e340 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -1473,6 +1473,7 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn, AccessLo } ACLFilledChecklist ch(nullptr, request, al, nullptr); + ch.syncAle(request, nullptr); ch.dst_peer_name = conn->getPeer() ? conn->getPeer()->name : NULL; ch.dst_addr = conn->remote; // TODO: ch.syncAle(request, nullptr); @@ -1497,6 +1498,7 @@ tos_t GetTosToServer(HttpRequest * request, const AccessLogEntry::Pointer &al) { ACLFilledChecklist ch(NULL, request, al, nullptr); + ch.syncAle(request, nullptr); return aclMapTOS(Ip::Qos::TheConfig.tosToServer, &ch); } @@ -1504,6 +1506,7 @@ nfmark_t GetNfmarkToServer(HttpRequest * request, const AccessLogEntry::Pointer &al) { ACLFilledChecklist ch(nullptr, request, al, nullptr); + ch.syncAle(request, nullptr); const auto mc = aclFindNfMarkConfig(Ip::Qos::TheConfig.nfmarkToServer, &ch); return mc.mark; } diff --git a/src/HttpHeaderTools.cc b/src/HttpHeaderTools.cc index 4c9b3c5d550..cc6eb5611be 100644 --- a/src/HttpHeaderTools.cc +++ b/src/HttpHeaderTools.cc @@ -288,6 +288,7 @@ httpHdrMangle(HttpHeaderEntry *e, HttpRequest * request, HeaderManglers *hms, co } ACLFilledChecklist checklist(hm->access_list, request, al, nullptr); + checklist.syncAle(request, nullptr); if (checklist.fastCheck().allowed()) { /* aclCheckFast returns true for allow. */ @@ -477,6 +478,7 @@ void httpHdrAdd(HttpHeader *heads, HttpRequest *request, const AccessLogEntryPointer &al, HeaderWithAclList &headersAdd) { ACLFilledChecklist checklist(nullptr, request, al, nullptr); + checklist.syncAle(request, nullptr); for (HeaderWithAclList::const_iterator hwa = headersAdd.begin(); hwa != headersAdd.end(); ++hwa) { if (!hwa->aclList || checklist.fastCheck(hwa->aclList).allowed()) { diff --git a/src/HttpReply.cc b/src/HttpReply.cc index 16500cac586..b3b0b395485 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -551,6 +551,7 @@ HttpReply::calcMaxBodySize(HttpRequest& request, const AccessLogEntry::Pointer & return; ACLFilledChecklist ch(nullptr, &request, al, nullptr); + ch.syncAle(&request, nullptr); // XXX: cont-cast becomes irrelevant when checklist is HttpReply::Pointer ch.reply = const_cast(this); HTTPMSGLOCK(ch.reply); diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 89b54b77b56..59f8b0f018e 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -613,6 +613,7 @@ HttpRequest::getRangeOffsetLimit(const AccessLogEntry::Pointer &al) rangeOffsetLimit = 0; // default value for rangeOffsetLimit ACLFilledChecklist ch(nullptr, this, al, nullptr); + ch.syncAle(this, nullptr); for (AclSizeLimit *l = Config.rangeOffsetLimit; l; l = l -> next) { /* if there is no ACL list or if the ACLs listed match use this limit value */ diff --git a/src/ICP.h b/src/ICP.h index 54f886db705..0a4ebbc9bb5 100644 --- a/src/ICP.h +++ b/src/ICP.h @@ -97,7 +97,7 @@ extern Ip::Address theIcpPublicHostID; HttpRequest* icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from); /// \ingroup ServerProtocolICPAPI -bool icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const AccessLogEntryPointer &al); +bool icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const char *url, AccessLogEntryPointer &al); /// \ingroup ServerProtocolICPAPI void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from, AccessLogEntryPointer); diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 0d4eae28233..7c0abdca7fa 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -134,6 +134,7 @@ ACLFilledChecklist::syncAle(HttpRequest *adaptedRequest, const char *logUri) con { if (!al) return; + // TODO: move this into the constructor if (adaptedRequest && !al->adapted_request) { al->adapted_request = adaptedRequest; HTTPMSGLOCK(al->adapted_request); diff --git a/src/auth/UserRequest.cc b/src/auth/UserRequest.cc index 90aaa682e31..962e77d48a4 100644 --- a/src/auth/UserRequest.cc +++ b/src/auth/UserRequest.cc @@ -466,6 +466,7 @@ schemesConfig(HttpRequest *request, HttpReply *rep, const AccessLogEntryPointer { if (!Auth::TheConfig.schemeLists.empty() && Auth::TheConfig.schemeAccess) { ACLFilledChecklist ch(nullptr, request, al, nullptr); + ch.syncAle(request, nullptr); ch.reply = rep; HTTPMSGLOCK(ch.reply); const auto answer = ch.fastCheck(Auth::TheConfig.schemeAccess); diff --git a/src/client_side.cc b/src/client_side.cc index 9361be9af7e..3d6fbcf3780 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2701,8 +2701,14 @@ void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &cer if (X509 *mimicCert = sslServerBump->serverCert.get()) certProperties.mimicCert.resetAndLock(mimicCert); - ACLFilledChecklist checklist(nullptr, sslServerBump->request.getRaw(), nullptr, // XXX + Http::StreamPointer context = pipeline.front(); + + const auto http = context ? context->http : nullptr; + const auto log_uri = http ? http->log_uri : nullptr; + + ACLFilledChecklist checklist(nullptr, sslServerBump->request.getRaw(), http ? http->al : nullptr, clientConnection != NULL ? clientConnection->rfc931 : dash_str); + checklist.syncAle(sslServerBump->request.getRaw(), log_uri); checklist.setClientConnectionDetails(this); checklist.sslErrors = cbdataReference(sslServerBump->sslErrors()); @@ -3542,8 +3548,8 @@ void clientAclChecklistFill(ACLFilledChecklist &checklist, ClientHttpRequest *http) { checklist.setRequest(http->request); - checklist.syncAle(http->request, http->log_uri); checklist.al = http->al; + checklist.syncAle(http->request, http->log_uri); // TODO: If http->getConn is always http->request->clientConnectionManager, // then call setIdent() inside checklist.setRequest(). Otherwise, restore // USE_IDENT lost in commit 94439e4. diff --git a/src/clients/Client.cc b/src/clients/Client.cc index e1f022d9f74..edd627b94b9 100644 --- a/src/clients/Client.cc +++ b/src/clients/Client.cc @@ -521,6 +521,7 @@ Client::blockCaching() // This relatively expensive check is not in StoreEntry::checkCachable: // That method lacks HttpRequest and may be called too many times. ACLFilledChecklist ch(acl, originalRequest().getRaw(), fwd->al, nullptr); + ch.syncAle(request.getRaw(), nullptr); ch.reply = const_cast(entry->getReply()); // ACLFilledChecklist API bug HTTPMSGLOCK(ch.reply); if (!ch.fastCheck().allowed()) { // when in doubt, block diff --git a/src/clients/FtpClient.cc b/src/clients/FtpClient.cc index f8878ee5ed5..c5000c4b104 100644 --- a/src/clients/FtpClient.cc +++ b/src/clients/FtpClient.cc @@ -705,6 +705,7 @@ Ftp::Client::sendPassive() bool doEpsv = true; if (Config.accessList.ftp_epsv) { ACLFilledChecklist checklist(Config.accessList.ftp_epsv, fwd->request, fwd->al, nullptr); + checklist.syncAle(fwd->request, nullptr); doEpsv = checklist.fastCheck().allowed(); } if (!doEpsv) { diff --git a/src/htcp.cc b/src/htcp.cc index 591e0beaf99..412ba7e9eb4 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -139,13 +139,10 @@ class htcpSpecifier : public RefCountable, public StoreClient assert(request); return al->clientAddr(); } - void setAddresses(Ip::Address &fromAddr) { - htcpSyncAle(al, fromAddr, dhdr->opcode, uri); - al->setClientAddr(fromAddr); - al->setMyAddr(htcpIncomingConn->local); - } - void setDataHeader(htcpDataHeader *aDataHeader) { + + void initFields(htcpDataHeader *aDataHeader, Ip::Address &fromAddr) { dhdr = aDataHeader; + htcpSyncAle(al, fromAddr, dhdr->opcode, uri); } /* StoreClient API */ @@ -291,6 +288,8 @@ htcpSyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const int opcod al->cache.start_time = current_time; al->cache.trTime.tv_sec = 0; al->cache.trTime.tv_usec = 0; + al->setClientAddr(caddr); + al->setMyAddr(htcpIncomingConn->local); } static void @@ -1140,11 +1139,10 @@ htcpHandleTstRequest(htcpDataHeader * dhdr, char *buf, int sz, Ip::Address &from debugs(31, 3, "htcpHandleTstRequest: htcpUnpackSpecifier failed"); htcpLogHtcp(from, dhdr->opcode, LOG_UDP_INVALID, dash_str, nullptr); return; - } else { - s->setAddresses(from); - s->setDataHeader(dhdr); } + s->initFields(dhdr, from); + if (!s->request) { debugs(31, 3, "htcpHandleTstRequest: failed to parse request"); htcpLogHtcp(from, dhdr->opcode, LOG_UDP_INVALID, dash_str, s->al); @@ -1197,11 +1195,10 @@ htcpHandleClr(htcpDataHeader * hdr, char *buf, int sz, Ip::Address &from) debugs(31, 3, "htcpHandleClr: htcpUnpackSpecifier failed"); htcpLogHtcp(from, hdr->opcode, LOG_UDP_INVALID, dash_str, nullptr); return; - } else { - s->setDataHeader(hdr); - s->setAddresses(from); } + s->initFields(hdr, from); + if (!s->request) { debugs(31, 3, "htcpHandleTstRequest: failed to parse request"); htcpLogHtcp(from, hdr->opcode, LOG_UDP_INVALID, dash_str, s->al); diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 30650bfea43..b6fe417baa5 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -468,12 +468,13 @@ icpDenyAccess(Ip::Address &from, char *url, int reqnum, int fd) } bool -icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const AccessLogEntryPointer &al) +icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const char *url, AccessLogEntryPointer &al) { /* absent any explicit rules, we deny all */ if (!Config.accessList.icp) return false; + ICPState::SyncAle(al, from, url, 0, 0); ACLFilledChecklist checklist(Config.accessList.icp, icp_request, al, nullptr); return checklist.fastCheck().allowed(); } @@ -520,10 +521,9 @@ doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header) HTTPMSGLOCK(icp_request); - AccessLogEntryPointer al = new AccessLogEntry(); - ICPState::SyncAle(al, from, url, 0, 0); + AccessLogEntryPointer al; - if (!icpAccessAllowed(from, icp_request, al)) { + if (!icpAccessAllowed(from, icp_request, url, al)) { icpDenyAccess(from, url, header.reqnum, fd); HTTPMSGUNLOCK(icp_request); return; diff --git a/src/icp_v3.cc b/src/icp_v3.cc index c4260be79b9..492ca6a1248 100644 --- a/src/icp_v3.cc +++ b/src/icp_v3.cc @@ -42,10 +42,9 @@ doV3Query(int fd, Ip::Address &from, char *buf, icp_common_t header) if (!icp_request) return; - AccessLogEntryPointer al = new AccessLogEntry(); - ICPState::SyncAle(al, from, url, 0, 0); + AccessLogEntryPointer al; - if (!icpAccessAllowed(from, icp_request, al)) { + if (!icpAccessAllowed(from, icp_request, url, al)) { icpDenyAccess (from, url, header.reqnum, fd); delete icp_request; return; diff --git a/src/urn.cc b/src/urn.cc index 398bc4d5c7b..b0af10c96ba 100644 --- a/src/urn.cc +++ b/src/urn.cc @@ -194,6 +194,7 @@ UrnState::fillChecklist(ACLFilledChecklist &checklist) const { checklist.setRequest(request.getRaw()); checklist.al = ale; + checklist.syncAle(request.getRaw(), nullptr); } void From 54777e140f798f56c2184a9f63ba3cd5669f5c8d Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Fri, 8 Nov 2019 21:49:19 +0300 Subject: [PATCH 50/66] ICPState::ICPState() always gets non-nil ALE --- src/icp_v2.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/icp_v2.cc b/src/icp_v2.cc index b6fe417baa5..52294106e44 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -148,6 +148,7 @@ ICPState::ICPState(icp_common_t &aHeader, HttpRequest *aRequest, const AccessLog url(nullptr), al(ale) { + assert(al); // created already in icpAccessAllowed() HTTPMSGLOCK(request); } @@ -176,8 +177,6 @@ LogTags * ICPState::loggingTags() { // calling SyncAle(LOG_TAG_NONE) here would not change cache.code - if (!al) - al = new AccessLogEntry(); return &al->cache.code; } From 7372011e2d8dc9926156bfcef19a7ccf178487fe Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sun, 10 Nov 2019 16:01:22 +0300 Subject: [PATCH 51/66] Made unit tests happy --- src/Makefile.am | 3 +++ src/tests/stub_AccessLogEntry.cc | 20 ++++++++++++++++++++ src/tests/stub_HttpRequest.cc | 10 +--------- src/tests/stub_icp.cc | 2 +- src/tests/stub_libauth.cc | 4 +++- src/tests/stub_tunnel.cc | 2 +- 6 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 src/tests/stub_AccessLogEntry.cc diff --git a/src/Makefile.am b/src/Makefile.am index 2a767bdcc23..8b268f27ee0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1534,6 +1534,7 @@ tests_testStore_SOURCES= \ tests/CapturingStoreEntry.h \ log/access_log.h \ tests/stub_access_log.cc \ + tests/stub_AccessLogEntry.cc \ tests/stub_acl.cc \ cache_cf.h \ tests/stub_cache_cf.cc \ @@ -1817,6 +1818,7 @@ nodist_tests_testACLMaxUserIP_SOURCES = \ Parsing.cc \ String.cc \ tests/stub_access_log.cc \ + tests/stub_AccessLogEntry.cc \ tests/stub_cache_cf.cc \ tests/stub_cbdata.cc \ tests/stub_client_side.cc \ @@ -2177,6 +2179,7 @@ tests_testHttpReply_SOURCES=\ Notes.cc \ SquidString.h \ SquidTime.h \ + tests/stub_AccessLogEntry.cc \ tests/stub_SBufDetailedStats.cc \ String.cc \ StrList.h \ diff --git a/src/tests/stub_AccessLogEntry.cc b/src/tests/stub_AccessLogEntry.cc new file mode 100644 index 00000000000..ead491fff2a --- /dev/null +++ b/src/tests/stub_AccessLogEntry.cc @@ -0,0 +1,20 @@ +/* + * Copyright (C) 1996-2019 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#include "squid.h" +#include "AccessLogEntry.h" + +#define STUB_API "AccessLogEntry.cc" +#include "tests/STUB.h" + +#if FOLLOW_X_FORWARDED_FOR +const Ip::Address& AccessLogEntry::furthestClientAddress() const STUB_RETREF(Ip::Address) +#endif +const Ip::Address& AccessLogEntry::clientAddr() const STUB_RETREF(Ip::Address) +const Ip::Address& AccessLogEntry::myAddr() const STUB_RETREF(Ip::Address) + diff --git a/src/tests/stub_HttpRequest.cc b/src/tests/stub_HttpRequest.cc index 28aaddd16fe..84873903234 100644 --- a/src/tests/stub_HttpRequest.cc +++ b/src/tests/stub_HttpRequest.cc @@ -50,20 +50,12 @@ void HttpRequest::pack(Packable *) const STUB void HttpRequest::httpRequestPack(void *, Packable *) STUB HttpRequest * HttpRequest::FromUrl(const SBuf &, const MasterXaction::Pointer &, const HttpRequestMethod &) STUB_RETVAL(nullptr) HttpRequest * HttpRequest::FromUrlXXX(const char *, const MasterXaction::Pointer &, const HttpRequestMethod &) STUB_RETVAL(nullptr) -ConnStateData *HttpRequest::pinnedConnection() STUB_RETVAL(NULL) const SBuf HttpRequest::storeId() STUB_RETVAL(SBuf(".")) void HttpRequest::ignoreRange(const char *) STUB -int64_t HttpRequest::getRangeOffsetLimit() STUB_RETVAL(0) +int64_t HttpRequest::getRangeOffsetLimit(const AccessLogEntry::Pointer &) STUB_RETVAL(0) void HttpRequest::packFirstLineInto(Packable *, bool) const STUB bool HttpRequest::sanityCheckStartLine(const char *, const size_t, Http::StatusCode *) STUB_RETVAL(false) void HttpRequest::hdrCacheInit() STUB bool HttpRequest::inheritProperties(const Http::Message *) STUB_RETVAL(false) -#if FOLLOW_X_FORWARDED_FOR -const Ip::Address& HttpRequest::furthestClientAddress() const STUB_RETREF(Ip::Address) -#endif -const Ip::Address& HttpRequest::clientAddr() const STUB_RETREF(Ip::Address) -const Ip::Address& HttpRequest::myAddr() const STUB_RETREF(Ip::Address) -Comm::ConnectionPointer HttpRequest::clientConnection() const STUB -CbcPointer &HttpRequest::clientConnectionManager() STUB_RETREF(CbcPointer) NotePairs::Pointer HttpRequest::notes() STUB_RETVAL(NotePairs::Pointer()) diff --git a/src/tests/stub_icp.cc b/src/tests/stub_icp.cc index cc65493fb04..348ed6bbe14 100644 --- a/src/tests/stub_icp.cc +++ b/src/tests/stub_icp.cc @@ -19,7 +19,7 @@ icp_common_t::icp_common_t(char *buf, unsigned int len) STUB void icp_common_t::handleReply(char *buf, Ip::Address &from) STUB icp_common_t *icp_common_t::CreateMessage(icp_opcode opcode, int flags, const char *url, int reqnum, int pad) STUB_RETVAL(nullptr) icp_opcode icp_common_t::getOpCode() const STUB_RETVAL(ICP_INVALID) -ICPState::ICPState(icp_common_t &aHeader, HttpRequest *aRequest) STUB +ICPState::ICPState(icp_common_t &aHeader, HttpRequest *aRequest, const AccessLogEntryPointer &) STUB ICPState::~ICPState() STUB bool ICPState::confirmAndPrepHit(const StoreEntry &) STUB_RETVAL(false) LogTags *ICPState::loggingTags() STUB_RETVAL(nullptr) diff --git a/src/tests/stub_libauth.cc b/src/tests/stub_libauth.cc index 7484ce237c6..b654d71a2ce 100644 --- a/src/tests/stub_libauth.cc +++ b/src/tests/stub_libauth.cc @@ -8,6 +8,8 @@ #include "squid.h" +#include "AccessLogEntry.h" + #define STUB_API "auth/libauth.la" #include "STUB.h" @@ -72,7 +74,7 @@ void Auth::UserRequest::releaseAuthServer() STUB const char * Auth::UserRequest::connLastHeader() STUB_RETVAL("stub") AuthAclState Auth::UserRequest::authenticate(Auth::UserRequest::Pointer *, Http::HdrType, HttpRequest *, ConnStateData *, const Ip::Address &, AccessLogEntry::Pointer &) STUB_RETVAL(AUTH_AUTHENTICATED) AuthAclState Auth::UserRequest::tryToAuthenticateAndSetAuthUser(Auth::UserRequest::Pointer *, Http::HdrType, HttpRequest *, ConnStateData *, const Ip::Address &, AccessLogEntry::Pointer &) STUB_RETVAL(AUTH_AUTHENTICATED) -void Auth::UserRequest::AddReplyAuthHeader(HttpReply *, Auth::UserRequest::Pointer, HttpRequest *, int, int) STUB +void Auth::UserRequest::AddReplyAuthHeader(HttpReply *, Auth::UserRequest::Pointer, HttpRequest *, int, int, const AccessLogEntry::Pointer &al) STUB Auth::Scheme::Pointer Auth::UserRequest::scheme() const STUB_RETVAL(NULL) #include "AuthReg.h" diff --git a/src/tests/stub_tunnel.cc b/src/tests/stub_tunnel.cc index cdf062628ec..83fbdd963b7 100644 --- a/src/tests/stub_tunnel.cc +++ b/src/tests/stub_tunnel.cc @@ -16,5 +16,5 @@ class ClientHttpRequest; void tunnelStart(ClientHttpRequest *) STUB -void switchToTunnel(HttpRequest *request, Comm::ConnectionPointer &clientConn, Comm::ConnectionPointer &srvConn) STUB +void switchToTunnel(HttpRequest *request, const AccessLogEntry::Pointer &al, Comm::ConnectionPointer &srvConn) STUB From 4e73210ceff552af056bf9b8ff92d404103e228a Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sun, 10 Nov 2019 16:10:27 +0300 Subject: [PATCH 52/66] Applied auto-format rules --- src/AccessLogEntry.cc | 2 +- src/store_client.cc | 2 +- src/tests/Stub.list | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/AccessLogEntry.cc b/src/AccessLogEntry.cc index 7af628c65ed..b44424e7a42 100644 --- a/src/AccessLogEntry.cc +++ b/src/AccessLogEntry.cc @@ -9,8 +9,8 @@ #include "squid.h" #include "AccessLogEntry.h" #include "client_side.h" -#include "HttpReply.h" #include "http/Stream.h" +#include "HttpReply.h" #include "HttpRequest.h" #include "MemBuf.h" #include "proxyp/Header.h" diff --git a/src/store_client.cc b/src/store_client.cc index 168d517ed89..4a0d0ec814b 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -14,8 +14,8 @@ #include "client_side_request.h" #include "event.h" #include "globals.h" -#include "HttpReply.h" #include "http/Stream.h" +#include "HttpReply.h" #include "HttpRequest.h" #include "MemBuf.h" #include "MemObject.h" diff --git a/src/tests/Stub.list b/src/tests/Stub.list index a96c3f92de5..c42a45f99fa 100644 --- a/src/tests/Stub.list +++ b/src/tests/Stub.list @@ -8,6 +8,7 @@ STUB_SOURCE= tests/STUB.h \ tests/stub_access_log.cc \ + tests/stub_AccessLogEntry.cc \ tests/stub_acl.cc \ tests/stub_cache_cf.cc \ tests/stub_CacheDigest.cc \ From cfb2feed77888ff2353b162bf2717e8c6c0cc5f1 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 11 Nov 2019 14:00:05 +0300 Subject: [PATCH 53/66] Removed ACLFilledChecklist::al assignment leftovers and polishing --- src/AccessLogEntry.h | 17 +++++++++-------- src/HttpHeaderTools.cc | 2 -- src/HttpRequest.h | 1 + src/client_side.cc | 3 +-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index f771cf45c2d..da332db024b 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -72,9 +72,6 @@ class AccessLogEntry: public CodeContext void syncNotes(HttpRequest *request); - /// the source address of the client connection - const Ip::Address& clientAddr() const; - #if FOLLOW_X_FORWARDED_FOR /// Indirect client address, if available, otherwise clientAddr(). const Ip::Address& furthestClientAddress() const; @@ -84,6 +81,9 @@ class AccessLogEntry: public CodeContext /// forces furthestClientAddress() to return a direct client address void ignoreIndirectClientAddr(); #endif + /// the source address of the client connection + const Ip::Address& clientAddr() const; + /// specify the source client address manually when lacking client connection void setClientAddr(const Ip::Address &fromAddr) { client_addr = fromAddr; } @@ -110,11 +110,6 @@ class AccessLogEntry: public CodeContext /// TCP/IP level details about the client connection Comm::ConnectionPointer tcpClient; -#if FOLLOW_X_FORWARDED_FOR - Ip::Address indirect_client_addr; ///< calculated client address, after applying X-Forwarded-For rules -#endif - Ip::Address client_addr; ///< source address of a non-TCP (e.g. ICMP) client - Ip::Address my_addr; ///< local address which a non-TCP (e.g., ICMP) client connects to // TCP/IP level details about the server or peer connection // are stored in hier.tcpServer @@ -296,6 +291,12 @@ class AccessLogEntry: public CodeContext } private: +#if FOLLOW_X_FORWARDED_FOR + Ip::Address indirect_client_addr; ///< calculated client address, after applying X-Forwarded-For rules +#endif + Ip::Address client_addr; ///< source address of a non-TCP (e.g. ICMP) client + Ip::Address my_addr; ///< local address which a non-TCP (e.g., ICMP) client connects to + /// Client URI (or equivalent) for effectiveVirginUrl() when HttpRequest is /// missing. This member is ignored unless the request member is nil. SBuf virginUrlForMissingRequest_; diff --git a/src/HttpHeaderTools.cc b/src/HttpHeaderTools.cc index 18af88e525d..4f1934ef513 100644 --- a/src/HttpHeaderTools.cc +++ b/src/HttpHeaderTools.cc @@ -289,8 +289,6 @@ httpHdrMangle(HttpHeaderEntry * e, HttpRequest * request, HeaderManglers *hms, c ACLFilledChecklist checklist(hm->access_list, request, al, nullptr); checklist.syncAle(request, nullptr); - - checklist.al = al; if (al && al->reply) { checklist.reply = al->reply.getRaw(); HTTPMSGLOCK(checklist.reply); diff --git a/src/HttpRequest.h b/src/HttpRequest.h index cc6a9a7c5e8..a1f28f923d9 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -241,6 +241,7 @@ class HttpRequest: public Http::Message private: mutable int64_t rangeOffsetLimit; /* caches the result of getRangeOffsetLimit */ + // TODO: remove and use ALE::notes instead /// annotations added by the note directive and helpers /// and(or) by annotate_transaction/annotate_client ACLs. NotePairs::Pointer theNotes; diff --git a/src/client_side.cc b/src/client_side.cc index 3efe2c6cb65..6714118979d 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1569,9 +1569,8 @@ ConnStateData::tunnelOnError(const HttpRequestMethod &method, const err_type req const auto http = context ? context->http : nullptr; const auto request = http ? http->request : nullptr; - const auto ale = (context && context->http) ? context->http->al : nullptr; + const auto ale = http ? http->al : nullptr; ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request, ale, nullptr); - checklist.al = http ? http->al : nullptr; checklist.requestErrorType = requestError; checklist.setClientConnectionDetails(this); const char *log_uri = http ? http->log_uri : nullptr; From 4976230f091a292da364a328f076c59fc4f5ccaa Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 19 Nov 2019 16:41:12 +0300 Subject: [PATCH 54/66] A couple of ALE-related improvements * Create ALE early, in ConnStateData constructor. ConnStateData::al is used for the first transaction on the connection: 1. by some early ACL checks (ssl_bump), instead of creating multiple temporary local ALE objects. 2. by ClientHttpRequest * Do not pass 'ident' to ACLFilledChecklist constructor, take it from ALE object. --- src/DelayId.cc | 2 +- src/FwdState.cc | 10 ++--- src/HttpHeaderTools.cc | 4 +- src/HttpReply.cc | 2 +- src/HttpRequest.cc | 4 +- src/Notes.cc | 2 +- src/acl/FilledChecklist.cc | 4 +- src/acl/FilledChecklist.h | 2 +- src/adaptation/AccessCheck.cc | 2 +- src/adaptation/icap/Launcher.cc | 2 +- src/adaptation/icap/icap_log.cc | 2 +- src/auth/UserRequest.cc | 2 +- src/client_side.cc | 68 +++++++++++++++------------------ src/client_side.h | 2 + src/client_side_request.cc | 36 ++++++++--------- src/clients/Client.cc | 2 +- src/clients/FtpClient.cc | 2 +- src/comm/TcpAcceptor.cc | 3 +- src/htcp.cc | 2 +- src/icp_v2.cc | 2 +- src/neighbors.cc | 2 +- src/peer_select.cc | 4 +- src/security/PeerConnector.cc | 4 +- src/servers/FtpServer.cc | 2 +- src/servers/Http1Server.cc | 2 +- src/snmp_core.cc | 2 +- src/ssl/PeekingPeerConnector.cc | 4 +- src/store_client.cc | 2 +- src/tunnel.cc | 2 +- 29 files changed, 87 insertions(+), 92 deletions(-) diff --git a/src/DelayId.cc b/src/DelayId.cc index ac5e08939b6..a8adb10305e 100644 --- a/src/DelayId.cc +++ b/src/DelayId.cc @@ -85,7 +85,7 @@ DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply) continue; } - ACLFilledChecklist ch(DelayPools::delay_data[pool].access, r, http->al, nullptr); + ACLFilledChecklist ch(DelayPools::delay_data[pool].access, r, http->al); ch.syncAle(r, http->log_uri); if (reply) { ch.reply = reply; diff --git a/src/FwdState.cc b/src/FwdState.cc index 4f77d9e6520..20ae94ed0e5 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -330,7 +330,7 @@ FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, Ht { if (Config.accessList.miss && !al->clientAddr().isEmpty() && request->needCheckMissAccess()) { // Check if this host is allowed to fetch MISSES from us (miss_access). - ACLFilledChecklist ch(Config.accessList.miss, request, al, nullptr); + ACLFilledChecklist ch(Config.accessList.miss, request, al); // TODO: Explain this acl_uses_indirect_client violation in squid.conf. // TODO: Refer to the above squid.conf documentation here. ch.forceDirectAddr(); @@ -982,7 +982,7 @@ FwdState::connectStart() cs->setHost(request->url.host()); bool retriable = checkRetriable(); if (!retriable && Config.accessList.serverPconnForNonretriable) { - ACLFilledChecklist ch(Config.accessList.serverPconnForNonretriable, request, al, nullptr); + ACLFilledChecklist ch(Config.accessList.serverPconnForNonretriable, request, al); ch.syncAle(request, nullptr); retriable = ch.fastCheck().allowed(); } @@ -1374,7 +1374,7 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn, AccessLo return; // anything will do. } - ACLFilledChecklist ch(nullptr, request, al, nullptr); + ACLFilledChecklist ch(nullptr, request, al); ch.syncAle(request, nullptr); ch.dst_peer_name = conn->getPeer() ? conn->getPeer()->name : NULL; ch.dst_addr = conn->remote; @@ -1403,7 +1403,7 @@ GetTosToServer(HttpRequest * request, Comm::Connection &conn, const AccessLogEnt if (!Ip::Qos::TheConfig.tosToServer) return 0; - ACLFilledChecklist ch(nullptr, request, al, nullptr); + ACLFilledChecklist ch(nullptr, request, al); ch.dst_peer_name = conn.getPeer() ? conn.getPeer()->name : nullptr; ch.dst_addr = conn.remote; return aclMapTOS(Ip::Qos::TheConfig.tosToServer, &ch); @@ -1416,7 +1416,7 @@ GetNfmarkToServer(HttpRequest * request, Comm::Connection &conn, const AccessLog if (!Ip::Qos::TheConfig.nfmarkToServer) return 0; - ACLFilledChecklist ch(nullptr, request, al, nullptr); + ACLFilledChecklist ch(nullptr, request, al); ch.dst_peer_name = conn.getPeer() ? conn.getPeer()->name : nullptr; ch.dst_addr = conn.remote; const auto mc = aclFindNfMarkConfig(Ip::Qos::TheConfig.nfmarkToServer, &ch); diff --git a/src/HttpHeaderTools.cc b/src/HttpHeaderTools.cc index 4f1934ef513..5e86c66222f 100644 --- a/src/HttpHeaderTools.cc +++ b/src/HttpHeaderTools.cc @@ -287,7 +287,7 @@ httpHdrMangle(HttpHeaderEntry * e, HttpRequest * request, HeaderManglers *hms, c return 1; } - ACLFilledChecklist checklist(hm->access_list, request, al, nullptr); + ACLFilledChecklist checklist(hm->access_list, request, al); checklist.syncAle(request, nullptr); if (al && al->reply) { checklist.reply = al->reply.getRaw(); @@ -481,7 +481,7 @@ HeaderManglers::find(const HttpHeaderEntry &e) const void httpHdrAdd(HttpHeader *heads, HttpRequest *request, const AccessLogEntryPointer &al, HeaderWithAclList &headersAdd) { - ACLFilledChecklist checklist(nullptr, request, al, nullptr); + ACLFilledChecklist checklist(nullptr, request, al); checklist.syncAle(request, nullptr); for (HeaderWithAclList::const_iterator hwa = headersAdd.begin(); hwa != headersAdd.end(); ++hwa) { diff --git a/src/HttpReply.cc b/src/HttpReply.cc index de8381c1a24..f3a5b8611e4 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -554,7 +554,7 @@ HttpReply::calcMaxBodySize(HttpRequest& request, const AccessLogEntry::Pointer & if (!Config.ReplyBodySize) return; - ACLFilledChecklist ch(nullptr, &request, al, nullptr); + ACLFilledChecklist ch(nullptr, &request, al); ch.syncAle(&request, nullptr); // XXX: cont-cast becomes irrelevant when checklist is HttpReply::Pointer ch.reply = const_cast(this); diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 2ab2557cdab..351fd719217 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -610,7 +610,7 @@ HttpRequest::getRangeOffsetLimit(const AccessLogEntry::Pointer &al) rangeOffsetLimit = 0; // default value for rangeOffsetLimit - ACLFilledChecklist ch(nullptr, this, al, nullptr); + ACLFilledChecklist ch(nullptr, this, al); ch.syncAle(this, nullptr); for (AclSizeLimit *l = Config.rangeOffsetLimit; l; l = l -> next) { @@ -724,7 +724,7 @@ HttpRequest::setInterceptionFlags(const AccessLogEntryPointer &al) const bool proxyProtocolPort = port ? port->flags.proxySurrogate : false; if (flags.interceptTproxy && !proxyProtocolPort) { if (Config.accessList.spoof_client_ip) { - ACLFilledChecklist *checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, al, connection->rfc931); + auto checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, al); checklist->syncAle(this, nullptr); flags.spoofClientIp = checklist->fastCheck().allowed(); delete checklist; diff --git a/src/Notes.cc b/src/Notes.cc index ff3adf2eb96..3bfc4b99c57 100644 --- a/src/Notes.cc +++ b/src/Notes.cc @@ -68,7 +68,7 @@ Note::addValue(const char *value, const bool quoted, const char *descr, const Va bool Note::match(HttpRequest *request, HttpReply *reply, const AccessLogEntry::Pointer &al, SBuf &matched) { - ACLFilledChecklist ch(nullptr, request, al, nullptr); + ACLFilledChecklist ch(nullptr, request, al); ch.reply = reply; ch.syncAle(request, nullptr); if (reply) diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 4afe244eeae..8a66676f96a 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -219,7 +219,7 @@ ACLFilledChecklist::markSourceDomainChecked() * *not* delete the list. After the callback function returns, * checkCallback() will delete the list (i.e., self). */ -ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_request, const AccessLogEntry::Pointer &ale, const char *ident): +ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_request, const AccessLogEntry::Pointer &ale): dst_rdns(NULL), request(NULL), reply(NULL), @@ -249,7 +249,7 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re setClientConnectionDetails(al->clientConnectionManager().get()); if (!clientConnectionManager()) // could not take the connection from the connection manager setClientConnection(al->tcpClient); - setIdent(ident); + setIdent(clientConnection_ ? clientConnection_->rfc931 : dash_str); } void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 0848eea6914..6b61b1767f0 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -36,7 +36,7 @@ class ACLFilledChecklist: public ACLChecklist public: ACLFilledChecklist(); - ACLFilledChecklist(const acl_access *, HttpRequest *, const AccessLogEntry::Pointer &, const char *ident = nullptr); + ACLFilledChecklist(const acl_access *, HttpRequest *, const AccessLogEntry::Pointer &); ~ACLFilledChecklist(); /// Configure client request-related fields for the first time. diff --git a/src/adaptation/AccessCheck.cc b/src/adaptation/AccessCheck.cc index 959b920f712..75bbe256c31 100644 --- a/src/adaptation/AccessCheck.cc +++ b/src/adaptation/AccessCheck.cc @@ -131,7 +131,7 @@ Adaptation::AccessCheck::checkCandidates() if (AccessRule *r = FindRule(topCandidate())) { /* BUG 2526: what to do when r->acl is empty?? */ // XXX: we do not have access to conn->rfc931 here. - acl_checklist = new ACLFilledChecklist(r->acl, filter.request, filter.al, dash_str); + acl_checklist = new ACLFilledChecklist(r->acl, filter.request, filter.al); if ((acl_checklist->reply = filter.reply)) HTTPMSGLOCK(acl_checklist->reply); acl_checklist->syncAle(filter.request, nullptr); diff --git a/src/adaptation/icap/Launcher.cc b/src/adaptation/icap/Launcher.cc index 03de09d3782..a402c55dd94 100644 --- a/src/adaptation/icap/Launcher.cc +++ b/src/adaptation/icap/Launcher.cc @@ -143,7 +143,7 @@ bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info // XXX: we cannot simply pass Xaction::al here, because icapRequest and al->request // represent different objects ACLFilledChecklist *cl = - new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, nullptr, dash_str); + new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, nullptr); cl->reply = info.icapReply; HTTPMSGLOCK(cl->reply); diff --git a/src/adaptation/icap/icap_log.cc b/src/adaptation/icap/icap_log.cc index 1ab0763c605..e432e733b7b 100644 --- a/src/adaptation/icap/icap_log.cc +++ b/src/adaptation/icap/icap_log.cc @@ -60,7 +60,7 @@ icapLogRotate() void icapLogLog(AccessLogEntry::Pointer &al) { if (IcapLogfileStatus == LOG_ENABLE) { - ACLFilledChecklist checklist(nullptr, al->adapted_request, al, nullptr); + ACLFilledChecklist checklist(nullptr, al->adapted_request, al); if (al->reply) { checklist.reply = al->reply.getRaw(); HTTPMSGLOCK(checklist.reply); diff --git a/src/auth/UserRequest.cc b/src/auth/UserRequest.cc index 962e77d48a4..8223686c365 100644 --- a/src/auth/UserRequest.cc +++ b/src/auth/UserRequest.cc @@ -465,7 +465,7 @@ static Auth::ConfigVector & schemesConfig(HttpRequest *request, HttpReply *rep, const AccessLogEntryPointer &al) { if (!Auth::TheConfig.schemeLists.empty() && Auth::TheConfig.schemeAccess) { - ACLFilledChecklist ch(nullptr, request, al, nullptr); + ACLFilledChecklist ch(nullptr, request, al); ch.syncAle(request, nullptr); ch.reply = rep; HTTPMSGLOCK(ch.reply); diff --git a/src/client_side.cc b/src/client_side.cc index 6714118979d..c9ce8adc687 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -440,7 +440,7 @@ ClientHttpRequest::logRequest() al->syncNotes(request); } - ACLFilledChecklist checklist(nullptr, request, al, nullptr); + ACLFilledChecklist checklist(nullptr, request, al); // no need checklist.syncAle(): already synced if (al->reply) { @@ -459,7 +459,7 @@ ClientHttpRequest::logRequest() bool updatePerformanceCounters = true; if (Config.accessList.stats_collection) { - ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, al, nullptr); + ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, al); statsCheck.setClientConnectionDetails(getConn()); if (al->reply) { statsCheck.reply = al->reply.getRaw(); @@ -1505,7 +1505,7 @@ bool ConnStateData::serveDelayedError(Http::Stream *context) bool allowDomainMismatch = false; if (Config.ssl_client.cert_error) { - ACLFilledChecklist check(Config.ssl_client.cert_error, request, http->al, dash_str); + ACLFilledChecklist check(Config.ssl_client.cert_error, request, http->al); check.setClientConnectionDetails(this); check.sslErrors = new Security::CertErrors(Security::CertError(SQUID_X509_V_ERR_DOMAIN_MISMATCH, srvCert)); check.syncAle(request, http->log_uri); @@ -1570,7 +1570,7 @@ ConnStateData::tunnelOnError(const HttpRequestMethod &method, const err_type req const auto request = http ? http->request : nullptr; const auto ale = http ? http->al : nullptr; - ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request, ale, nullptr); + ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request, ale); checklist.requestErrorType = requestError; checklist.setClientConnectionDetails(this); const char *log_uri = http ? http->log_uri : nullptr; @@ -1811,8 +1811,7 @@ ConnStateData::proxyProtocolValidateClient() if (!Config.accessList.proxyProtocol) return proxyProtocolError("PROXY client not permitted by default ACL"); - ACLFilledChecklist ch(Config.accessList.proxyProtocol, nullptr, nullptr, clientConnection->rfc931); - ch.setClientConnectionDetails(this); + ACLFilledChecklist ch(Config.accessList.proxyProtocol, nullptr, al); if (!ch.fastCheck().allowed()) return proxyProtocolError("PROXY client not permitted by ACLs"); @@ -1855,6 +1854,7 @@ ConnStateData::parseProxyProtocolHeader() assert(bool(proxyProtocolHeader_)); inBuf.consume(parsed.size); needProxyProtocolHeader_ = false; + al->proxyProtocolHeader = proxyProtocolHeader_; if (proxyProtocolHeader_->hasForwardedAddresses()) { clientConnection->local = proxyProtocolHeader_->destinationAddress; clientConnection->remote = proxyProtocolHeader_->sourceAddress; @@ -2213,6 +2213,14 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) : log_addr = clientConnection->remote; log_addr.applyClientMask(Config.Addrs.client_netmask); + al = new AccessLogEntry; + CodeContext::Reset(al); + al->setClientConnectionManager(this); + al->tcpClient = clientConnection; + al->cache.start_time = current_time; + al->cache.port = port; + al->cache.caddr = log_addr; + // register to receive notice of Squid signal events // which may affect long persisting client connections registerRunner(); @@ -2265,7 +2273,7 @@ ConnStateData::whenClientIpKnown() #if USE_IDENT if (Ident::TheConfig.identLookup) { - ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, nullptr, nullptr, nullptr); + ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, nullptr, nullptr); identChecklist.setClientConnectionDetails(this); if (identChecklist.fastCheck().allowed()) Ident::Start(clientConnection, clientIdentDone, this); @@ -2282,7 +2290,7 @@ ConnStateData::whenClientIpKnown() const auto &pools = ClientDelayPools::Instance()->pools; if (pools.size()) { - ACLFilledChecklist ch(nullptr, nullptr, nullptr, nullptr); + ACLFilledChecklist ch(nullptr, nullptr, nullptr); ch.setClientConnectionDetails(this); // TODO: we check early to limit error response bandwith but we @@ -2621,7 +2629,7 @@ ConnStateData::postHttpsAccept() } MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); - // Create a fake HTTP request and ALE for the ssl_bump ACL check, + // Create a fake HTTP request for the ssl_bump ACL check, // using tproxy/intercept provided destination IP and port. // XXX: Merge with subsequent fakeAConnectRequest(), buildFakeRequest(). // XXX: Do this earlier (e.g., in Http[s]::One::Server constructor). @@ -2630,25 +2638,18 @@ ConnStateData::postHttpsAccept() assert(clientConnection->flags & (COMM_TRANSPARENT | COMM_INTERCEPTION)); request->url.host(clientConnection->local.toStr(ip, sizeof(ip))); request->url.port(clientConnection->local.port()); - const AccessLogEntry::Pointer connectAle = new AccessLogEntry; - CodeContext::Reset(connectAle); + HTTPMSGUNLOCK(al->request); + al->request = request; + HTTPMSGLOCK(al->request); + // It looks like pipeline is still empty here. + // TODO: remove + if (const auto context = pipeline.front()) + if (const auto http = context->http) + al->url = http->log_uri; + // TODO: Use these request/ALE when waiting for new bumped transactions. - ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, connectAle, nullptr); - acl_checklist->setClientConnectionDetails(this); - // Build a local AccessLogEntry to allow requiresAle() acls work - acl_checklist->al->cache.start_time = current_time; - acl_checklist->al->tcpClient = clientConnection; - acl_checklist->al->cache.port = port; - acl_checklist->al->cache.caddr = log_addr; - acl_checklist->al->proxyProtocolHeader = proxyProtocolHeader_; - HTTPMSGUNLOCK(acl_checklist->al->request); - acl_checklist->al->request = request; - HTTPMSGLOCK(acl_checklist->al->request); - Http::StreamPointer context = pipeline.front(); - ClientHttpRequest *http = context ? context->http : nullptr; - const char *log_uri = http ? http->log_uri : nullptr; - acl_checklist->syncAle(request, log_uri); + auto acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request, al); acl_checklist->nonBlockingCheck(httpsSslBumpAccessCheckDone, this); #else fatal("FATAL: SSL-Bump requires --with-openssl"); @@ -2720,15 +2721,7 @@ void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &cer if (X509 *mimicCert = sslServerBump->serverCert.get()) certProperties.mimicCert.resetAndLock(mimicCert); - Http::StreamPointer context = pipeline.front(); - - const auto http = context ? context->http : nullptr; - const auto log_uri = http ? http->log_uri : nullptr; - - ACLFilledChecklist checklist(nullptr, sslServerBump->request.getRaw(), http ? http->al : nullptr, - clientConnection != NULL ? clientConnection->rfc931 : dash_str); - checklist.syncAle(sslServerBump->request.getRaw(), log_uri); - checklist.setClientConnectionDetails(this); + ACLFilledChecklist checklist(nullptr, sslServerBump->request.getRaw(), al); checklist.sslErrors = cbdataReference(sslServerBump->sslErrors()); for (sslproxy_cert_adapt *ca = Config.ssl_client.cert_adapt; ca != NULL; ca = ca->next) { @@ -3129,8 +3122,7 @@ ConnStateData::startPeekAndSplice() sslServerBump->step = XactionStep::tlsBump2; // Run a accessList check to check if want to splice or continue bumping - ACLFilledChecklist *acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, sslServerBump->request.getRaw(), http ? http->al : nullptr, nullptr); - acl_checklist->setClientConnectionDetails(this); + auto acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, sslServerBump->request.getRaw(), http ? http->al : nullptr); //acl_checklist->src_addr = params.conn->remote; //acl_checklist->my_addr = s->s; acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpNone)); @@ -3579,7 +3571,7 @@ varyEvaluateMatch(StoreEntry * entry, HttpRequest * request) ACLFilledChecklist * clientAclChecklistCreate(const acl_access * acl, ClientHttpRequest * http) { - const auto checklist = new ACLFilledChecklist(acl, nullptr, http->al, nullptr); + const auto checklist = new ACLFilledChecklist(acl, nullptr, http->al); clientAclChecklistFill(*checklist, http); return checklist; } diff --git a/src/client_side.h b/src/client_side.h index 97183831b22..69afea6efc8 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -128,6 +128,8 @@ class ConnStateData : public Server, public HttpControlMsgSink, private Independ Ip::Address log_addr; + AccessLogEntry::Pointer al; + struct { bool readMore; ///< needs comm_read (for this request or new requests) bool swanSang; // XXX: temporary flag to check proper cleanup diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 3e3710a9960..933f1a6113e 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -167,23 +167,27 @@ ClientHttpRequest::ClientHttpRequest(ConnStateData * aConn) : #endif { setConn(aConn); - al = new AccessLogEntry; - CodeContext::Reset(al); - al->setClientConnectionManager(aConn); - al->cache.start_time = current_time; - if (aConn) { - al->tcpClient = clientConnection = aConn->clientConnection; - al->cache.port = aConn->port; - al->cache.caddr = aConn->log_addr; - al->proxyProtocolHeader = aConn->proxyProtocolHeader(); + if (conn_ && (conn_->pipeline.nrequests == 0)) { + al = conn_->al; + } else { + al = new AccessLogEntry; + CodeContext::Reset(al); + al->cache.start_time = current_time; + if (conn_) { + al->setClientConnectionManager(conn_); + al->tcpClient = clientConnection = conn_->clientConnection; + al->cache.port = conn_->port; + al->cache.caddr = conn_->log_addr; + al->proxyProtocolHeader = conn_->proxyProtocolHeader(); + } + } #if USE_OPENSSL - if (aConn->clientConnection != NULL && aConn->clientConnection->isOpen()) { - if (auto ssl = fd_table[aConn->clientConnection->fd].ssl.get()) - al->cache.sslClientCert.resetWithoutLocking(SSL_get_peer_certificate(ssl)); - } -#endif + if (clientConnection && clientConnection->isOpen()) { + if (auto ssl = fd_table[clientConnection->fd].ssl.get()) + al->cache.sslClientCert.resetWithoutLocking(SSL_get_peer_certificate(ssl)); } +#endif dlinkAdd(this, &active, &ClientActiveRequests); } @@ -329,8 +333,6 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre ClientHttpRequest *http = new ClientHttpRequest(NULL); HttpRequest *request; StoreIOBuffer tempBuffer; - if (http->al != NULL) - http->al->cache.start_time = current_time; /* this is only used to adjust the connection offset in client_side.c */ http->req_sz = 0; tempBuffer.length = taillen; @@ -1807,7 +1809,7 @@ ClientHttpRequest::doCallouts() // Set appropriate MARKs and CONNMARKs if needed. if (getConn() && Comm::IsConnOpen(getConn()->clientConnection)) { - ACLFilledChecklist ch(nullptr, request, calloutContext->http->al, nullptr); + ACLFilledChecklist ch(nullptr, request, calloutContext->http->al); ch.setClientConnectionDetails(getConn()); ch.syncAle(request, log_uri); diff --git a/src/clients/Client.cc b/src/clients/Client.cc index 17c9bde6cc3..23fed02716a 100644 --- a/src/clients/Client.cc +++ b/src/clients/Client.cc @@ -524,7 +524,7 @@ Client::blockCaching() if (const Acl::Tree *acl = Config.accessList.storeMiss) { // This relatively expensive check is not in StoreEntry::checkCachable: // That method lacks HttpRequest and may be called too many times. - ACLFilledChecklist ch(acl, originalRequest().getRaw(), fwd->al, nullptr); + ACLFilledChecklist ch(acl, originalRequest().getRaw(), fwd->al); ch.syncAle(request.getRaw(), nullptr); ch.reply = const_cast(&entry->mem().freshestReply()); // ACLFilledChecklist API bug HTTPMSGLOCK(ch.reply); diff --git a/src/clients/FtpClient.cc b/src/clients/FtpClient.cc index c5000c4b104..d1dfdab0a40 100644 --- a/src/clients/FtpClient.cc +++ b/src/clients/FtpClient.cc @@ -704,7 +704,7 @@ Ftp::Client::sendPassive() default: { bool doEpsv = true; if (Config.accessList.ftp_epsv) { - ACLFilledChecklist checklist(Config.accessList.ftp_epsv, fwd->request, fwd->al, nullptr); + ACLFilledChecklist checklist(Config.accessList.ftp_epsv, fwd->request, fwd->al); checklist.syncAle(fwd->request, nullptr); doEpsv = checklist.fastCheck().allowed(); } diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index 4e3234682bf..175be06de3b 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -265,8 +265,7 @@ Comm::TcpAcceptor::logAcceptError(const ConnectionPointer &tcpClient) const al->tcpClient = tcpClient; al->url = "error:accept-client-connection"; al->setVirginUrlForMissingRequest(al->url); - ACLFilledChecklist ch(nullptr, nullptr, al, nullptr); - ch.setClientConnectionDetails(nullptr, conn); + ACLFilledChecklist ch(nullptr, nullptr, al); accessLogLog(al, &ch); CodeContext::Reset(listenPort_); diff --git a/src/htcp.cc b/src/htcp.cc index 4838bca56db..bd2debcc30b 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -807,7 +807,7 @@ htcpAccessAllowed(acl_access * acl, const htcpSpecifier::Pointer &s, Ip::Address if (!acl) return false; - ACLFilledChecklist checklist(acl, s->request.getRaw(), s->al, nullptr); + ACLFilledChecklist checklist(acl, s->request.getRaw(), s->al); return checklist.fastCheck().allowed(); } diff --git a/src/icp_v2.cc b/src/icp_v2.cc index 199a8562cb6..c5cba54f20d 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -474,7 +474,7 @@ icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const char *url, A return false; ICPState::SyncAle(al, from, url, 0, 0); - ACLFilledChecklist checklist(Config.accessList.icp, icp_request, al, nullptr); + ACLFilledChecklist checklist(Config.accessList.icp, icp_request, al); return checklist.fastCheck().allowed(); } diff --git a/src/neighbors.cc b/src/neighbors.cc index 430cd2a3684..faa27a3625b 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -166,7 +166,7 @@ peerAllowedToUse(const CachePeer * p, PeerSelector * ps) if (p->access == NULL) return true; - ACLFilledChecklist checklist(p->access, request, ps->al, nullptr); + ACLFilledChecklist checklist(p->access, request, ps->al); if (ps->al && ps->al->reply) { checklist.reply = ps->al->reply.getRaw(); HTTPMSGLOCK(checklist.reply); diff --git a/src/peer_select.cc b/src/peer_select.cc index ab8b89a8ac0..8fb6119faab 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -475,7 +475,7 @@ PeerSelector::selectMore() if (always_direct == ACCESS_DUNNO) { debugs(44, 3, "direct = " << DirectStr[direct] << " (always_direct to be checked)"); /** check always_direct; */ - ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, al, nullptr); + auto ch = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, al); acl_checklist = ch; acl_checklist->syncAle(request, nullptr); acl_checklist->nonBlockingCheck(CheckAlwaysDirectDone, this); @@ -483,7 +483,7 @@ PeerSelector::selectMore() } else if (never_direct == ACCESS_DUNNO) { debugs(44, 3, "direct = " << DirectStr[direct] << " (never_direct to be checked)"); /** check never_direct; */ - ACLFilledChecklist *ch = new ACLFilledChecklist(Config.accessList.NeverDirect, request, al, nullptr); + auto ch = new ACLFilledChecklist(Config.accessList.NeverDirect, request, al); acl_checklist = ch; acl_checklist->syncAle(request, nullptr); acl_checklist->nonBlockingCheck(CheckNeverDirectDone, this); diff --git a/src/security/PeerConnector.cc b/src/security/PeerConnector.cc index dcbae9136f1..4e347f78f2d 100644 --- a/src/security/PeerConnector.cc +++ b/src/security/PeerConnector.cc @@ -130,7 +130,7 @@ Security::PeerConnector::initialize(Security::SessionPointer &serverSession) // Create the ACL check list now, while we have access to more info. // The list is used in ssl_verify_cb() and is freed in ssl_free(). if (acl_access *acl = ::Config.ssl_client.cert_error) { - ACLFilledChecklist *check = new ACLFilledChecklist(acl, request.getRaw(), al, dash_str); + auto check = new ACLFilledChecklist(acl, request.getRaw(), al); check->syncAle(request.getRaw(), nullptr); // check->fd(fd); XXX: need client FD here SSL_set_ex_data(serverSession.get(), ssl_ex_index_cert_error_check, check); @@ -309,7 +309,7 @@ Security::PeerConnector::sslCrtvdCheckForErrors(Ssl::CertValidationResponse cons { ACLFilledChecklist *check = NULL; if (acl_access *acl = ::Config.ssl_client.cert_error) { - check = new ACLFilledChecklist(acl, request.getRaw(), al, dash_str); + check = new ACLFilledChecklist(acl, request.getRaw(), al); check->syncAle(request.getRaw(), nullptr); } diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 6f276902129..3fe8dcd31b3 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1536,7 +1536,7 @@ Ftp::Server::handleUploadRequest(String &, String &) if (Config.accessList.forceRequestBodyContinuation) { ClientHttpRequest *http = pipeline.front()->http; HttpRequest *request = http->request; - ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, http->al, nullptr); + ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, http->al); bodyContinuationCheck.setClientConnectionDetails(this); bodyContinuationCheck.syncAle(request, http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index c0241bf97cd..9ffcd0c153e 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -260,7 +260,7 @@ Http::One::Server::processParsedRequest(Http::StreamPointer &context) } if (Config.accessList.forceRequestBodyContinuation) { - ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), http->al, nullptr); + ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), http->al); bodyContinuationCheck.setClientConnectionDetails(this); bodyContinuationCheck.syncAle(request.getRaw(), http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 490445b1304..fc598680cbb 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -394,7 +394,7 @@ snmpDecodePacket(SnmpRequest * rq) /* Check if we have explicit permission to access SNMP data. * default (set above) is to deny all */ if (Community) { - ACLFilledChecklist checklist(Config.accessList.snmp, nullptr, nullptr, nullptr); + ACLFilledChecklist checklist(Config.accessList.snmp, nullptr, nullptr); checklist.snmpDetails(reinterpret_cast(Community), rq->from, snmpIncomingConn->local); if (checklist.fastCheck().allowed() && (snmp_coexist_V2toV1(PDU))) { rq->community = Community; diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index ebf0becf91c..29531289213 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -54,9 +54,9 @@ Ssl::PeekingPeerConnector::checkForPeekAndSplice() handleServerCertificate(); - ACLFilledChecklist *acl_checklist = new ACLFilledChecklist( + auto acl_checklist = new ACLFilledChecklist( ::Config.accessList.ssl_bump, - request.getRaw(), al, nullptr); + request.getRaw(), al); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpNone)); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpPeek)); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpStare)); diff --git a/src/store_client.cc b/src/store_client.cc index 4a0d0ec814b..d586d533613 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -59,7 +59,7 @@ StoreClient::onCollapsingPath() const if (!Config.accessList.collapsedForwardingAccess) return true; - ACLFilledChecklist checklist(Config.accessList.collapsedForwardingAccess, nullptr, nullptr, nullptr); + ACLFilledChecklist checklist(Config.accessList.collapsedForwardingAccess, nullptr, nullptr); fillChecklist(checklist); return checklist.fastCheck().allowed(); } diff --git a/src/tunnel.cc b/src/tunnel.cc index 7753375f2c4..907f4df27ea 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -963,7 +963,7 @@ tunnelStart(ClientHttpRequest * http) * Check if this host is allowed to fetch MISSES from us (miss_access) * default is to allow. */ - ACLFilledChecklist ch(Config.accessList.miss, request, http->al, nullptr); + ACLFilledChecklist ch(Config.accessList.miss, request, http->al); ch.syncAle(request, http->log_uri); if (ch.fastCheck().denied()) { debugs(26, 4, HERE << "MISS access forbidden."); From d466504944240d52cce40aead5a91eb8b199151c Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 19 Nov 2019 21:51:33 +0300 Subject: [PATCH 55/66] Do not create MasterXaction object twice ... for the initial HTTP transaction. The MasterXaction object was created: 1. just after connection establishment (TcpAcceptor::notify()) 2. after request parsing Now for the initial transaction, the MasterXaction object created at (1) is reused at (2). For subsequent transactions, a new MasterXaction is created as before. --- src/MasterXaction.cc | 13 +++++++++++++ src/MasterXaction.h | 4 ++++ src/client_side.cc | 19 ++++++++++++------- src/client_side.h | 11 ++++++++++- src/client_side_reply.cc | 4 +++- src/servers/FtpServer.cc | 2 +- src/servers/Http1Server.cc | 2 +- 7 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/MasterXaction.cc b/src/MasterXaction.cc index bea79f409cb..307673437f7 100644 --- a/src/MasterXaction.cc +++ b/src/MasterXaction.cc @@ -30,3 +30,16 @@ MasterXaction::clientConnection() return clientConnectionManager_.valid() ? clientConnectionManager_->clientConnection : clientConnection_; } +void +MasterXaction::setClientConnectionManager(ConnStateData *connManager) +{ + if (!connManager || clientConnectionManager_.valid()) + return; + clientConnectionManager_ = connManager; + if (clientConnection_) { + Must(clientConnection_ == connManager->clientConnection); + return; + } + clientConnection_ = connManager->clientConnection; +} + diff --git a/src/MasterXaction.h b/src/MasterXaction.h index d799a11c2ba..984561a586e 100644 --- a/src/MasterXaction.h +++ b/src/MasterXaction.h @@ -56,6 +56,10 @@ class MasterXaction : public RefCountable /// the client connection manager of the transaction, if any CbcPointer &clientConnectionManager() { return clientConnectionManager_; } + /// Initializes the client connection manager and the client connection with non-nil values. + /// Has no effect if the client connection manager has been already initialized. + void setClientConnectionManager(ConnStateData *); + /// transaction ID. InstanceId id; diff --git a/src/client_side.cc b/src/client_side.cc index c9ce8adc687..bd907407b42 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2183,6 +2183,7 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) : AsyncJob("ConnStateData"), // kids overwrite Server(xact), bodyParser(nullptr), + masterXaction(xact), #if USE_OPENSSL sslBumpMode(Ssl::bumpEnd), #endif @@ -2213,6 +2214,8 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) : log_addr = clientConnection->remote; log_addr.applyClientMask(Config.Addrs.client_netmask); + masterXaction->setClientConnectionManager(this); + al = new AccessLogEntry; CodeContext::Reset(al); al->setClientConnectionManager(this); @@ -2628,7 +2631,8 @@ ConnStateData::postHttpsAccept() return; } - MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); + Must(pipeline.nrequests == 0); + const auto mx = createMasterXaction(nullptr); // Create a fake HTTP request for the ssl_bump ACL check, // using tproxy/intercept provided destination IP and port. // XXX: Merge with subsequent fakeAConnectRequest(), buildFakeRequest(). @@ -2641,11 +2645,6 @@ ConnStateData::postHttpsAccept() HTTPMSGUNLOCK(al->request); al->request = request; HTTPMSGLOCK(al->request); - // It looks like pipeline is still empty here. - // TODO: remove - if (const auto context = pipeline.front()) - if (const auto http = context->http) - al->url = http->log_uri; // TODO: Use these request/ALE when waiting for new bumped transactions. @@ -3294,7 +3293,7 @@ ConnStateData::buildFakeRequest(Http::MethodType const method, SBuf &useHost, un stream->registerWithConn(); - MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); + const auto mx = createMasterXaction(nullptr); // Setup Http::Request object. Maybe should be replaced by a call to (modified) // clientProcessRequest HttpRequest::Pointer request = new HttpRequest(mx); @@ -3324,6 +3323,12 @@ ConnStateData::buildFakeRequest(Http::MethodType const method, SBuf &useHost, un return http; } +MasterXaction::Pointer +ConnStateData::createMasterXaction(const Http::Stream *stream) +{ + return firstTransaction(stream) ? masterXaction : new MasterXaction(XactionInitiator::initClient, this); +} + /// check FD after clientHttp[s]ConnectionOpened, adjust HttpSockets as needed static bool OpenedHttpSocket(const Comm::ConnectionPointer &c, const Ipc::FdNoteId portType) diff --git a/src/client_side.h b/src/client_side.h index 69afea6efc8..5aa7da9364e 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -128,7 +128,9 @@ class ConnStateData : public Server, public HttpControlMsgSink, private Independ Ip::Address log_addr; - AccessLogEntry::Pointer al; + MasterXaction::Pointer masterXaction; ///< the master transaction for the initial request + + AccessLogEntry::Pointer al; ///< ALE of the initial transaction struct { bool readMore; ///< needs comm_read (for this request or new requests) @@ -326,6 +328,8 @@ class ConnStateData : public Server, public HttpControlMsgSink, private Independ const ProxyProtocol::HeaderPointer &proxyProtocolHeader() const { return proxyProtocolHeader_; } + MasterXaction::Pointer createMasterXaction(const Http::Stream *); + protected: void startDechunkingRequest(); void finishDechunkingRequest(bool withSuccess); @@ -371,6 +375,11 @@ class ConnStateData : public Server, public HttpControlMsgSink, private Independ /// The PROXY protocol may require some data input first. void whenClientIpKnown(); + /// Whether we are processing the initial transaction on this connection. + /// \param the Stream object created for the current transaction. + /// If the caller does not have Stream object yet, nil is passed. + bool firstTransaction(const Http::Stream *stream) const { return stream ? pipeline.nrequests == 1 : pipeline.nrequests == 0; } + BodyPipe::Pointer bodyPipe; ///< set when we are reading request body /// whether preservedClientData is valid and should be kept up to date diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index e22dec9e3b2..3b5fd2812b6 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -2262,7 +2262,9 @@ clientReplyContext::createStoreEntry(const HttpRequestMethod& m, RequestFlags re */ if (http->request == NULL) { - const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, http->getConn()); + const MasterXaction::Pointer mx = http->getConn() ? + http->getConn()->createMasterXaction(http->getConn()->pipeline.front().getRaw()) : + new MasterXaction(XactionInitiator::initClient, http->getConn()); // XXX: These fake URI parameters shadow the real (or error:...) URI. // TODO: Either always set the request earlier and assert here OR use // http->uri (converted to Anyp::Uri) to create this catch-all request. diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 3fe8dcd31b3..02915c7b62f 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -724,7 +724,7 @@ Ftp::Server::parseOneRequest() const SBuf *path = (params.length() && CommandHasPathParameter(cmd)) ? ¶ms : NULL; calcUri(path); - MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); + const auto mx = createMasterXaction(nullptr); auto * const request = HttpRequest::FromUrl(uri, mx, method); if (!request) { debugs(33, 5, "Invalid FTP URL: " << uri); diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index 9ffcd0c153e..89dcb59502d 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -137,7 +137,7 @@ Http::One::Server::buildHttpRequest(Http::StreamPointer &context) } // TODO: move URL parse into Http Parser and INVALID_URL into the above parse error handling - MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient, this); + const auto mx = createMasterXaction(context.getRaw()); request = HttpRequest::FromUrlXXX(http->uri, mx, parser_->method()); if (!request) { debugs(33, 5, "Invalid URL: " << http->uri); From 54fa61888e5b3aace77c16b449db6a31b02798ab Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Wed, 20 Nov 2019 19:25:49 +0300 Subject: [PATCH 56/66] Fixed problems revealed by test-builds.sh --- src/HttpReply.h | 6 +++--- src/HttpRequest.h | 2 +- src/acl/FilledChecklist.cc | 2 ++ src/client_side.h | 4 +++- src/icmp/net_db.cc | 2 -- src/peer_digest.cc | 2 -- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/HttpReply.h b/src/HttpReply.h index 750f8795da7..473687aa908 100644 --- a/src/HttpReply.h +++ b/src/HttpReply.h @@ -96,12 +96,12 @@ class HttpReply: public Http::Message /** Checks whether received body exceeds known maximum size. * Requires a prior call to calcMaxBodySize(). */ - bool receivedBodyTooLarge(HttpRequest&, int64_t receivedBodySize, const AccessLogEntry::Pointer &); + bool receivedBodyTooLarge(HttpRequest&, int64_t receivedBodySize, const AccessLogEntryPointer &); /** Checks whether expected body exceeds known maximum size. * Requires a prior call to calcMaxBodySize(). */ - bool expectedBodyTooLarge(HttpRequest& request, const AccessLogEntry::Pointer &); + bool expectedBodyTooLarge(HttpRequest& request, const AccessLogEntryPointer &); int validatorsMatch (HttpReply const *other) const; @@ -152,7 +152,7 @@ class HttpReply: public Http::Message /** Calculates and stores maximum body size if needed. * Used by receivedBodyTooLarge() and expectedBodyTooLarge(). */ - void calcMaxBodySize(HttpRequest& request, const AccessLogEntry::Pointer &al) const; + void calcMaxBodySize(HttpRequest& request, const AccessLogEntryPointer &al) const; String removeStaleWarningValues(const String &value); diff --git a/src/HttpRequest.h b/src/HttpRequest.h index a1f28f923d9..dba5f54bb64 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -222,7 +222,7 @@ class HttpRequest: public Http::Message /// forgets about the cached Range header (for a reason) void ignoreRange(const char *reason); - int64_t getRangeOffsetLimit(const AccessLogEntry::Pointer &); /* the result of this function gets cached in rangeOffsetLimit */ + int64_t getRangeOffsetLimit(const AccessLogEntryPointer &); /* the result of this function gets cached in rangeOffsetLimit */ /// \returns existing non-empty transaction annotations, /// creates and returns empty annotations otherwise diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 8a66676f96a..8bb00939512 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -321,6 +321,7 @@ ACLFilledChecklist::setClientConnection(Comm::ConnectionPointer conn) setClientSideAddresses(); } +#if SQUID_SNMP void ACLFilledChecklist::snmpDetails(char *snmpCommunity, const Ip::Address &fromAddr, const Ip::Address &localAddr) { @@ -328,6 +329,7 @@ ACLFilledChecklist::snmpDetails(char *snmpCommunity, const Ip::Address &fromAddr client_addr = fromAddr; my_addr = localAddr; } +#endif void ACLFilledChecklist::setIdent(const char *ident) diff --git a/src/client_side.h b/src/client_side.h index 5aa7da9364e..ee886908dc4 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -40,6 +40,8 @@ class HttpHdrRangeSpec; class MasterXaction; typedef RefCount MasterXactionPointer; +class AccessLogEntry; +typedef RefCount AccessLogEntryPointer; #if USE_OPENSSL namespace Ssl @@ -130,7 +132,7 @@ class ConnStateData : public Server, public HttpControlMsgSink, private Independ MasterXaction::Pointer masterXaction; ///< the master transaction for the initial request - AccessLogEntry::Pointer al; ///< ALE of the initial transaction + AccessLogEntryPointer al; ///< ALE of the initial transaction struct { bool readMore; ///< needs comm_read (for this request or new requests) diff --git a/src/icmp/net_db.cc b/src/icmp/net_db.cc index f4eef40ae0a..92b2174d234 100644 --- a/src/icmp/net_db.cc +++ b/src/icmp/net_db.cc @@ -1281,8 +1281,6 @@ netdbExchangeStart(void *data) return; } - req->selfInitiated(); - netdbExchangeState *ex = new netdbExchangeState(p, req); ex->e = storeCreateEntry(uri, uri, RequestFlags(), Http::METHOD_GET); assert(NULL != ex->e); diff --git a/src/peer_digest.cc b/src/peer_digest.cc index f29058963f2..3d100d592bf 100644 --- a/src/peer_digest.cc +++ b/src/peer_digest.cc @@ -334,8 +334,6 @@ peerDigestRequest(PeerDigest * pd) /* add custom headers */ assert(!req->header.len); - req->selfInitiated(); - req->header.putStr(Http::HdrType::ACCEPT, StoreDigestMimeStr); req->header.putStr(Http::HdrType::ACCEPT, "text/html"); From 94c976dbeb5551460c34a328d6ebeb9388146bde Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Thu, 28 Nov 2019 17:57:57 +0300 Subject: [PATCH 57/66] Overall review and polishing --- src/AccessLogEntry.h | 7 +++--- src/FwdState.cc | 11 +++++---- src/FwdState.h | 4 +-- src/HttpReply.h | 6 ++--- src/HttpRequest.cc | 1 - src/HttpRequest.h | 10 +++----- src/ICP.h | 6 ++--- src/acl/FilledChecklist.cc | 15 +++++------- src/auth/UserRequest.h | 4 +-- src/auth/digest/UserRequest.h | 2 +- src/client_side.cc | 1 + src/clients/FtpRelay.cc | 2 +- src/comm/TcpAcceptor.cc | 2 +- src/format/Format.cc | 46 +++++++++++++++++------------------ src/http.h | 4 +-- src/http/Stream.cc | 2 +- src/ident/AclIdent.cc | 2 +- src/ip/Address.h | 1 - src/pconn.cc | 2 +- src/peer_select.cc | 6 ++--- 20 files changed, 62 insertions(+), 72 deletions(-) diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index da332db024b..b4cdb885cc7 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -94,11 +94,11 @@ class AccessLogEntry: public CodeContext const Ip::Address& myAddr() const; /// the client connection manager of the underlying transaction, if any - CbcPointer &clientConnectionManager() { return clientConnectionManager_; } + CbcPointer &clientConnectionManager() { return clientConnectionManager_; } void setClientConnectionManager(const CbcPointer &aMgr) { clientConnectionManager_ = aMgr; } /// the Downloader of the underlying transaction, if any - CbcPointer &downloader() { return downloader_; } + CbcPointer &downloader() { return downloader_; } void setDownloader(const CbcPointer &aDownloader) { downloader_ = aDownloader; } ConnStateData *pinnedConnection(); @@ -110,7 +110,6 @@ class AccessLogEntry: public CodeContext /// TCP/IP level details about the client connection Comm::ConnectionPointer tcpClient; - // TCP/IP level details about the server or peer connection // are stored in hier.tcpServer @@ -295,7 +294,7 @@ class AccessLogEntry: public CodeContext Ip::Address indirect_client_addr; ///< calculated client address, after applying X-Forwarded-For rules #endif Ip::Address client_addr; ///< source address of a non-TCP (e.g. ICMP) client - Ip::Address my_addr; ///< local address which a non-TCP (e.g., ICMP) client connects to + Ip::Address my_addr; ///< local address which a non-TCP (e.g., ICMP) client connects to /// Client URI (or equivalent) for effectiveVirginUrl() when HttpRequest is /// missing. This member is ignored unless the request member is nil. diff --git a/src/FwdState.cc b/src/FwdState.cc index 20ae94ed0e5..6887a2f0840 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -1342,7 +1342,7 @@ aclFindNfMarkConfig(acl_nfmark * head, ACLChecklist * ch) } void -getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn, AccessLogEntry::Pointer al) +getOutgoingAddress(HttpRequest *request, Comm::ConnectionPointer conn, const AccessLogEntry::Pointer &al) { // skip if an outgoing address is already set. if (conn->local.isKnown()) @@ -1378,7 +1378,6 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn, AccessLo ch.syncAle(request, nullptr); ch.dst_peer_name = conn->getPeer() ? conn->getPeer()->name : NULL; ch.dst_addr = conn->remote; - // TODO: ch.syncAle(request, nullptr); // TODO use the connection details in ACL. // needs a bit of rework in ACLFilledChecklist to use Comm::Connection instead of ConnStateData @@ -1398,12 +1397,13 @@ getOutgoingAddress(HttpRequest * request, Comm::ConnectionPointer conn, AccessLo /// \returns the TOS value that should be set on the to-peer connection static tos_t -GetTosToServer(HttpRequest * request, Comm::Connection &conn, const AccessLogEntry::Pointer &al) +GetTosToServer(HttpRequest *request, Comm::Connection &conn, const AccessLogEntry::Pointer &al) { if (!Ip::Qos::TheConfig.tosToServer) return 0; ACLFilledChecklist ch(nullptr, request, al); + ch.syncAle(request, nullptr); ch.dst_peer_name = conn.getPeer() ? conn.getPeer()->name : nullptr; ch.dst_addr = conn.remote; return aclMapTOS(Ip::Qos::TheConfig.tosToServer, &ch); @@ -1417,6 +1417,7 @@ GetNfmarkToServer(HttpRequest * request, Comm::Connection &conn, const AccessLog return 0; ACLFilledChecklist ch(nullptr, request, al); + ch.syncAle(request, nullptr); ch.dst_peer_name = conn.getPeer() ? conn.getPeer()->name : nullptr; ch.dst_addr = conn.remote; const auto mc = aclFindNfMarkConfig(Ip::Qos::TheConfig.nfmarkToServer, &ch); @@ -1424,7 +1425,7 @@ GetNfmarkToServer(HttpRequest * request, Comm::Connection &conn, const AccessLog } void -GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn, const AccessLogEntry::Pointer &al) +GetMarkingsToServer(HttpRequest *request, Comm::Connection &conn, const AccessLogEntry::Pointer &al) { // Get the server side TOS and Netfilter mark to be set on the connection. conn.tos = GetTosToServer(request, conn, al); @@ -1433,7 +1434,7 @@ GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn, const AccessL } void -ResetMarkingsToServer(HttpRequest * request, Comm::Connection &conn, const AccessLogEntry::Pointer &al) +ResetMarkingsToServer(HttpRequest *request, Comm::Connection &conn, const AccessLogEntry::Pointer &al) { GetMarkingsToServer(request, conn, al); diff --git a/src/FwdState.h b/src/FwdState.h index cfae7414ec1..23267b19a60 100644 --- a/src/FwdState.h +++ b/src/FwdState.h @@ -50,7 +50,7 @@ class CertValidationResponse; /// Sets initial TOS value and Netfilter for the future outgoing connection. /// Updates the given Connection object, not the future transport connection. -void GetMarkingsToServer(HttpRequest * request, Comm::Connection &conn, const AccessLogEntry::Pointer &); +void GetMarkingsToServer(HttpRequest *, Comm::Connection &, const AccessLogEntry::Pointer &); /// Recomputes and applies TOS value and Netfilter to the outgoing connection. /// Updates both the given Connection object and the transport connection. @@ -197,7 +197,7 @@ class FwdState: public RefCountable, public PeerSelectionInitiator PconnRace pconnRace; ///< current pconn race state }; -void getOutgoingAddress(HttpRequest *request, Comm::ConnectionPointer conn, AccessLogEntry::Pointer); +void getOutgoingAddress(HttpRequest *, Comm::ConnectionPointer, const AccessLogEntry::Pointer &); /// a collection of previously used persistent Squid-to-peer HTTP(S) connections extern PconnPool *fwdPconnPool; diff --git a/src/HttpReply.h b/src/HttpReply.h index 473687aa908..64f0169672b 100644 --- a/src/HttpReply.h +++ b/src/HttpReply.h @@ -96,12 +96,12 @@ class HttpReply: public Http::Message /** Checks whether received body exceeds known maximum size. * Requires a prior call to calcMaxBodySize(). */ - bool receivedBodyTooLarge(HttpRequest&, int64_t receivedBodySize, const AccessLogEntryPointer &); + bool receivedBodyTooLarge(HttpRequest &, int64_t receivedBodySize, const AccessLogEntryPointer &); /** Checks whether expected body exceeds known maximum size. * Requires a prior call to calcMaxBodySize(). */ - bool expectedBodyTooLarge(HttpRequest& request, const AccessLogEntryPointer &); + bool expectedBodyTooLarge(HttpRequest &, const AccessLogEntryPointer &); int validatorsMatch (HttpReply const *other) const; @@ -152,7 +152,7 @@ class HttpReply: public Http::Message /** Calculates and stores maximum body size if needed. * Used by receivedBodyTooLarge() and expectedBodyTooLarge(). */ - void calcMaxBodySize(HttpRequest& request, const AccessLogEntryPointer &al) const; + void calcMaxBodySize(HttpRequest &, const AccessLogEntryPointer &) const; String removeStaleWarningValues(const String &value); diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 351fd719217..81881d92435 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -241,7 +241,6 @@ HttpRequest::inheritProperties(const Http::Message *aMsg) theNotes = aReq->theNotes; sources = aReq->sources; - return true; } diff --git a/src/HttpRequest.h b/src/HttpRequest.h index dba5f54bb64..ebe987c021f 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -104,7 +104,7 @@ class HttpRequest: public Http::Message void clearError(); /// sets TPROXY-related flags - void setInterceptionFlags(const AccessLogEntryPointer &al); + void setInterceptionFlags(const AccessLogEntryPointer &); /// whether this request is a subject of 'miss_access' check bool needCheckMissAccess() const; @@ -245,7 +245,6 @@ class HttpRequest: public Http::Message /// annotations added by the note directive and helpers /// and(or) by annotate_transaction/annotate_client ACLs. NotePairs::Pointer theNotes; - protected: virtual void packFirstLineInto(Packable * p, bool full_uri) const; @@ -257,10 +256,9 @@ class HttpRequest: public Http::Message }; class ConnStateData; -/** - * Updates ConnStateData ids and HttpRequest notes from helpers received notes. - */ -void UpdateRequestNotes(HttpRequest &request, NotePairs const ¬es); + +/// updates ConnStateData ids and HttpRequest notes from helpers received notes +void UpdateRequestNotes(HttpRequest &, NotePairs const &); /// \returns listening/*_port address used by the client connection (or nil) /// nil parameter(s) indicate missing caller information and are handled safely diff --git a/src/ICP.h b/src/ICP.h index 0a4ebbc9bb5..f914821c854 100644 --- a/src/ICP.h +++ b/src/ICP.h @@ -65,11 +65,11 @@ class ICPState: public StoreClient { public: - ICPState(icp_common_t &aHeader, HttpRequest *aRequest, const AccessLogEntryPointer &); + ICPState(icp_common_t &aHeader, HttpRequest *, const AccessLogEntryPointer &); virtual ~ICPState(); /// creates ALE (if nil), always overwriting its fields with the supplied parameters - static void SyncAle(AccessLogEntryPointer &al, const Ip::Address &caddr, const char *url, int len, int delay); + static void SyncAle(AccessLogEntryPointer &, const Ip::Address &caddr, const char *url, int len, int delay); icp_common_t header; HttpRequest *request; @@ -97,7 +97,7 @@ extern Ip::Address theIcpPublicHostID; HttpRequest* icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from); /// \ingroup ServerProtocolICPAPI -bool icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const char *url, AccessLogEntryPointer &al); +bool icpAccessAllowed(Ip::Address &from, HttpRequest *icp_request, const char *url, AccessLogEntryPointer &); /// \ingroup ServerProtocolICPAPI void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from, AccessLogEntryPointer); diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 8bb00939512..48fbfbb984e 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -239,9 +239,6 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re destinationDomainChecked_(false), sourceDomainChecked_(false) { - my_addr.setEmpty(); - client_addr.setEmpty(); - dst_addr.setEmpty(); rfc931[0] = '\0'; changeAcl(A); @@ -262,7 +259,7 @@ void ACLFilledChecklist::setRequest(HttpRequest *httpRequest) } static void -InitializeClientAddress(Ip::Address &addr, const Ip::Address &value) +InitializeAddress(Ip::Address &addr, const Ip::Address &value) { assert(!addr.isKnown() || addr == value); if (!addr.isKnown()) @@ -276,14 +273,14 @@ ACLFilledChecklist::setClientSideAddresses() if (request) { #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.acl_uses_indirect_client) - InitializeClientAddress(client_addr, al->furthestClientAddress()); + InitializeAddress(client_addr, al->furthestClientAddress()); else #endif - InitializeClientAddress(client_addr, al->clientAddr()); - InitializeClientAddress(my_addr, al->myAddr()); + InitializeAddress(client_addr, al->clientAddr()); + InitializeAddress(my_addr, al->myAddr()); } else if (clientConnection_) { - InitializeClientAddress(client_addr, clientConnection_->remote); - InitializeClientAddress(my_addr, clientConnection_->local); + InitializeAddress(client_addr, clientConnection_->remote); + InitializeAddress(my_addr, clientConnection_->local); } } diff --git a/src/auth/UserRequest.h b/src/auth/UserRequest.h index 53b3ea80f96..fe9fca3c113 100644 --- a/src/auth/UserRequest.h +++ b/src/auth/UserRequest.h @@ -126,7 +126,7 @@ class UserRequest : public RefCountable */ bool valid() const; - virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &al) = 0; + virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &) = 0; /* template method - what needs to be done next? advertise schemes, challenge, handle error, nothing? */ virtual Direction module_direction() = 0; @@ -165,7 +165,7 @@ class UserRequest : public RefCountable static AuthAclState tryToAuthenticateAndSetAuthUser(UserRequest::Pointer *aUR, Http::HdrType, HttpRequest *, ConnStateData *, const Ip::Address &, AccessLogEntry::Pointer &); /// Add the appropriate [Proxy-]Authenticate header to the given reply - static void AddReplyAuthHeader(HttpReply * rep, UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal, const AccessLogEntryPointer &al); + static void AddReplyAuthHeader(HttpReply * rep, UserRequest::Pointer auth_user_request, HttpRequest * request, int accelerated, int internal, const AccessLogEntryPointer &); /** Start an asynchronous helper lookup to verify the user credentials * diff --git a/src/auth/digest/UserRequest.h b/src/auth/digest/UserRequest.h index e39d28641e0..d35238e49fc 100644 --- a/src/auth/digest/UserRequest.h +++ b/src/auth/digest/UserRequest.h @@ -34,7 +34,7 @@ class UserRequest : public Auth::UserRequest virtual ~UserRequest(); virtual int authenticated() const; - virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &al); + virtual void authenticate(HttpRequest * request, ConnStateData * conn, Http::HdrType type, AccessLogEntry::Pointer &); virtual Direction module_direction(); virtual void addAuthenticationInfoHeader(HttpReply * rep, int accel); #if WAITING_FOR_TE diff --git a/src/client_side.cc b/src/client_side.cc index bd907407b42..490b8b11ada 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -3587,6 +3587,7 @@ clientAclChecklistFill(ACLFilledChecklist &checklist, ClientHttpRequest *http) checklist.setRequest(http->request); checklist.al = http->al; checklist.syncAle(http->request, http->log_uri); + // TODO: If http->getConn is always http->request->clientConnectionManager, // then call setIdent() inside checklist.setRequest(). Otherwise, restore // USE_IDENT lost in commit 94439e4. diff --git a/src/clients/FtpRelay.cc b/src/clients/FtpRelay.cc index a768e88702e..f75ccf3b1ee 100644 --- a/src/clients/FtpRelay.cc +++ b/src/clients/FtpRelay.cc @@ -548,7 +548,7 @@ Ftp::Relay::sendCommand() SENT_COMMAND; if (state == SENT_DATA_REQUEST) { - CbcPointer &mgr = fwd->al->clientConnectionManager(); + auto &mgr = fwd->al->clientConnectionManager(); if (mgr.valid()) { if (Ftp::Server *srv = dynamic_cast(mgr.get())) { typedef NullaryMemFunT CbDialer; diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc index 175be06de3b..c414bebae1e 100644 --- a/src/comm/TcpAcceptor.cc +++ b/src/comm/TcpAcceptor.cc @@ -333,7 +333,7 @@ Comm::TcpAcceptor::notify(const Comm::Flag flag, const Comm::ConnectionPointer & params.xaction = new MasterXaction(XactionInitiator::initClient, newConnDetails); params.xaction->squidPort = listenPort_; params.fd = conn->fd; - params.conn = newConnDetails; + params.conn = newConnDetails; params.flag = flag; params.xerrno = errcode; ScheduleCallHere(call); diff --git a/src/format/Format.cc b/src/format/Format.cc index e031aebdba0..49ca3e3548d 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -457,23 +457,23 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_EXT_ACL_CLIENT_EUI48: #if USE_SQUID_EUI - if (al->clientConnectionManager().valid() && - al->clientConnectionManager()->clientConnection && - al->clientConnectionManager()->clientConnection->remote.isIPv4()) { - al->clientConnectionManager()->clientConnection->remoteEui48.encode(tmp, sizeof(tmp)); - out = tmp; - } + if (const auto mgr = al->clientConnectionManager().valid()) + if (const auto conn = mgr->clientConnection) + if (conn->remote.isIPv4()) { + conn->remoteEui48.encode(tmp, sizeof(tmp)); + out = tmp; + } #endif break; case LFT_EXT_ACL_CLIENT_EUI64: #if USE_SQUID_EUI - if (al->clientConnectionManager().valid() && - al->clientConnectionManager()->clientConnection && - !al->clientConnectionManager()->clientConnection->remote.isIPv4()) { - al->clientConnectionManager()->clientConnection->remoteEui64.encode(tmp, sizeof(tmp)); - out = tmp; - } + if (const auto mgr = al->clientConnectionManager().valid()) + if (const auto conn = mgr->clientConnection) + if (!conn->remote.isIPv4()) { + conn->remoteEui64.encode(tmp, sizeof(tmp)); + out = tmp; + } #endif break; @@ -559,8 +559,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_CLIENT_HANDSHAKE: - if (al->clientConnectionManager().valid()) { - const auto &handshake = al->clientConnectionManager()->preservedClientData; + if (const auto mgr = al->clientConnectionManager().valid()) { + const auto &handshake = mgr->preservedClientData; if (const auto rawLength = handshake.length()) { // add 1 byte to optimize the c_str() conversion below char *buf = sb.rawAppendStart(base64_encode_len(rawLength) + 1); @@ -1297,19 +1297,17 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS break; case LFT_SSL_CLIENT_SNI: - if (al->clientConnectionManager().valid()) { - if (const auto conn = al->clientConnectionManager().get()) { - if (!conn->tlsClientSni().isEmpty()) { - sb = conn->tlsClientSni(); - out = sb.c_str(); - } + if (const auto mgr = al->clientConnectionManager().valid()) { + if (!mgr->tlsClientSni().isEmpty()) { + sb = mgr->tlsClientSni(); + out = sb.c_str(); } } break; case LFT_SSL_SERVER_CERT_ERRORS: - if (al->clientConnectionManager().valid()) { - if (const auto srvBump = al->clientConnectionManager()->serverBump()) { + if (const auto mgr = al->clientConnectionManager().valid()) { + if (const auto srvBump = mgr->serverBump()) { const char *separator = fmt->data.string ? fmt->data.string : ":"; for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) { if (!sb.isEmpty()) @@ -1330,8 +1328,8 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS case LFT_SSL_SERVER_CERT_ISSUER: case LFT_SSL_SERVER_CERT_SUBJECT: case LFT_SSL_SERVER_CERT_WHOLE: - if (al->clientConnectionManager().valid()) { - if (const auto srvBump = al->clientConnectionManager()->serverBump()) { + if (const auto mgr = al->clientConnectionManager().valid()) { + if (const auto srvBump = mgr->serverBump()) { if (X509 *serverCert = srvBump->serverCert.get()) { if (fmt->type == LFT_SSL_SERVER_CERT_SUBJECT) out = Ssl::GetX509UserAttribute(serverCert, "DN"); diff --git a/src/http.h b/src/http.h index 95816d56e0f..d7cffdace2c 100644 --- a/src/http.h +++ b/src/http.h @@ -107,7 +107,7 @@ class HttpStateData : public Client void abortTransaction(const char *reason) { abortAll(reason); } // abnormal termination - AccessLogEntry::Pointer ale() { assert(fwd); assert(fwd->al); return fwd->al; } + AccessLogEntry::Pointer ale() const { assert(fwd); assert(fwd->al); return fwd->al; } /** * determine if read buffer can have space made available @@ -137,7 +137,7 @@ class HttpStateData : public Client void httpTimeout(const CommTimeoutCbParams ¶ms); mb_size_t buildRequestPrefix(MemBuf * mb); - static bool decideIfWeDoRanges (HttpRequest * orig_request, const AccessLogEntryPointer &al); + static bool decideIfWeDoRanges (HttpRequest *orig_request, const AccessLogEntryPointer &); bool peerSupportsConnectionPinning() const; /// Parser being used at present to parse the HTTP/ICY server response. diff --git a/src/http/Stream.cc b/src/http/Stream.cc index a9d7e86da40..e0ddf3afd41 100644 --- a/src/http/Stream.cc +++ b/src/http/Stream.cc @@ -424,7 +424,7 @@ Http::Stream::buildRangeHeader(HttpReply *rep) HttpRequest *request = http->request; assert(request->range); /* check if we still want to do ranges */ - int64_t roffLimit = request->getRangeOffsetLimit(http->al); + const auto roffLimit = request->getRangeOffsetLimit(http->al); auto contentRange = rep ? rep->contentRange() : nullptr; if (!rep) diff --git a/src/ident/AclIdent.cc b/src/ident/AclIdent.cc index 6ff68b5ff20..e1d666550fc 100644 --- a/src/ident/AclIdent.cc +++ b/src/ident/AclIdent.cc @@ -117,7 +117,7 @@ IdentLookup::Instance() void IdentLookup::checkForAsync(ACLChecklist *cl)const { - ACLFilledChecklist *checklist = Filled(cl); + auto checklist = Filled(cl); const auto conn = checklist->clientConnectionManager(); // check that ACLIdent::match() tested this lookup precondition assert(conn && Comm::IsConnOpen(conn->clientConnection)); diff --git a/src/ip/Address.h b/src/ip/Address.h index 2f8f405e759..8b39fa5517c 100644 --- a/src/ip/Address.h +++ b/src/ip/Address.h @@ -348,7 +348,6 @@ class Address struct sockaddr_in6 mSocketAddr_; private: - /* Internally used constants */ static const unsigned int STRLEN_IP4A = 16; // aaa.bbb.ccc.ddd\0 static const unsigned int STRLEN_IP4R = 28; // ddd.ccc.bbb.aaa.in-addr.arpa.\0 diff --git a/src/pconn.cc b/src/pconn.cc index 972b1175949..4866229f0e5 100644 --- a/src/pconn.cc +++ b/src/pconn.cc @@ -247,7 +247,7 @@ IdleConnList::findUseable(const Comm::ConnectionPointer &aKey) assert(size_); // small optimization: do the constant bool tests only once. - const bool keyCheckAddr = aKey->local.isKnown(); + const auto keyCheckAddr = aKey->local.isKnown(); const bool keyCheckPort = aKey->local.port() > 0; for (int i=size_-1; i>=0; --i) { diff --git a/src/peer_select.cc b/src/peer_select.cc index 8fb6119faab..b52729852b5 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -475,16 +475,14 @@ PeerSelector::selectMore() if (always_direct == ACCESS_DUNNO) { debugs(44, 3, "direct = " << DirectStr[direct] << " (always_direct to be checked)"); /** check always_direct; */ - auto ch = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, al); - acl_checklist = ch; + acl_checklist = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request, al); acl_checklist->syncAle(request, nullptr); acl_checklist->nonBlockingCheck(CheckAlwaysDirectDone, this); return; } else if (never_direct == ACCESS_DUNNO) { debugs(44, 3, "direct = " << DirectStr[direct] << " (never_direct to be checked)"); /** check never_direct; */ - auto ch = new ACLFilledChecklist(Config.accessList.NeverDirect, request, al); - acl_checklist = ch; + acl_checklist = new ACLFilledChecklist(Config.accessList.NeverDirect, request, al); acl_checklist->syncAle(request, nullptr); acl_checklist->nonBlockingCheck(CheckNeverDirectDone, this); return; From 37fc9047dc6a9ba16ee7a55c6a7c39c51dd886c3 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Fri, 29 Nov 2019 15:10:48 +0300 Subject: [PATCH 58/66] Removed unnecessary ACLFilledChecklist::setClientConnectionDetails() Since 3e3f2aba this setting is performed in ACLFilledChecklist constructor and we do not need to specify connection details manually. --- src/client_side.cc | 4 ---- src/client_side_request.cc | 1 - src/servers/FtpServer.cc | 1 - src/servers/Http1Server.cc | 1 - 4 files changed, 7 deletions(-) diff --git a/src/client_side.cc b/src/client_side.cc index 490b8b11ada..a1c44d8bf78 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -454,13 +454,11 @@ ClientHttpRequest::logRequest() HTTPMSGLOCK(al->adapted_request); } - checklist.setClientConnectionDetails(getConn()); accessLogLog(al, &checklist); bool updatePerformanceCounters = true; if (Config.accessList.stats_collection) { ACLFilledChecklist statsCheck(Config.accessList.stats_collection, request, al); - statsCheck.setClientConnectionDetails(getConn()); if (al->reply) { statsCheck.reply = al->reply.getRaw(); HTTPMSGLOCK(statsCheck.reply); @@ -1506,7 +1504,6 @@ bool ConnStateData::serveDelayedError(Http::Stream *context) bool allowDomainMismatch = false; if (Config.ssl_client.cert_error) { ACLFilledChecklist check(Config.ssl_client.cert_error, request, http->al); - check.setClientConnectionDetails(this); check.sslErrors = new Security::CertErrors(Security::CertError(SQUID_X509_V_ERR_DOMAIN_MISMATCH, srvCert)); check.syncAle(request, http->log_uri); allowDomainMismatch = check.fastCheck().allowed(); @@ -1572,7 +1569,6 @@ ConnStateData::tunnelOnError(const HttpRequestMethod &method, const err_type req const auto ale = http ? http->al : nullptr; ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request, ale); checklist.requestErrorType = requestError; - checklist.setClientConnectionDetails(this); const char *log_uri = http ? http->log_uri : nullptr; checklist.syncAle(request, log_uri); auto answer = checklist.fastCheck(); diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 933f1a6113e..303516320fd 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1810,7 +1810,6 @@ ClientHttpRequest::doCallouts() // Set appropriate MARKs and CONNMARKs if needed. if (getConn() && Comm::IsConnOpen(getConn()->clientConnection)) { ACLFilledChecklist ch(nullptr, request, calloutContext->http->al); - ch.setClientConnectionDetails(getConn()); ch.syncAle(request, log_uri); if (!calloutContext->toClientMarkingDone) { diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 02915c7b62f..52b224e6073 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1537,7 +1537,6 @@ Ftp::Server::handleUploadRequest(String &, String &) ClientHttpRequest *http = pipeline.front()->http; HttpRequest *request = http->request; ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, http->al); - bodyContinuationCheck.setClientConnectionDetails(this); bodyContinuationCheck.syncAle(request, http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { request->forcedBodyContinuation = true; diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index 89dcb59502d..2b52ed7080b 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -261,7 +261,6 @@ Http::One::Server::processParsedRequest(Http::StreamPointer &context) if (Config.accessList.forceRequestBodyContinuation) { ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), http->al); - bodyContinuationCheck.setClientConnectionDetails(this); bodyContinuationCheck.syncAle(request.getRaw(), http->log_uri); if (bodyContinuationCheck.fastCheck().allowed()) { debugs(33, 5, "Body Continuation forced"); From 103fc3fd79b8b6a7849e0d3b3c2f9a3bbccf6dec Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sat, 30 Nov 2019 12:34:24 +0300 Subject: [PATCH 59/66] Reduced code duplication --- src/ssl/PeekingPeerConnector.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index 29531289213..41983415a37 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -84,9 +84,9 @@ Ssl::PeekingPeerConnector::checkForPeekAndSpliceMatched(const Ssl::BumpMode acti Ssl::BumpMode finalAction = action; Must(finalAction == Ssl::bumpSplice || finalAction == Ssl::bumpBump || finalAction == Ssl::bumpTerminate); // Record final decision - if (al->clientConnectionManager().valid()) { - al->clientConnectionManager()->sslBumpMode = finalAction; - al->clientConnectionManager()->serverBump()->act.step3 = finalAction; + if (auto mgr = al->clientConnectionManager().valid()) { + mgr->sslBumpMode = finalAction; + mgr->serverBump()->act.step3 = finalAction; } al->ssl.bumpMode = finalAction; From 5c3caae4a28570b32dda46e750dedafb5525fdde Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sat, 30 Nov 2019 12:34:42 +0300 Subject: [PATCH 60/66] Fixed a bug of calling pure virtual ConnStateData::toCbdata() ... inherited from CbdataParent. This problem appeared after recent changes when ConnStateData acquired ALE and MasterXaction fields. These fields, in turn, have cbc pointers to it which were mistakenly initialized in the ConnStateData constructor: ConnStateData is not not a CBDATA class and, hence, does not have toCbdata(), required by that initialisation. --- src/client_side.cc | 3 --- src/client_side.h | 3 +++ src/servers/FtpServer.cc | 8 ++++++++ src/servers/FtpServer.h | 1 + src/servers/Http1Server.cc | 8 ++++++++ src/servers/Http1Server.h | 1 + 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/client_side.cc b/src/client_side.cc index a1c44d8bf78..f7879741165 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2210,11 +2210,8 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) : log_addr = clientConnection->remote; log_addr.applyClientMask(Config.Addrs.client_netmask); - masterXaction->setClientConnectionManager(this); - al = new AccessLogEntry; CodeContext::Reset(al); - al->setClientConnectionManager(this); al->tcpClient = clientConnection; al->cache.start_time = current_time; al->cache.port = port; diff --git a/src/client_side.h b/src/client_side.h index ee886908dc4..b3c9da42ec4 100644 --- a/src/client_side.h +++ b/src/client_side.h @@ -382,6 +382,9 @@ class ConnStateData : public Server, public HttpControlMsgSink, private Independ /// If the caller does not have Stream object yet, nil is passed. bool firstTransaction(const Http::Stream *stream) const { return stream ? pipeline.nrequests == 1 : pipeline.nrequests == 0; } + /// CBDATA subclasses use this method to initialize CbcPointer fields + virtual void initWithConnectionManager() = 0; + BodyPipe::Pointer bodyPipe; ///< set when we are reading request body /// whether preservedClientData is valid and should be kept up to date diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 52b224e6073..48e4c1f15c4 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -66,6 +66,7 @@ Ftp::Server::Server(const MasterXaction::Pointer &xact): waitingForOrigin(false), originDataDownloadAbortedOnError(false) { + initWithConnectionManager(); flags.readMore = false; // we need to announce ourselves first *uploadBuf = 0; } @@ -87,6 +88,13 @@ Ftp::Server::idleTimeout() const return Config.Timeout.ftpClientIdle; } +void +Ftp::Server::initWithConnectionManager() +{ + masterXaction->setClientConnectionManager(this); + al->setClientConnectionManager(this); +} + void Ftp::Server::start() { diff --git a/src/servers/FtpServer.h b/src/servers/FtpServer.h index 0e305c8c438..f3c94ef1734 100644 --- a/src/servers/FtpServer.h +++ b/src/servers/FtpServer.h @@ -99,6 +99,7 @@ class Server: public ConnStateData virtual int pipelinePrefetchMax() const override; virtual bool writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call) override; virtual time_t idleTimeout() const override; + virtual void initWithConnectionManager() override; /* BodyPipe API */ virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer) override; diff --git a/src/servers/Http1Server.cc b/src/servers/Http1Server.cc index 2b52ed7080b..5b8a22fe7a2 100644 --- a/src/servers/Http1Server.cc +++ b/src/servers/Http1Server.cc @@ -29,6 +29,7 @@ Http::One::Server::Server(const MasterXaction::Pointer &xact, bool beHttpsServer ConnStateData(xact), isHttpsServer(beHttpsServer) { + initWithConnectionManager(); } time_t @@ -37,6 +38,13 @@ Http::One::Server::idleTimeout() const return Config.Timeout.clientIdlePconn; } +void +Http::One::Server::initWithConnectionManager() +{ + masterXaction->setClientConnectionManager(this); + al->setClientConnectionManager(this); +} + void Http::One::Server::start() { diff --git a/src/servers/Http1Server.h b/src/servers/Http1Server.h index 58a454740f8..bb833e6319f 100644 --- a/src/servers/Http1Server.h +++ b/src/servers/Http1Server.h @@ -34,6 +34,7 @@ class Server: public ConnStateData virtual void handleReply(HttpReply *rep, StoreIOBuffer receivedData); virtual bool writeControlMsgAndCall(HttpReply *rep, AsyncCall::Pointer &call); virtual time_t idleTimeout() const; + virtual void initWithConnectionManager(); /* BodyPipe API */ virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer); From 25c4e121c33400472a5bbb75adb27403e139475e Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sun, 1 Dec 2019 01:40:40 +0300 Subject: [PATCH 61/66] Provide ALE for more checks The following check lists were fixed: ident_lookup_access, client_delay_access and collapsed_forwarding_access. Some adjustments were applied for this purpose, including a new StoreClient::accessLogEntry() API. With this change it was possible to get rid of the public ACLFilledChecklist::setClientConnectionDetails(), because all these details are now configured implicitly in the constructor. Also cleaning up and removing some leftovers. --- src/ICP.h | 1 + src/StoreClient.h | 4 ++++ src/acl/FilledChecklist.cc | 12 ++++-------- src/acl/FilledChecklist.h | 6 +----- src/adaptation/icap/Launcher.cc | 3 +-- src/client_side.cc | 8 ++------ src/client_side_reply.h | 4 ++++ src/clients/Client.cc | 1 - src/htcp.cc | 5 ++++- src/icp_v2.cc | 1 - src/mime.cc | 11 +++++++++++ src/store_client.cc | 2 +- src/urn.cc | 2 +- 13 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/ICP.h b/src/ICP.h index f914821c854..c04fb57017c 100644 --- a/src/ICP.h +++ b/src/ICP.h @@ -82,6 +82,7 @@ class ICPState: public StoreClient /* StoreClient API */ virtual LogTags *loggingTags() override; virtual void fillChecklist(ACLFilledChecklist &) const override; + virtual const AccessLogEntryPointer &accessLogEntry() const override { return al; } /// either confirms and starts processing a cache hit or returns false bool confirmAndPrepHit(const StoreEntry &); diff --git a/src/StoreClient.h b/src/StoreClient.h index 1005de70bba..fdb0d5b268b 100644 --- a/src/StoreClient.h +++ b/src/StoreClient.h @@ -18,6 +18,8 @@ typedef void STCB(void *, StoreIOBuffer); /* store callback */ class StoreEntry; class ACLFilledChecklist; class LogTags; +class AccessLogEntry; +typedef RefCount AccessLogEntryPointer; /// A StoreEntry::getPublic*() caller. class StoreClient @@ -51,6 +53,8 @@ class StoreClient bool mayInitiateCollapsing() const { return onCollapsingPath(); } /// whether Squid configuration allows collapsing for this transaction bool onCollapsingPath() const; + + virtual const AccessLogEntryPointer &accessLogEntry() const = 0; }; #if USE_DELAY_POOLS diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 48fbfbb984e..039ee60beba 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -243,7 +243,7 @@ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_re changeAcl(A); setRequest(http_request); - setClientConnectionDetails(al->clientConnectionManager().get()); + setClientConnectionManager(al->clientConnectionManager().get()); if (!clientConnectionManager()) // could not take the connection from the connection manager setClientConnection(al->tcpClient); setIdent(clientConnection_ ? clientConnection_->rfc931 : dash_str); @@ -273,10 +273,10 @@ ACLFilledChecklist::setClientSideAddresses() if (request) { #if FOLLOW_X_FORWARDED_FOR if (Config.onoff.acl_uses_indirect_client) - InitializeAddress(client_addr, al->furthestClientAddress()); + InitializeAddress(client_addr, al->furthestClientAddress()); else #endif - InitializeAddress(client_addr, al->clientAddr()); + InitializeAddress(client_addr, al->clientAddr()); InitializeAddress(my_addr, al->myAddr()); } else if (clientConnection_) { InitializeAddress(client_addr, clientConnection_->remote); @@ -285,19 +285,15 @@ ACLFilledChecklist::setClientSideAddresses() } void -ACLFilledChecklist::setClientConnectionDetails(ConnStateData *mgr, Comm::ConnectionPointer conn) +ACLFilledChecklist::setClientConnectionManager(ConnStateData *mgr) { if (clientConnectionManager()) return; if (mgr && cbdataReferenceValid(mgr)) { connectionManager_ = cbdataReference(mgr); - Must(!conn || conn == mgr->clientConnection); setClientConnection(mgr->clientConnection); - return; } - - setClientConnection(conn); } /// Configures client-related fields from the passed client connection. diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 6b61b1767f0..00b157fd296 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -47,11 +47,6 @@ class ACLFilledChecklist: public ACLChecklist /// configure rfc931 user identity for the first time void setIdent(const char *userIdentity); - /// Configure client connection-related information. Each and both parameters - /// can be nil (or equivalent). Specifying mgr->clientConnection as the second - /// parameter is useless. - void setClientConnectionDetails(ConnStateData *, Comm::ConnectionPointer conn = nullptr); - #if FOLLOW_X_FORWARDED_FOR /// Instructs clientAddr() to return the indirect client address, if available, /// or direct client address otherwise. @@ -122,6 +117,7 @@ class ACLFilledChecklist: public ACLChecklist err_type requestErrorType; private: + void setClientConnectionManager(ConnStateData *); void setClientConnection(Comm::ConnectionPointer); void setClientSideAddresses(); /// a client connection manager, if any diff --git a/src/adaptation/icap/Launcher.cc b/src/adaptation/icap/Launcher.cc index a402c55dd94..44d449fea86 100644 --- a/src/adaptation/icap/Launcher.cc +++ b/src/adaptation/icap/Launcher.cc @@ -142,8 +142,7 @@ bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info // XXX: we cannot simply pass Xaction::al here, because icapRequest and al->request // represent different objects - ACLFilledChecklist *cl = - new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, nullptr); + auto cl = new ACLFilledChecklist(TheConfig.repeat, info.icapRequest, nullptr); cl->reply = info.icapReply; HTTPMSGLOCK(cl->reply); diff --git a/src/client_side.cc b/src/client_side.cc index f7879741165..50a97b32a00 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2269,8 +2269,7 @@ ConnStateData::whenClientIpKnown() #if USE_IDENT if (Ident::TheConfig.identLookup) { - ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, nullptr, nullptr); - identChecklist.setClientConnectionDetails(this); + ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, nullptr, al); if (identChecklist.fastCheck().allowed()) Ident::Start(clientConnection, clientIdentDone, this); } @@ -2286,8 +2285,7 @@ ConnStateData::whenClientIpKnown() const auto &pools = ClientDelayPools::Instance()->pools; if (pools.size()) { - ACLFilledChecklist ch(nullptr, nullptr, nullptr); - ch.setClientConnectionDetails(this); + ACLFilledChecklist ch(nullptr, nullptr, al); // TODO: we check early to limit error response bandwith but we // should recheck when we can honor delay_pool_uses_indirect @@ -3578,14 +3576,12 @@ void clientAclChecklistFill(ACLFilledChecklist &checklist, ClientHttpRequest *http) { checklist.setRequest(http->request); - checklist.al = http->al; checklist.syncAle(http->request, http->log_uri); // TODO: If http->getConn is always http->request->clientConnectionManager, // then call setIdent() inside checklist.setRequest(). Otherwise, restore // USE_IDENT lost in commit 94439e4. ConnStateData * conn = http->getConn(); - checklist.setClientConnectionDetails(conn); const char *ident = (cbdataReferenceValid(conn) && conn && conn->clientConnection) ? conn->clientConnection->rfc931 : dash_str; diff --git a/src/client_side_reply.h b/src/client_side_reply.h index 9ceaa80bc9b..ee7787a215d 100644 --- a/src/client_side_reply.h +++ b/src/client_side_reply.h @@ -104,6 +104,10 @@ class clientReplyContext : public RefCountable, public StoreClient } flags; clientStreamNode *ourNode; /* This will go away if/when this file gets refactored some more */ +protected: + /* StoreClient API */ + virtual const AccessLogEntryPointer &accessLogEntry() const { return http->al; } + private: /* StoreClient API */ virtual void fillChecklist(ACLFilledChecklist &) const; diff --git a/src/clients/Client.cc b/src/clients/Client.cc index 23fed02716a..432387d7e18 100644 --- a/src/clients/Client.cc +++ b/src/clients/Client.cc @@ -528,7 +528,6 @@ Client::blockCaching() ch.syncAle(request.getRaw(), nullptr); ch.reply = const_cast(&entry->mem().freshestReply()); // ACLFilledChecklist API bug HTTPMSGLOCK(ch.reply); - ch.al = fwd->al; if (!ch.fastCheck().allowed()) { // when in doubt, block debugs(20, 3, "store_miss prohibits caching"); return true; diff --git a/src/htcp.cc b/src/htcp.cc index bd2debcc30b..de5fdcde3f5 100644 --- a/src/htcp.cc +++ b/src/htcp.cc @@ -165,6 +165,10 @@ class htcpSpecifier: public CodeContext, public StoreClient /// optimization: nil until needed mutable AccessLogEntryPointer al; +protected: + /* StoreClient API */ + virtual const AccessLogEntryPointer &accessLogEntry() const { return al; } + private: HttpRequest::Pointer checkHitRequest; @@ -1018,7 +1022,6 @@ htcpSpecifier::fillChecklist(ACLFilledChecklist &checklist) const { checklist.setRequest(request.getRaw()); htcpSyncAle(al, from(), dhdr->opcode, uri); - checklist.al = al; } static void diff --git a/src/icp_v2.cc b/src/icp_v2.cc index c5cba54f20d..eec7d302865 100644 --- a/src/icp_v2.cc +++ b/src/icp_v2.cc @@ -185,7 +185,6 @@ ICPState::fillChecklist(ACLFilledChecklist &checklist) const { checklist.setRequest(request); SyncAle(al, from, url, 0, 0); - checklist.al = al; } /* End ICPState */ diff --git a/src/mime.cc b/src/mime.cc index a3aadb1d01d..bc1064739ce 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -50,6 +50,8 @@ class MimeIcon : public StoreClient virtual void fillChecklist(ACLFilledChecklist &) const; private: + virtual const AccessLogEntryPointer &accessLogEntry() const; + SBuf icon_; char *url_; }; @@ -448,6 +450,15 @@ MimeIcon::fillChecklist(ACLFilledChecklist &) const assert(false); } +const AccessLogEntryPointer & +MimeIcon::accessLogEntry() const +{ + // Unreachable: We never mayInitiateCollapsing() or startCollapsingOn(). + assert(false); + static AccessLogEntryPointer al; + return al; +}; + MimeEntry::~MimeEntry() { xfree(pattern); diff --git a/src/store_client.cc b/src/store_client.cc index d586d533613..48807a731e8 100644 --- a/src/store_client.cc +++ b/src/store_client.cc @@ -59,7 +59,7 @@ StoreClient::onCollapsingPath() const if (!Config.accessList.collapsedForwardingAccess) return true; - ACLFilledChecklist checklist(Config.accessList.collapsedForwardingAccess, nullptr, nullptr); + ACLFilledChecklist checklist(Config.accessList.collapsedForwardingAccess, nullptr, accessLogEntry()); fillChecklist(checklist); return checklist.fastCheck().allowed(); } diff --git a/src/urn.cc b/src/urn.cc index cbe6e66c8d9..a60cba13b05 100644 --- a/src/urn.cc +++ b/src/urn.cc @@ -57,6 +57,7 @@ class UrnState : public StoreClient /* StoreClient API */ virtual LogTags *loggingTags() { return ale ? &ale->cache.code : nullptr; } virtual void fillChecklist(ACLFilledChecklist &) const; + virtual const AccessLogEntryPointer &accessLogEntry() const { return ale; } char *urlres = nullptr; }; @@ -182,7 +183,6 @@ void UrnState::fillChecklist(ACLFilledChecklist &checklist) const { checklist.setRequest(request.getRaw()); - checklist.al = ale; checklist.syncAle(request.getRaw(), nullptr); } From db4e1b353a68d9ed523bc99a6703922037411e64 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 10 Dec 2019 18:32:26 +0300 Subject: [PATCH 62/66] Eliminated an Address.isAnyAddr() misuse Basically, Ssl::setClientSNI() checks whether the passed string is FQDN or not. It did it in an obscure way, passing the string to Ip::Address constructor (which expects a numeric address, not documented behavior), and testing by means of isAnyAddr() whether the created Ip::Address object has got a meaningful value. Ideally, this check should be performed by a static Ip::Address method (for example returning true if the passed name is FQDN). Since Ip::Address lacks such a method, I decided to utilize Ip::Address::operator= for this check, similarly to many other existing places (see e.g., idnsAddNameserver()). --- src/ssl/support.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ssl/support.cc b/src/ssl/support.cc index 75029f0bd3b..f0b790d22a3 100644 --- a/src/ssl/support.cc +++ b/src/ssl/support.cc @@ -896,8 +896,8 @@ Ssl::verifySslCertificate(Security::ContextPointer &ctx, CertificateProperties c void Ssl::setClientSNI(SSL *ssl, const char *fqdn) { - const Ip::Address test(fqdn); - if (!test.isAnyAddr()) + Ip::Address test; + if (test = fqdn) return; // raw IP is inappropriate for SNI //The SSL_CTRL_SET_TLSEXT_HOSTNAME is a openssl macro which indicates From 6d91ff11d449b50e0dfa60f2368709d1242eb3f3 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 10 Dec 2019 18:42:36 +0300 Subject: [PATCH 63/66] Fixed Ip::Address::isBindable() A created by default Ip::Address is 'empty', but at the same time is 'bindable', because in the current Ip::Address implementation 'empty' and 'is any addr' states are equivalent. --- src/ip/Address.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ip/Address.cc b/src/ip/Address.cc index 8a5f4ea9e55..e7d8553abf0 100644 --- a/src/ip/Address.cc +++ b/src/ip/Address.cc @@ -151,7 +151,7 @@ Ip::Address::applyMask(const unsigned int cidrMask, int mtype) bool Ip::Address::isBindable() const { - return !isEmpty() && !isNoAddr(); + return !isNoAddr(); } bool From 37bd940bdc0c560f6aa2cf33a0e11d73d0d0c714 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 10 Dec 2019 19:39:09 +0300 Subject: [PATCH 64/66] Eliminated Ip::Address::isEmpty() isEmpty() was used previously in this branch to check whether a (remote) client address was provided, i.e. the address returned by ALE::clientAddr() has a value from the default one. The problem with this approach is that isEmpty(), returning true, corresponds to the same (default) Ip::Address as the existing isAnyAddr(). Simply calling isAnyAddr() instead for client address lacks any sense: it is applicable (as well as the underlying low-level INADDR_ANY option) only to local server addresses (i.e., bindable addresses). Moreover, the existing isEmtpy() check does not take into account a special 'no addr' value. I used Address::isKnown() to overcome both these problems. --- src/FwdState.cc | 2 +- src/ip/Address.cc | 7 ------- src/ip/Address.h | 3 --- src/tunnel.cc | 2 +- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/FwdState.cc b/src/FwdState.cc index 6887a2f0840..befd206f921 100644 --- a/src/FwdState.cc +++ b/src/FwdState.cc @@ -328,7 +328,7 @@ FwdState::~FwdState() void FwdState::Start(const Comm::ConnectionPointer &clientConn, StoreEntry *entry, HttpRequest *request, const AccessLogEntryPointer &al) { - if (Config.accessList.miss && !al->clientAddr().isEmpty() && request->needCheckMissAccess()) { + if (Config.accessList.miss && al->clientAddr().isKnown() && request->needCheckMissAccess()) { // Check if this host is allowed to fetch MISSES from us (miss_access). ACLFilledChecklist ch(Config.accessList.miss, request, al); // TODO: Explain this acl_uses_indirect_client violation in squid.conf. diff --git a/src/ip/Address.cc b/src/ip/Address.cc index e7d8553abf0..d66258144e0 100644 --- a/src/ip/Address.cc +++ b/src/ip/Address.cc @@ -197,13 +197,6 @@ Ip::Address::isAnyAddr() const return IN6_IS_ADDR_UNSPECIFIED(&mSocketAddr_.sin6_addr) || IN6_ARE_ADDR_EQUAL(&mSocketAddr_.sin6_addr, &v4_anyaddr); } -bool -Ip::Address::isEmpty() const -{ - static const Ip::Address emptyAddr; - return *this == emptyAddr; -} - /// NOTE: Does NOT clear the Port stored. Ony the Address and Type. void Ip::Address::setAnyAddr() diff --git a/src/ip/Address.h b/src/ip/Address.h index 8b39fa5517c..98acc792449 100644 --- a/src/ip/Address.h +++ b/src/ip/Address.h @@ -327,9 +327,6 @@ class Address void getSockAddr(struct sockaddr_in6 &) const; void getInAddr(struct in6_addr &) const; - /// whether the address is the same as the one created with default constructor - bool isEmpty() const; - private: /* Conversion for dual-type internals */ diff --git a/src/tunnel.cc b/src/tunnel.cc index 907f4df27ea..47d8b6cae44 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -958,7 +958,7 @@ tunnelStart(ClientHttpRequest * http) HttpRequest *request = http->request; char *url = http->uri; - if (Config.accessList.miss && !tunnelState->al->clientAddr().isEmpty() && request->needCheckMissAccess()) { + if (Config.accessList.miss && tunnelState->al->clientAddr().isKnown() && request->needCheckMissAccess()) { /* * Check if this host is allowed to fetch MISSES from us (miss_access) * default is to allow. From aed4646a10395a618102676b0abb8ec4b2b856ec Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Tue, 10 Dec 2019 20:05:05 +0300 Subject: [PATCH 65/66] Removed useless Ip::Address::setEmpty() initialization calls ... because the newly created Address is 'empty' by default. --- src/acl/FilledChecklist.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index 039ee60beba..1543f16e77b 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -42,9 +42,6 @@ ACLFilledChecklist::ACLFilledChecklist() : destinationDomainChecked_(false), sourceDomainChecked_(false) { - my_addr.setEmpty(); - client_addr.setEmpty(); - dst_addr.setEmpty(); rfc931[0] = '\0'; } From e8c9c4db02be69673c18c53dad8d02757a7acda8 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Fri, 13 Dec 2019 16:52:32 +0300 Subject: [PATCH 66/66] Fixed a couple of typos made when moving to a new Ip::Address::isKnown() --- src/servers/FtpServer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/servers/FtpServer.cc b/src/servers/FtpServer.cc index 48e4c1f15c4..a87ea0eabe1 100644 --- a/src/servers/FtpServer.cc +++ b/src/servers/FtpServer.cc @@ -1376,7 +1376,7 @@ Ftp::Server::handleUserRequest(const SBuf &, SBuf ¶ms) // Otherwise (domain, IPv4, [bracketed] IPv6, garbage, etc), use as is. if (host.find(':') != SBuf::npos) { const Ip::Address ipa(host.c_str()); - if (!ipa.isKnown()) { + if (ipa.isKnown()) { char ipBuf[MAX_IPSTRLEN]; ipa.toHostStr(ipBuf, MAX_IPSTRLEN); host = ipBuf; @@ -1437,7 +1437,7 @@ bool Ftp::Server::createDataConnection(Ip::Address cltAddr) { assert(clientConnection != NULL); - assert(!clientConnection->remote.isKnown()); + assert(clientConnection->remote.isKnown()); if (cltAddr != clientConnection->remote) { debugs(33, 2, "rogue PORT " << cltAddr << " request? ctrl: " << clientConnection->remote);