From 8319d478be54a358aa11d7a134aababc81eb9285 Mon Sep 17 00:00:00 2001 From: Alex Rousskov Date: Tue, 8 Aug 2023 13:36:09 +0000 Subject: [PATCH] Replaced ACLStrategised, enabling other ACL improvements (#1392) The ACLStrategised class stands in the way of several ACL bug fixes and improvements because its design forces us to place ACL-like match() methods inside non-ACL classes, creating two parallel matching hierarchies: one rooted in the ACL class and one rooted in the Strategy template. The two APIs have similar methods, but Strategy-based objects lie outside the ACL hierarchy and cannot be treated as ACL objects. ACLStrategised pairs an ACL-like matching algorithm (a Strategy-derived class) with an ACLData-derived class. The need to combine the two is genuine, but the same combination is best supported without creating a parallel hierarchy of Strategy classes. The new ACL-derived ParameterizedNode base class accomplishes that, addressing the old ACLStrategised design XXX. Strategy-derived classes were not pooled at all! With these changes, all formerly ACLStrategised classes get individual memory pools, typically one per acltype, with proper acltype-based naming in mgr:mem reports. No other functionality changes intended. --- src/AclRegs.cc | 173 ++++++++++++++++++++++++-------- src/acl/AdaptationService.cc | 6 +- src/acl/AdaptationService.h | 14 ++- src/acl/AnnotateClient.cc | 7 +- src/acl/AnnotateClient.h | 13 ++- src/acl/AnnotateTransaction.cc | 7 +- src/acl/AnnotateTransaction.h | 13 ++- src/acl/Asn.cc | 15 ++- src/acl/AtStep.cc | 5 +- src/acl/AtStep.h | 14 ++- src/acl/Certificate.cc | 10 +- src/acl/Certificate.h | 15 +-- src/acl/DestinationAsn.h | 17 ++-- src/acl/DestinationDomain.cc | 10 +- src/acl/DestinationDomain.h | 15 +-- src/acl/Gadgets.cc | 3 - src/acl/HasComponent.cc | 4 +- src/acl/HasComponent.h | 16 ++- src/acl/HierCode.cc | 12 +-- src/acl/HierCode.h | 14 ++- src/acl/HttpRepHeader.cc | 4 +- src/acl/HttpRepHeader.h | 15 ++- src/acl/HttpReqHeader.cc | 4 +- src/acl/HttpReqHeader.h | 14 ++- src/acl/LocalPort.cc | 4 +- src/acl/LocalPort.h | 14 ++- src/acl/Makefile.am | 4 +- src/acl/Method.cc | 10 +- src/acl/Method.h | 14 ++- src/acl/MyPortName.cc | 5 +- src/acl/MyPortName.h | 14 ++- src/acl/Note.cc | 18 ++-- src/acl/Note.h | 20 ++-- src/acl/ParameterizedNode.h | 49 +++++++++ src/acl/PeerName.cc | 6 +- src/acl/PeerName.h | 13 ++- src/acl/Protocol.cc | 10 +- src/acl/Protocol.h | 13 ++- src/acl/ReplyHeaderStrategy.h | 20 ++-- src/acl/ReplyMimeType.h | 4 +- src/acl/RequestHeaderStrategy.h | 20 ++-- src/acl/RequestMimeType.h | 4 +- src/acl/ServerCertificate.cc | 7 +- src/acl/ServerCertificate.h | 16 +-- src/acl/ServerName.cc | 15 ++- src/acl/ServerName.h | 14 ++- src/acl/SourceAsn.h | 17 ++-- src/acl/SourceDomain.cc | 4 +- src/acl/SourceDomain.h | 15 ++- src/acl/SquidError.cc | 4 +- src/acl/SquidError.h | 13 ++- src/acl/SslError.cc | 5 +- src/acl/SslError.h | 13 ++- src/acl/Strategised.cc | 31 ------ src/acl/Strategised.h | 127 ----------------------- src/acl/Strategy.h | 40 -------- src/acl/Tag.cc | 5 +- src/acl/Tag.h | 13 ++- src/acl/Time.cc | 4 +- src/acl/Time.h | 16 ++- src/acl/Url.cc | 5 +- src/acl/Url.h | 12 ++- src/acl/UrlLogin.cc | 5 +- src/acl/UrlLogin.h | 13 ++- src/acl/UrlPath.cc | 5 +- src/acl/UrlPath.h | 13 ++- src/acl/UrlPort.cc | 4 +- src/acl/UrlPort.h | 13 ++- src/mem/Allocator.h | 6 +- src/mem/AllocatorProxy.cc | 7 ++ src/mem/AllocatorProxy.h | 3 + src/snmp_core.cc | 4 +- src/snmp_core.h | 14 ++- 73 files changed, 638 insertions(+), 487 deletions(-) create mode 100644 src/acl/ParameterizedNode.h delete mode 100644 src/acl/Strategised.cc delete mode 100644 src/acl/Strategised.h delete mode 100644 src/acl/Strategy.h diff --git a/src/AclRegs.cc b/src/AclRegs.cc index 166e3bdad7..58fab91815 100644 --- a/src/AclRegs.cc +++ b/src/AclRegs.cc @@ -81,8 +81,6 @@ #include "acl/SslError.h" #include "acl/SslErrorData.h" #endif -#include "acl/Strategised.h" -#include "acl/Strategy.h" #include "acl/StringData.h" #if USE_OPENSSL #include "acl/ServerCertificate.h" @@ -108,6 +106,85 @@ #if SQUID_SNMP #include "snmp_core.h" #endif +#include "sbuf/Stream.h" + +namespace Acl +{ + +/// Constructs a ParameterizedNode-derived ACL (specified as a Parent class). +/// This template exists to avoid placing a variant of this ACL construction +/// code in each ParameterizedNode-derived ACL class just to pass through +/// TypeName and Parameters onto ParameterizedNode (and to add MEMPROXY_CLASS). +template +class FinalizedParameterizedNode: public Parent +{ + MEMPROXY_CLASS(Acl::FinalizedParameterizedNode); + +public: + using Parameters = typename Parent::Parameters; + using Parent::data; + + /// Replaces generic memory allocator label X set by our MEMPROXY_CLASS(X) + /// with an admin-friendly label based on the given acltype-like name. + /// Normally, our class constructor sets the right allocator label using the + /// actlype name, but that algorithm results in unstable and misleading + /// labels when the same instantiation of this template class is used for + /// _multiple_ acltype names. Calling this method corrects that behavior. + /// \prec this method must be called at most once + /// \prec if called, this method must be called before the class constructor + static void PreferAllocatorLabelPrefix(const char * const suffix) + { + assert(!PreferredAllocatorLabelSuffix); // must be called at most once + assert(!FinalPoolLabel); // must be called before the class constructor + assert(suffix); + PreferredAllocatorLabelSuffix = suffix; + } + + FinalizedParameterizedNode(TypeName typeName, Parameters * const params): + typeName_(typeName) + { + Assure(!data); // base classes never set this data member + data.reset(params); + Assure(data); // ... but we always do + + FinalizePoolLabel(typeName); + } + + ~FinalizedParameterizedNode() override = default; + + /* ACL API */ + const char *typeString() const override { return typeName_; } + +private: + /// A constructor helper function that replaces generic memory allocator + /// label X set by our MEMPROXY_CLASS(X) with an admin-friendly label based + /// on the acltype name from squid.conf. Meant to be called from the + /// constructor so that no mgr:mem report lists this C++ template class + /// statistics using label X. Repeated calls are allowed but have no effect. + /// \sa PreferAllocatorLabelPrefix() + static void FinalizePoolLabel(const TypeName typeName) + { + if (FinalPoolLabel) + return; // the label has been finalized already + + assert(typeName); + const auto label = ToSBuf("acltype=", PreferredAllocatorLabelSuffix ? PreferredAllocatorLabelSuffix : typeName); + FinalPoolLabel = SBufToCstring(label); + Pool().relabel(FinalPoolLabel); + } + + /// if set, overrules FinalizePoolLabel() argument + inline static const char *PreferredAllocatorLabelSuffix = nullptr; + + /// custom allocator label set by FinalizePoolLabel() + inline static const char *FinalPoolLabel = nullptr; + + // TODO: Consider storing the spelling used by the admin instead. + /// the "acltype" name in its canonical spelling + TypeName typeName_; +}; + +} // namespace Acl // Not in src/acl/ because some of the ACLs it registers are not in src/acl/. void @@ -122,43 +199,52 @@ Acl::Init() RegisterMaker("all-of", [](TypeName)->ACL* { return new Acl::AllOf; }); // XXX: Add name parameter to ctor RegisterMaker("any-of", [](TypeName)->ACL* { return new Acl::AnyOf; }); // XXX: Add name parameter to ctor RegisterMaker("random", [](TypeName name)->ACL* { return new ACLRandom(name); }); - RegisterMaker("time", [](TypeName name)->ACL* { return new ACLStrategised(new ACLTimeData, new ACLTimeStrategy, name); }); - RegisterMaker("src_as", [](TypeName name)->ACL* { return new ACLStrategised(new ACLASN, new ACLSourceASNStrategy, name); }); - RegisterMaker("dst_as", [](TypeName name)->ACL* { return new ACLStrategised(new ACLASN, new ACLDestinationASNStrategy, name); }); - RegisterMaker("browser", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); - RegisterMaker("dstdomain", [](TypeName name)->ACL* { return new ACLStrategised(new ACLDomainData, new ACLDestinationDomainStrategy, name); }); - RegisterMaker("dstdom_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLDestinationDomainStrategy, name); }); + RegisterMaker("time", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLTimeData); }); + RegisterMaker("src_as", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLASN); }); + RegisterMaker("dst_as", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLASN); }); + RegisterMaker("browser", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode >(name, new ACLRegexData); }); + + RegisterMaker("dstdomain", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLDomainData); }); + RegisterMaker("dstdom_regex", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLRegexData); }); + Acl::FinalizedParameterizedNode::PreferAllocatorLabelPrefix("dstdomain+"); + RegisterMaker("dst", [](TypeName)->ACL* { return new ACLDestinationIP; }); // XXX: Add name parameter to ctor - RegisterMaker("hier_code", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHierCodeData, new ACLHierCodeStrategy, name); }); - RegisterMaker("rep_header", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHTTPHeaderData, new ACLHTTPRepHeaderStrategy, name); }); - RegisterMaker("req_header", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHTTPHeaderData, new ACLHTTPReqHeaderStrategy, name); }); + RegisterMaker("hier_code", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLHierCodeData); }); + RegisterMaker("rep_header", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLHTTPHeaderData); }); + RegisterMaker("req_header", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLHTTPHeaderData); }); RegisterMaker("http_status", [](TypeName name)->ACL* { return new ACLHTTPStatus(name); }); RegisterMaker("maxconn", [](TypeName name)->ACL* { return new ACLMaxConnection(name); }); - RegisterMaker("method", [](TypeName name)->ACL* { return new ACLStrategised(new ACLMethodData, new ACLMethodStrategy, name); }); + RegisterMaker("method", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLMethodData); }); RegisterMaker("localip", [](TypeName)->ACL* { return new ACLLocalIP; }); // XXX: Add name parameter to ctor - RegisterMaker("localport", [](TypeName name)->ACL* { return new ACLStrategised(new ACLIntRange, new ACLLocalPortStrategy, name); }); - RegisterMaker("myportname", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLMyPortNameStrategy, name); }); - RegisterMaker("peername", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLPeerNameStrategy, name); }); - RegisterMaker("peername_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLPeerNameStrategy, name); }); - RegisterMaker("proto", [](TypeName name)->ACL* { return new ACLStrategised(new ACLProtocolData, new ACLProtocolStrategy, name); }); - RegisterMaker("referer_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); - RegisterMaker("rep_mime_type", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLReplyHeaderStrategy, name); }); - RegisterMaker("req_mime_type", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); - RegisterMaker("srcdomain", [](TypeName name)->ACL* { return new ACLStrategised(new ACLDomainData, new ACLSourceDomainStrategy, name); }); - RegisterMaker("srcdom_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLSourceDomainStrategy, name); }); + RegisterMaker("localport", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLIntRange); }); + RegisterMaker("myportname", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLStringData); }); + + RegisterMaker("peername", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLStringData); }); + RegisterMaker("peername_regex", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLRegexData); }); + Acl::FinalizedParameterizedNode::PreferAllocatorLabelPrefix("peername+"); + + RegisterMaker("proto", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLProtocolData); }); + RegisterMaker("referer_regex", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode >(name, new ACLRegexData); }); + RegisterMaker("rep_mime_type", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode >(name, new ACLRegexData); }); + RegisterMaker("req_mime_type", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode >(name, new ACLRegexData); }); + + RegisterMaker("srcdomain", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLDomainData); }); + RegisterMaker("srcdom_regex", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLRegexData); }); + Acl::FinalizedParameterizedNode::PreferAllocatorLabelPrefix("srcdomain+"); + RegisterMaker("src", [](TypeName)->ACL* { return new ACLSourceIP; }); // XXX: Add name parameter to ctor - RegisterMaker("url_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlStrategy, name); }); - RegisterMaker("urllogin", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlLoginStrategy, name); }); - RegisterMaker("urlpath_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlPathStrategy, name); }); - RegisterMaker("port", [](TypeName name)->ACL* { return new ACLStrategised(new ACLIntRange, new ACLUrlPortStrategy, name); }); + RegisterMaker("url_regex", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLRegexData); }); + RegisterMaker("urllogin", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLRegexData); }); + RegisterMaker("urlpath_regex", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLRegexData); }); + RegisterMaker("port", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLIntRange); }); RegisterMaker("external", [](TypeName name)->ACL* { return new ACLExternal(name); }); - RegisterMaker("squid_error", [](TypeName name)->ACL* { return new ACLStrategised(new ACLSquidErrorData, new ACLSquidErrorStrategy, name); }); + RegisterMaker("squid_error", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLSquidErrorData); }); RegisterMaker("connections_encrypted", [](TypeName name)->ACL* { return new Acl::ConnectionsEncrypted(name); }); - RegisterMaker("tag", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLTagStrategy, name); }); - RegisterMaker("note", [](TypeName name)->ACL* { return new ACLStrategised(new ACLNoteData, new ACLNoteStrategy, name); }); - RegisterMaker("annotate_client", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAnnotationData, new ACLAnnotateClientStrategy, name); }); - RegisterMaker("annotate_transaction", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAnnotationData, new ACLAnnotateTransactionStrategy, name); }); - RegisterMaker("has", [](TypeName name)->ACL* {return new ACLStrategised(new ACLHasComponentData, new ACLHasComponentStrategy, name); }); + RegisterMaker("tag", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLStringData); }); + RegisterMaker("note", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLNoteData); }); + RegisterMaker("annotate_client", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLAnnotationData); }); + RegisterMaker("annotate_transaction", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLAnnotationData); }); + RegisterMaker("has", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLHasComponentData); }); RegisterMaker("transaction_initiator", [](TypeName name)->ACL* {return new TransactionInitiator(name);}); #if USE_LIBNETFILTERCONNTRACK @@ -167,13 +253,18 @@ Acl::Init() #endif #if USE_OPENSSL - RegisterMaker("ssl_error", [](TypeName name)->ACL* { return new ACLStrategised(new ACLSslErrorData, new ACLSslErrorStrategy, name); }); - RegisterMaker("user_cert", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509UserAttribute, "*"), new ACLCertificateStrategy, name); }); - RegisterMaker("ca_cert", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509CAAttribute, "*"), new ACLCertificateStrategy, name); }); - RegisterMaker("server_cert_fingerprint", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509Fingerprint, nullptr, true), new ACLServerCertificateStrategy, name); }); - RegisterMaker("at_step", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAtStepData, new ACLAtStepStrategy, name); }); - RegisterMaker("ssl::server_name", [](TypeName name)->ACL* { return new ACLStrategised(new ACLServerNameData, new ACLServerNameStrategy, name); }); - RegisterMaker("ssl::server_name_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLServerNameStrategy, name); }); + RegisterMaker("ssl_error", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLSslErrorData); }); + + RegisterMaker("user_cert", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLCertificateData(Ssl::GetX509UserAttribute, "*")); }); + RegisterMaker("ca_cert", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLCertificateData(Ssl::GetX509CAAttribute, "*")); }); + Acl::FinalizedParameterizedNode::PreferAllocatorLabelPrefix("user_cert+"); + + RegisterMaker("server_cert_fingerprint", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLCertificateData(Ssl::GetX509Fingerprint, nullptr, true)); }); + RegisterMaker("at_step", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLAtStepData); }); + + RegisterMaker("ssl::server_name", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLServerNameData); }); + RegisterMaker("ssl::server_name_regex", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLRegexData); }); + Acl::FinalizedParameterizedNode::PreferAllocatorLabelPrefix("ssl::server_name+"); #endif #if USE_SQUID_EUI @@ -195,11 +286,11 @@ Acl::Init() #endif #if USE_ADAPTATION - RegisterMaker("adaptation_service", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAdaptationServiceData, new ACLAdaptationServiceStrategy, name); }); + RegisterMaker("adaptation_service", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLAdaptationServiceData); }); #endif #if SQUID_SNMP - RegisterMaker("snmp_community", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLSNMPCommunityStrategy, name); }); + RegisterMaker("snmp_community", [](TypeName name)->ACL* { return new Acl::FinalizedParameterizedNode(name, new ACLStringData); }); #endif } diff --git a/src/acl/AdaptationService.cc b/src/acl/AdaptationService.cc index 8686efdda1..f5c0f00b71 100644 --- a/src/acl/AdaptationService.cc +++ b/src/acl/AdaptationService.cc @@ -9,14 +9,14 @@ #include "squid.h" #include "acl/AdaptationService.h" #include "acl/FilledChecklist.h" -#include "acl/IntRange.h" -#include "adaptation/Config.h" #include "adaptation/History.h" #include "HttpRequest.h" int -ACLAdaptationServiceStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::AdaptationServiceCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + HttpRequest::Pointer request = checklist->request; if (request == nullptr) return 0; diff --git a/src/acl/AdaptationService.h b/src/acl/AdaptationService.h index 1fb997c2db..92e7416c2b 100644 --- a/src/acl/AdaptationService.h +++ b/src/acl/AdaptationService.h @@ -9,15 +9,21 @@ #ifndef SQUID_ACLADAPTATIONSERVICE_H #define SQUID_ACLADAPTATIONSERVICE_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" -/// \ingroup ACLAPI -class ACLAdaptationServiceStrategy : public ACLStrategy +namespace Acl { +/// an "adaptation_service" ACL +class AdaptationServiceCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLADAPTATIONSERVICE_H */ diff --git a/src/acl/AnnotateClient.cc b/src/acl/AnnotateClient.cc index 9282a92f8d..a2080047d6 100644 --- a/src/acl/AnnotateClient.cc +++ b/src/acl/AnnotateClient.cc @@ -12,13 +12,14 @@ #include "acl/FilledChecklist.h" #include "client_side.h" #include "http/Stream.h" -#include "Notes.h" int -ACLAnnotateClientStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::AnnotateClientCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (const auto conn = checklist->conn()) { - ACLAnnotationData *tdata = dynamic_cast(data); + const auto tdata = dynamic_cast(data.get()); assert(tdata); tdata->annotate(conn->notes(), &delimiters.value, checklist->al); if (const auto request = checklist->request) diff --git a/src/acl/AnnotateClient.h b/src/acl/AnnotateClient.h index ec4df279c3..ce714970c4 100644 --- a/src/acl/AnnotateClient.h +++ b/src/acl/AnnotateClient.h @@ -10,15 +10,20 @@ #define SQUID_ACLANNOTATECLIENT #include "acl/Note.h" -#include "Notes.h" -/// \ingroup ACLAPI -class ACLAnnotateClientStrategy : public Acl::AnnotationStrategy +namespace Acl +{ + +/// an "annotate_client" ACL +class AnnotateClientCheck: public Acl::AnnotationCheck { public: + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override { return true; } - int match(ACLData * &, ACLFilledChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLANNOTATECLIENT */ diff --git a/src/acl/AnnotateTransaction.cc b/src/acl/AnnotateTransaction.cc index ee4ea29fcf..39d027734f 100644 --- a/src/acl/AnnotateTransaction.cc +++ b/src/acl/AnnotateTransaction.cc @@ -11,13 +11,14 @@ #include "acl/AnnotationData.h" #include "acl/FilledChecklist.h" #include "HttpRequest.h" -#include "Notes.h" int -ACLAnnotateTransactionStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::AnnotateTransactionCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (const auto request = checklist->request) { - ACLAnnotationData *tdata = dynamic_cast(data); + const auto tdata = dynamic_cast(data.get()); assert(tdata); tdata->annotate(request->notes(), &delimiters.value, checklist->al); return 1; diff --git a/src/acl/AnnotateTransaction.h b/src/acl/AnnotateTransaction.h index 08211e1039..147fcec75b 100644 --- a/src/acl/AnnotateTransaction.h +++ b/src/acl/AnnotateTransaction.h @@ -10,15 +10,20 @@ #define SQUID_ACLANNOTATETRANSACTION #include "acl/Note.h" -#include "Notes.h" -/// \ingroup ACLAPI -class ACLAnnotateTransactionStrategy: public Acl::AnnotationStrategy +namespace Acl +{ + +/// an "annotate_transaction" ACL +class AnnotateTransactionCheck: public Acl::AnnotationCheck { public: - int match(ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override { return true; } }; +} // namespace Acl + #endif /* SQUID_ACLANNOTATETRANSACTION */ diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index f3d20138ee..f1e318b1c7 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -11,11 +11,10 @@ #include "squid.h" #include "acl/Acl.h" #include "acl/Asn.h" -#include "acl/Checklist.h" #include "acl/DestinationAsn.h" #include "acl/DestinationIp.h" +#include "acl/FilledChecklist.h" #include "acl/SourceAsn.h" -#include "acl/Strategised.h" #include "base/CharacterSet.h" #include "FwdState.h" #include "HttpReply.h" @@ -517,19 +516,19 @@ ACLASN::parse() } } -/* explicit template instantiation required for some systems */ - -template class ACLStrategised; - int -ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::SourceAsnCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match(checklist->src_addr); } int -ACLDestinationASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::DestinationAsnCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->url.host(), IP_LOOKUP_IF_MISS); if (ia) { diff --git a/src/acl/AtStep.cc b/src/acl/AtStep.cc index 8f92897b95..0eb56051d2 100644 --- a/src/acl/AtStep.cc +++ b/src/acl/AtStep.cc @@ -9,7 +9,6 @@ #include "squid.h" #include "acl/AtStep.h" -#include "acl/AtStepData.h" #include "acl/FilledChecklist.h" #include "client_side.h" #include "http/Stream.h" @@ -18,8 +17,10 @@ #endif int -ACLAtStepStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::AtStepCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + #if USE_OPENSSL // We use step1 for all these very different cases: // - The transaction is not subject to ssl_bump rules (if any). diff --git a/src/acl/AtStep.h b/src/acl/AtStep.h index e3d8018bd1..6c315da64e 100644 --- a/src/acl/AtStep.h +++ b/src/acl/AtStep.h @@ -9,16 +9,22 @@ #ifndef SQUID_ACLATSTEP_H #define SQUID_ACLATSTEP_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "XactionStep.h" -/// \ingroup ACLAPI -class ACLAtStepStrategy: public ACLStrategy +namespace Acl { +/// an "at_step" ACL +class AtStepCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLATSTEP_H */ diff --git a/src/acl/Certificate.cc b/src/acl/Certificate.cc index f08835dea3..4416249202 100644 --- a/src/acl/Certificate.cc +++ b/src/acl/Certificate.cc @@ -16,17 +16,15 @@ #if USE_OPENSSL #include "acl/Certificate.h" -#include "acl/CertificateData.h" -#include "acl/Checklist.h" -#include "client_side.h" +#include "acl/FilledChecklist.h" #include "fde.h" #include "globals.h" -#include "http/Stream.h" -#include "HttpRequest.h" int -ACLCertificateStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::ClientCertificateCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + const int fd = checklist->fd(); const bool goodDescriptor = 0 <= fd && fd <= Biggest_FD; auto ssl = goodDescriptor ? fd_table[fd].ssl.get() : nullptr; diff --git a/src/acl/Certificate.h b/src/acl/Certificate.h index e8fc70144b..baadebce85 100644 --- a/src/acl/Certificate.h +++ b/src/acl/Certificate.h @@ -9,19 +9,22 @@ #ifndef SQUID_ACLCERTIFICATE_H #define SQUID_ACLCERTIFICATE_H -#include "acl/Acl.h" -#include "acl/Checklist.h" #include "acl/Data.h" -#include "acl/Strategised.h" +#include "acl/ParameterizedNode.h" #include "ssl/support.h" -/// \ingroup ACLAPI -class ACLCertificateStrategy : public ACLStrategy +namespace Acl { +/// a "user_cert" or "ca_cert" ACL +class ClientCertificateCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLCERTIFICATE_H */ diff --git a/src/acl/DestinationAsn.h b/src/acl/DestinationAsn.h index f7da6511e0..7955a8ff96 100644 --- a/src/acl/DestinationAsn.h +++ b/src/acl/DestinationAsn.h @@ -9,18 +9,23 @@ #ifndef SQUID_ACLDESTINATIONASN_H #define SQUID_ACLDESTINATIONASN_H -#include "acl/Asn.h" -#include "acl/Strategy.h" -#include "ip/Address.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" +#include "ip/forward.h" -/// \ingroup ACLAPI -class ACLDestinationASNStrategy : public ACLStrategy +namespace Acl { +/// a "dst_as" ACL +class DestinationAsnCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + #endif /* SQUID_ACLDESTINATIONASN_H */ diff --git a/src/acl/DestinationDomain.cc b/src/acl/DestinationDomain.cc index c7450e13b1..156cee0574 100644 --- a/src/acl/DestinationDomain.cc +++ b/src/acl/DestinationDomain.cc @@ -9,9 +9,9 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" #include "acl/DestinationDomain.h" #include "acl/DomainData.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "fqdncache.h" #include "HttpRequest.h" @@ -40,10 +40,10 @@ DestinationDomainLookup::LookupDone(const char *, const Dns::LookupDetails &deta checklist->resumeNonBlockingCheck(DestinationDomainLookup::Instance()); } -/* ACLDestinationDomainStrategy */ +/* Acl::DestinationDomainCheck */ const Acl::Options & -ACLDestinationDomainStrategy::options() +Acl::DestinationDomainCheck::options() { static const Acl::BooleanOption LookupBanFlag("-n"); static const Acl::Options MyOptions = { &LookupBanFlag }; @@ -52,8 +52,10 @@ ACLDestinationDomainStrategy::options() } int -ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::DestinationDomainCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + assert(checklist != nullptr && checklist->request != nullptr); if (data->match(checklist->request->url.host())) { diff --git a/src/acl/DestinationDomain.h b/src/acl/DestinationDomain.h index 6ed635d816..8910bf4ec0 100644 --- a/src/acl/DestinationDomain.h +++ b/src/acl/DestinationDomain.h @@ -9,19 +9,20 @@ #ifndef SQUID_ACLDESTINATIONDOMAIN_H #define SQUID_ACLDESTINATIONDOMAIN_H -#include "acl/Acl.h" #include "acl/Checklist.h" #include "acl/Data.h" -#include "acl/Strategised.h" +#include "acl/ParameterizedNode.h" #include "dns/forward.h" -/// \ingroup ACLAPI -class ACLDestinationDomainStrategy : public ACLStrategy +namespace Acl { +/// a "dstdomain" or "dstdom_regex" ACL +class DestinationDomainCheck: public ParameterizedNode< ACLData > +{ public: - /* ACLStrategy API */ - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} const Acl::Options &options() override; @@ -29,6 +30,8 @@ private: Acl::BooleanOptionValue lookupBanned; ///< Are DNS lookups allowed? }; +} // namespace Acl + /// \ingroup ACLAPI class DestinationDomainLookup : public ACLChecklist::AsyncState { diff --git a/src/acl/Gadgets.cc b/src/acl/Gadgets.cc index 605d409d7a..fd65b519fa 100644 --- a/src/acl/Gadgets.cc +++ b/src/acl/Gadgets.cc @@ -17,11 +17,8 @@ */ #include "squid.h" -#include "acl/Acl.h" #include "acl/AclDenyInfoList.h" -#include "acl/Checklist.h" #include "acl/Gadgets.h" -#include "acl/Strategised.h" #include "acl/Tree.h" #include "cache_cf.h" #include "ConfigParser.h" diff --git a/src/acl/HasComponent.cc b/src/acl/HasComponent.cc index 5c9136f9a2..e03e6b8de9 100644 --- a/src/acl/HasComponent.cc +++ b/src/acl/HasComponent.cc @@ -11,9 +11,9 @@ #include "acl/HasComponentData.h" int -ACLHasComponentStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::HasComponentCheck::match(ACLChecklist * const checklist) { - ACLHasComponentData *cdata = dynamic_cast(data); + const auto cdata = dynamic_cast(data.get()); assert(cdata); return cdata->match(checklist); } diff --git a/src/acl/HasComponent.h b/src/acl/HasComponent.h index a0a8e5203e..9c26689db1 100644 --- a/src/acl/HasComponent.h +++ b/src/acl/HasComponent.h @@ -9,15 +9,21 @@ #ifndef SQUID_ACLHASCOMPONENT_H #define SQUID_ACLHASCOMPONENT_H -#include "acl/Strategised.h" -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" -/// \ingroup ACLAPI -class ACLHasComponentStrategy : public ACLStrategy +namespace Acl +{ + +/// a "has" ACL +class HasComponentCheck: public ParameterizedNode< ACLData > { public: - int match(ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif diff --git a/src/acl/HierCode.cc b/src/acl/HierCode.cc index 3a74e62855..2bfca1d773 100644 --- a/src/acl/HierCode.cc +++ b/src/acl/HierCode.cc @@ -7,19 +7,15 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/HierCode.h" -#include "acl/HierCodeData.h" -#include "acl/Strategised.h" #include "HttpRequest.h" -/* explicit template instantiation required for some systems */ - -template class ACLStrategised; - int -ACLHierCodeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::HierCodeCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match (checklist->request->hier.code); } diff --git a/src/acl/HierCode.h b/src/acl/HierCode.h index 821df248df..24bf04f12b 100644 --- a/src/acl/HierCode.h +++ b/src/acl/HierCode.h @@ -9,17 +9,23 @@ #ifndef SQUID_ACLHIERCODE_H #define SQUID_ACLHIERCODE_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "hier_code.h" -/// \ingroup ACLAPI -class ACLHierCodeStrategy : public ACLStrategy +namespace Acl { +/// a "hier_code" ACL +class HierCodeCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + #endif /* SQUID_ACLHIERCODE_H */ diff --git a/src/acl/HttpRepHeader.cc b/src/acl/HttpRepHeader.cc index 819a0e7f69..afa7a52c3f 100644 --- a/src/acl/HttpRepHeader.cc +++ b/src/acl/HttpRepHeader.cc @@ -13,8 +13,10 @@ #include "HttpReply.h" int -ACLHTTPRepHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::HttpRepHeaderCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match (&checklist->reply->header); } diff --git a/src/acl/HttpRepHeader.h b/src/acl/HttpRepHeader.h index 3e17d6d444..e1f43610c7 100644 --- a/src/acl/HttpRepHeader.h +++ b/src/acl/HttpRepHeader.h @@ -9,18 +9,23 @@ #ifndef SQUID_ACLHTTPREPHEADER_H #define SQUID_ACLHTTPREPHEADER_H -#include "acl/Strategised.h" -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "HttpHeader.h" -/// \ingroup ACLAPI -class ACLHTTPRepHeaderStrategy : public ACLStrategy +namespace Acl { +/// a "rep_header" ACL +class HttpRepHeaderCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresReply() const override { return true; } }; +} // namespace Acl + #endif /* SQUID_ACLHTTPREPHEADER_H */ diff --git a/src/acl/HttpReqHeader.cc b/src/acl/HttpReqHeader.cc index 58911aecd8..1d8bf42a7f 100644 --- a/src/acl/HttpReqHeader.cc +++ b/src/acl/HttpReqHeader.cc @@ -13,8 +13,10 @@ #include "HttpRequest.h" int -ACLHTTPReqHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::HttpReqHeaderCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match (&checklist->request->header); } diff --git a/src/acl/HttpReqHeader.h b/src/acl/HttpReqHeader.h index 30d0b4aa56..0e1e78b6e8 100644 --- a/src/acl/HttpReqHeader.h +++ b/src/acl/HttpReqHeader.h @@ -9,17 +9,23 @@ #ifndef SQUID_ACLHTTPREQHEADER_H #define SQUID_ACLHTTPREQHEADER_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "HttpHeader.h" -/// \ingroup ACLAPI -class ACLHTTPReqHeaderStrategy : public ACLStrategy +namespace Acl { +/// a "req_header" ACL +class HttpReqHeaderCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override { return true; } }; +} // namespace Acl + #endif /* SQUID_ACLHTTPREQHEADER_H */ diff --git a/src/acl/LocalPort.cc b/src/acl/LocalPort.cc index 2cf48dc205..d018c68f12 100644 --- a/src/acl/LocalPort.cc +++ b/src/acl/LocalPort.cc @@ -11,8 +11,10 @@ #include "acl/LocalPort.h" int -ACLLocalPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::LocalPortCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match (checklist->my_addr.port()); } diff --git a/src/acl/LocalPort.h b/src/acl/LocalPort.h index 9e1a82202e..1ca6f5d58b 100644 --- a/src/acl/LocalPort.h +++ b/src/acl/LocalPort.h @@ -9,15 +9,21 @@ #ifndef SQUID_ACLLOCALPORT_H #define SQUID_ACLLOCALPORT_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" -/// \ingroup ACLAPI -class ACLLocalPortStrategy : public ACLStrategy +namespace Acl { +/// a "localport" ACL +class LocalPortCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLLOCALPORT_H */ diff --git a/src/acl/Makefile.am b/src/acl/Makefile.am index 4043044f7b..a2904d664a 100644 --- a/src/acl/Makefile.am +++ b/src/acl/Makefile.am @@ -38,9 +38,7 @@ libstate_la_SOURCES = \ Data.h \ FilledChecklist.cc \ FilledChecklist.h \ - Strategised.cc \ - Strategised.h \ - Strategy.h + ParameterizedNode.h ## data-specific ACLs libacls_la_SOURCES = \ diff --git a/src/acl/Method.cc b/src/acl/Method.cc index f1de157694..0087072fc5 100644 --- a/src/acl/Method.cc +++ b/src/acl/Method.cc @@ -9,17 +9,13 @@ #include "squid.h" #include "acl/FilledChecklist.h" #include "acl/Method.h" -#include "acl/MethodData.h" -#include "acl/Strategised.h" #include "HttpRequest.h" -/* explicit template instantiation required for some systems */ - -template class ACLStrategised; - int -ACLMethodStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::MethodCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match (checklist->request->method); } diff --git a/src/acl/Method.h b/src/acl/Method.h index 9c5c4d833b..96231db574 100644 --- a/src/acl/Method.h +++ b/src/acl/Method.h @@ -9,17 +9,23 @@ #ifndef SQUID_ACLMETHOD_H #define SQUID_ACLMETHOD_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "http/RequestMethod.h" -/// \ingroup ACLAPI -class ACLMethodStrategy : public ACLStrategy +namespace Acl { +/// a "method" ACL +class MethodCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + #endif /* SQUID_ACLMETHOD_H */ diff --git a/src/acl/MyPortName.cc b/src/acl/MyPortName.cc index 0583b3aaac..ac60431eb3 100644 --- a/src/acl/MyPortName.cc +++ b/src/acl/MyPortName.cc @@ -9,15 +9,16 @@ #include "squid.h" #include "acl/FilledChecklist.h" #include "acl/MyPortName.h" -#include "acl/StringData.h" #include "anyp/PortCfg.h" #include "client_side.h" #include "http/Stream.h" #include "HttpRequest.h" int -ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::MyPortNameCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (checklist->conn() != nullptr && checklist->conn()->port != nullptr) return data->match(checklist->conn()->port->name); if (checklist->request != nullptr) diff --git a/src/acl/MyPortName.h b/src/acl/MyPortName.h index fbb630a61d..62a57f762b 100644 --- a/src/acl/MyPortName.h +++ b/src/acl/MyPortName.h @@ -8,14 +8,22 @@ #ifndef SQUID_ACLMYPORTNAME_H #define SQUID_ACLMYPORTNAME_H -#include "acl/Strategy.h" -class ACLMyPortNameStrategy : public ACLStrategy +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" + +namespace Acl { +/// a "myportname" ACL +class MyPortNameCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLMYPORTNAME_H */ diff --git a/src/acl/Note.cc b/src/acl/Note.cc index 3f6d3d041d..5b462958eb 100644 --- a/src/acl/Note.cc +++ b/src/acl/Note.cc @@ -13,10 +13,10 @@ #include "acl/NoteData.h" #include "HttpRequest.h" -/* Acl::AnnotationStrategy */ +/* Acl::AnnotationCheck */ const Acl::Options & -Acl::AnnotationStrategy::options() +Acl::AnnotationCheck::options() { static const Acl::CharacterSetOption Delimiters("-m"); static const Acl::Options MyOptions = { &Delimiters }; @@ -24,17 +24,19 @@ Acl::AnnotationStrategy::options() return MyOptions; } -/* ACLNoteStrategy */ +/* Acl::NoteCheck */ int -ACLNoteStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::NoteCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (const auto request = checklist->request) { - if (request->hasNotes() && matchNotes(data, request->notes().getRaw())) + if (request->hasNotes() && matchNotes(request->notes().getRaw())) return 1; #if USE_ADAPTATION const Adaptation::History::Pointer ah = request->adaptLogHistory(); - if (ah != nullptr && ah->metaHeaders != nullptr && matchNotes(data, ah->metaHeaders.getRaw())) + if (ah != nullptr && ah->metaHeaders != nullptr && matchNotes(ah->metaHeaders.getRaw())) return 1; #endif } @@ -42,11 +44,11 @@ ACLNoteStrategy::match(ACLData * &data, ACLFilledChecklist *checklist } bool -ACLNoteStrategy::matchNotes(ACLData *noteData, const NotePairs *note) const +Acl::NoteCheck::matchNotes(const NotePairs *note) const { const NotePairs::Entries &entries = note->expandListEntries(&delimiters.value); for (auto e: entries) - if (noteData->match(e.getRaw())) + if (data->match(e.getRaw())) return true; return false; } diff --git a/src/acl/Note.h b/src/acl/Note.h index 1024d032ac..0cf32a0512 100644 --- a/src/acl/Note.h +++ b/src/acl/Note.h @@ -11,35 +11,35 @@ #include "acl/CharacterSetOption.h" #include "acl/Data.h" -#include "acl/Strategy.h" +#include "acl/ParameterizedNode.h" #include "Notes.h" namespace Acl { /// common parent of several ACLs dealing with transaction annotations -class AnnotationStrategy: public ACLStrategy +class AnnotationCheck: public ParameterizedNode< ACLData > { public: - AnnotationStrategy(): delimiters(CharacterSet(__FILE__, ",")) {} + AnnotationCheck(): delimiters(CharacterSet(__FILE__, ",")) {} const Acl::Options &options() override; Acl::CharacterSetOptionValue delimiters; ///< annotation separators }; -} // namespace Acl - -/// \ingroup ACLAPI -class ACLNoteStrategy: public Acl::AnnotationStrategy +/// a "note" ACL +class NoteCheck: public Acl::AnnotationCheck { - public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override { return true; } private: - bool matchNotes(ACLData *, const NotePairs *) const; + bool matchNotes(const NotePairs *) const; }; +} // namespace Acl + #endif /* SQUID_ACLNOTE_H */ diff --git a/src/acl/ParameterizedNode.h b/src/acl/ParameterizedNode.h new file mode 100644 index 0000000000..a36c75129e --- /dev/null +++ b/src/acl/ParameterizedNode.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 1996-2023 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. + */ + +#ifndef SQUID_SRC_ACL_PARAMETERIZEDNODE_H +#define SQUID_SRC_ACL_PARAMETERIZEDNODE_H + +#include "acl/Acl.h" +#include "base/Assure.h" + +#include + +namespace Acl +{ + +/// An ACL that manages squid.conf-configured ACL parameters using a given class +/// P. That P class must support the ACLData<> or equivalent API. +template +class ParameterizedNode: public ACL +{ +public: + using Parameters = P; + + // to avoid dragging constructor parameters through each derived class, they + // are set in a leaf class constructor; \sa Acl::FinalizedParameterizedNode + ParameterizedNode() = default; + ~ParameterizedNode() override = default; + +protected: + /* ACL API */ + void parse() override { Assure(data); data->parse(); } + void prepareForUse() override { data->prepareForUse(); } + SBufList dump() const override { return data->dump(); } + bool empty() const override { return data->empty(); } + const Acl::Options &lineOptions() override { return data->lineOptions(); } + + /// Points to items this ACL is configured to match. A derived class ensures + /// that this pointer is never nil after the ACL object construction ends. + std::unique_ptr data; +}; + +} // namespace Acl + +#endif /* SQUID_SRC_ACL_PARAMETERIZEDNODE_H */ + diff --git a/src/acl/PeerName.cc b/src/acl/PeerName.cc index 0ebb728dca..42cba8530f 100644 --- a/src/acl/PeerName.cc +++ b/src/acl/PeerName.cc @@ -9,12 +9,12 @@ #include "squid.h" #include "acl/FilledChecklist.h" #include "acl/PeerName.h" -#include "acl/RegexData.h" -#include "acl/StringData.h" int -ACLPeerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::PeerNameCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (!checklist->dst_peer_name.isEmpty()) return data->match(checklist->dst_peer_name.c_str()); return 0; diff --git a/src/acl/PeerName.h b/src/acl/PeerName.h index ed0246d9de..d65e294c8e 100644 --- a/src/acl/PeerName.h +++ b/src/acl/PeerName.h @@ -9,14 +9,21 @@ #ifndef SQUID_ACLPEERNAME_H #define SQUID_ACLPEERNAME_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" -class ACLPeerNameStrategy : public ACLStrategy +namespace Acl { +/// a "peername" or "peername_regex" ACL +class PeerNameCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLPEERNAME_H */ diff --git a/src/acl/Protocol.cc b/src/acl/Protocol.cc index d53ff93b93..e7c92c5e05 100644 --- a/src/acl/Protocol.cc +++ b/src/acl/Protocol.cc @@ -9,17 +9,13 @@ #include "squid.h" #include "acl/FilledChecklist.h" #include "acl/Protocol.h" -#include "acl/ProtocolData.h" -#include "acl/Strategised.h" #include "HttpRequest.h" -/* explicit template instantiation required for some systems */ - -template class ACLStrategised; - int -ACLProtocolStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::ProtocolCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match(checklist->request->url.getScheme()); } diff --git a/src/acl/Protocol.h b/src/acl/Protocol.h index a7ef518ca8..2517cdc6e1 100644 --- a/src/acl/Protocol.h +++ b/src/acl/Protocol.h @@ -9,16 +9,23 @@ #ifndef SQUID_ACLPROTOCOL_H #define SQUID_ACLPROTOCOL_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "anyp/ProtocolType.h" -class ACLProtocolStrategy : public ACLStrategy +namespace Acl { +/// a "proto" ACL +class ProtocolCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + #endif /* SQUID_ACLPROTOCOL_H */ diff --git a/src/acl/ReplyHeaderStrategy.h b/src/acl/ReplyHeaderStrategy.h index 26005ae6b0..da0b202572 100644 --- a/src/acl/ReplyHeaderStrategy.h +++ b/src/acl/ReplyHeaderStrategy.h @@ -9,25 +9,33 @@ #ifndef SQUID_ACLREPLYHEADERSTRATEGY_H #define SQUID_ACLREPLYHEADERSTRATEGY_H -#include "acl/Acl.h" #include "acl/Data.h" #include "acl/FilledChecklist.h" -#include "acl/Strategy.h" +#include "acl/ParameterizedNode.h" +#include "acl/ReplyHeaderStrategy.h" #include "HttpReply.h" -template -class ACLReplyHeaderStrategy : public ACLStrategy +namespace Acl { +/// matches the value of a given reply header (e.g., "rep_mime_type" ACL) +template +class ReplyHeaderCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresReply() const override {return true;} }; +} // namespace Acl + template int -ACLReplyHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::ReplyHeaderCheck
::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + char const *theHeader = checklist->reply->header.getStr(header); if (nullptr == theHeader) diff --git a/src/acl/ReplyMimeType.h b/src/acl/ReplyMimeType.h index 2af7cb2371..1a7750cc5a 100644 --- a/src/acl/ReplyMimeType.h +++ b/src/acl/ReplyMimeType.h @@ -17,8 +17,10 @@ template <> inline int -ACLReplyHeaderStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::ReplyHeaderCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + char const *theHeader = checklist->reply->header.getStr(Http::HdrType::CONTENT_TYPE); if (nullptr == theHeader) diff --git a/src/acl/RequestHeaderStrategy.h b/src/acl/RequestHeaderStrategy.h index dc04068215..44c20b8b07 100644 --- a/src/acl/RequestHeaderStrategy.h +++ b/src/acl/RequestHeaderStrategy.h @@ -8,25 +8,33 @@ #ifndef SQUID_ACLREQUESTHEADERSTRATEGY_H #define SQUID_ACLREQUESTHEADERSTRATEGY_H -#include "acl/Acl.h" + #include "acl/Data.h" #include "acl/FilledChecklist.h" -#include "acl/Strategy.h" +#include "acl/ParameterizedNode.h" #include "HttpRequest.h" -template -class ACLRequestHeaderStrategy : public ACLStrategy +namespace Acl { +/// matches the value of a given request header (e.g., "browser" or "referer_regex") +template +class RequestHeaderCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + template int -ACLRequestHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::RequestHeaderCheck
::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + char const *theHeader = checklist->request->header.getStr(header); if (nullptr == theHeader) diff --git a/src/acl/RequestMimeType.h b/src/acl/RequestMimeType.h index 3927cd7eb9..67c8e52792 100644 --- a/src/acl/RequestMimeType.h +++ b/src/acl/RequestMimeType.h @@ -17,8 +17,10 @@ template <> inline int -ACLRequestHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::RequestHeaderCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + char const *theHeader = checklist->request->header.getStr(Http::HdrType::CONTENT_TYPE); if (nullptr == theHeader) diff --git a/src/acl/ServerCertificate.cc b/src/acl/ServerCertificate.cc index 873eec775c..a7d2c286af 100644 --- a/src/acl/ServerCertificate.cc +++ b/src/acl/ServerCertificate.cc @@ -10,8 +10,7 @@ #if USE_OPENSSL -#include "acl/CertificateData.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/ServerCertificate.h" #include "client_side.h" #include "fde.h" @@ -19,8 +18,10 @@ #include "ssl/ServerBump.h" int -ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::ServerCertificateCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + Security::CertPointer cert; if (checklist->serverCert) cert = checklist->serverCert; diff --git a/src/acl/ServerCertificate.h b/src/acl/ServerCertificate.h index 8315c81a1c..a25d641d62 100644 --- a/src/acl/ServerCertificate.h +++ b/src/acl/ServerCertificate.h @@ -9,18 +9,22 @@ #ifndef SQUID_ACLSERVERCERTIFICATE_H #define SQUID_ACLSERVERCERTIFICATE_H -#include "acl/Acl.h" -#include "acl/Checklist.h" #include "acl/Data.h" -#include "acl/Strategised.h" +#include "acl/ParameterizedNode.h" #include "ssl/support.h" -/// \ingroup ACLAPI -class ACLServerCertificateStrategy : public ACLStrategy +namespace Acl +{ + +/// a "server_cert_fingerprint" ACL +class ServerCertificateCheck: public ParameterizedNode< ACLData > { public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLSERVERCERTIFICATE_H */ diff --git a/src/acl/ServerName.cc b/src/acl/ServerName.cc index fe356923e9..f48629dddc 100644 --- a/src/acl/ServerName.cc +++ b/src/acl/ServerName.cc @@ -9,16 +9,11 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/DomainData.h" #include "acl/FilledChecklist.h" -#include "acl/RegexData.h" #include "acl/ServerName.h" #include "client_side.h" -#include "fde.h" #include "http/Stream.h" #include "HttpRequest.h" -#include "ipcache.h" -#include "SquidString.h" #include "ssl/bio.h" #include "ssl/ServerBump.h" #include "ssl/support.h" @@ -78,8 +73,10 @@ check_cert_domain( void *check_data, ASN1_STRING *cn_data) } int -ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::ServerNameCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + assert(checklist != nullptr && checklist->request != nullptr); const char *serverName = nullptr; @@ -104,7 +101,7 @@ ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *ch serverName = clientRequestedServerName; else { // either no options or useServerProvided if (X509 *peer_cert = (conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr)) - return Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain); + return Ssl::matchX509CommonNames(peer_cert, data.get(), check_cert_domain); if (!useServerProvided) serverName = clientRequestedServerName; } @@ -117,7 +114,7 @@ ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *ch } const Acl::Options & -ACLServerNameStrategy::options() +Acl::ServerNameCheck::options() { static const Acl::BooleanOption ClientRequested("--client-requested"); static const Acl::BooleanOption ServerProvided("--server-provided"); @@ -130,7 +127,7 @@ ACLServerNameStrategy::options() } bool -ACLServerNameStrategy::valid() const +Acl::ServerNameCheck::valid() const { int optionCount = 0; diff --git a/src/acl/ServerName.h b/src/acl/ServerName.h index a797c1c22d..a804b2fbea 100644 --- a/src/acl/ServerName.h +++ b/src/acl/ServerName.h @@ -9,9 +9,8 @@ #ifndef SQUID_ACLSERVERNAME_H #define SQUID_ACLSERVERNAME_H -#include "acl/Acl.h" #include "acl/DomainData.h" -#include "acl/Strategy.h" +#include "acl/ParameterizedNode.h" class ACLServerNameData : public ACLDomainData { MEMPROXY_CLASS(ACLServerNameData); @@ -20,12 +19,15 @@ public: bool match(const char *) override; }; -class ACLServerNameStrategy : public ACLStrategy +namespace Acl { +/// an "ssl::server_name" or "ssl::server_name_regex" ACL +class ServerNameCheck: public ParameterizedNode< ACLData > +{ public: - /* ACLStrategy API */ - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} const Acl::Options &options() override; bool valid() const override; @@ -36,5 +38,7 @@ private: Acl::BooleanOptionValue useConsensus; ///< Ignore mismatching names }; +} // namespace Acl + #endif /* SQUID_ACLSERVERNAME_H */ diff --git a/src/acl/SourceAsn.h b/src/acl/SourceAsn.h index 416115357c..70029b7203 100644 --- a/src/acl/SourceAsn.h +++ b/src/acl/SourceAsn.h @@ -9,17 +9,22 @@ #ifndef SQUID_ACL_SOURCEASN_H #define SQUID_ACL_SOURCEASN_H -#include "acl/Strategy.h" -#include "ip/Address.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" +#include "ip/forward.h" -class ACLChecklist; - -class ACLSourceASNStrategy : public ACLStrategy +namespace Acl { +/// a "src_as" ACL +class SourceAsnCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACL_SOURCEASN_H */ diff --git a/src/acl/SourceDomain.cc b/src/acl/SourceDomain.cc index d9670525f5..ea892b3eac 100644 --- a/src/acl/SourceDomain.cc +++ b/src/acl/SourceDomain.cc @@ -41,8 +41,10 @@ SourceDomainLookup::LookupDone(const char *, const Dns::LookupDetails &details, } int -ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::SourceDomainCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + const char *fqdn = nullptr; fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); diff --git a/src/acl/SourceDomain.h b/src/acl/SourceDomain.h index 99cac9ea60..2a32792364 100644 --- a/src/acl/SourceDomain.h +++ b/src/acl/SourceDomain.h @@ -8,19 +8,24 @@ #ifndef SQUID_ACLSOURCEDOMAIN_H #define SQUID_ACLSOURCEDOMAIN_H -#include "acl/Acl.h" -#include "acl/Checklist.h" + #include "acl/Data.h" -#include "acl/Strategy.h" +#include "acl/ParameterizedNode.h" #include "dns/forward.h" -class ACLSourceDomainStrategy : public ACLStrategy +namespace Acl { +/// a "srcdomain" or "srcdom_regex" ACL +class SourceDomainCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + class SourceDomainLookup : public ACLChecklist::AsyncState { diff --git a/src/acl/SquidError.cc b/src/acl/SquidError.cc index efbfd8d091..5540abd8fd 100644 --- a/src/acl/SquidError.cc +++ b/src/acl/SquidError.cc @@ -12,8 +12,10 @@ #include "HttpRequest.h" int -ACLSquidErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::SquidErrorCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (checklist->requestErrorType != ERR_MAX) return data->match(checklist->requestErrorType); else if (checklist->request) diff --git a/src/acl/SquidError.h b/src/acl/SquidError.h index 5d31126b79..b9185b6d23 100644 --- a/src/acl/SquidError.h +++ b/src/acl/SquidError.h @@ -9,15 +9,22 @@ #ifndef SQUID_ACLSQUIDERROR_H #define SQUID_ACLSQUIDERROR_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "error/forward.h" -class ACLSquidErrorStrategy : public ACLStrategy +namespace Acl { +/// a "squid_error" ACL +class SquidErrorCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLSQUIDERROR_H */ diff --git a/src/acl/SslError.cc b/src/acl/SslError.cc index 4bea9f7349..0513aac126 100644 --- a/src/acl/SslError.cc +++ b/src/acl/SslError.cc @@ -9,11 +9,12 @@ #include "squid.h" #include "acl/FilledChecklist.h" #include "acl/SslError.h" -#include "acl/SslErrorData.h" int -ACLSslErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::CertificateErrorCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match(checklist->sslErrors.get()); } diff --git a/src/acl/SslError.h b/src/acl/SslError.h index 4bc8a187f2..c1747e27cd 100644 --- a/src/acl/SslError.h +++ b/src/acl/SslError.h @@ -9,15 +9,22 @@ #ifndef SQUID_ACLSSL_ERROR_H #define SQUID_ACLSSL_ERROR_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "security/forward.h" -class ACLSslErrorStrategy : public ACLStrategy +namespace Acl { +/// an "ssl_error" ACL +class CertificateErrorCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLSSL_ERROR_H */ diff --git a/src/acl/Strategised.cc b/src/acl/Strategised.cc deleted file mode 100644 index 52b942a638..0000000000 --- a/src/acl/Strategised.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 1996-2023 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. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Strategised.h" -#include "HttpHeader.h" - -/* - * moved template instantiation into ACLStrategized.cc - * to compile on Mac OSX 10.5 Leopard. - * This corrects a duplicate symbol error - */ - -/* explicit template instantiation required for some systems */ - -/* XXX: move to ACLHTTPRepHeader or ACLHTTPReqHeader */ -template class ACLStrategised; - -/* ACLMyPortName + ACLMyPeerName + ACLBrowser */ -template class ACLStrategised; - -/* ACLLocalPort + ACLSslError */ -template class ACLStrategised; - diff --git a/src/acl/Strategised.h b/src/acl/Strategised.h deleted file mode 100644 index 46650d755d..0000000000 --- a/src/acl/Strategised.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 1996-2023 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. - */ - -#ifndef SQUID_ACLSTRATEGISED_H -#define SQUID_ACLSTRATEGISED_H - -#include "acl/Acl.h" -#include "acl/Data.h" -#include "acl/FilledChecklist.h" -#include "acl/Strategy.h" - -// XXX: Replace with a much simpler abstract ACL child class without the -// ACLStrategy parameter (and associated call forwarding). Duplicating key -// portions of the ACL class API in ACLStrategy is not needed because -// ACLStrategy is unused outside the ACLStrategised context. Existing classes -// like ACLExtUser, ACLProxyAuth, and ACLIdent seem to confirm this assertion. -// It also requires forwarding ACL info to ACLStrategy as method parameters. - -/// Splits the ACL API into two individually configurable components: -/// * ACLStrategy that usually extracts information from the current transaction -/// * ACLData that usually matches information against admin-configured values -template -class ACLStrategised : public ACL -{ - MEMPROXY_CLASS(ACLStrategised); - -public: - typedef M MatchType; - - ~ACLStrategised() override; - ACLStrategised(ACLData *, ACLStrategy *, char const *); - - char const *typeString() const override; - - bool requiresRequest() const override {return matcher->requiresRequest();} - - bool requiresReply() const override {return matcher->requiresReply();} - - void prepareForUse() override { data->prepareForUse();} - void parse() override; - int match(ACLChecklist *checklist) override; - virtual int match (M const &); - SBufList dump() const override; - bool empty () const override; - bool valid () const override; - -private: - /* ACL API */ - const Acl::Options &options() override { return matcher->options(); } - const Acl::Options &lineOptions() override { return data->lineOptions(); } - - ACLData *data; - char const *type_; - ACLStrategy *matcher; -}; - -/* implementation follows */ - -template -ACLStrategised::~ACLStrategised() -{ - delete data; - delete matcher; -} - -template -ACLStrategised::ACLStrategised(ACLData *newData, ACLStrategy *theStrategy, char const *theType): data(newData), type_(theType), matcher(theStrategy) -{} - -template -char const * -ACLStrategised::typeString() const -{ - return type_; -} - -template -void -ACLStrategised::parse() -{ - data->parse(); -} - -template -bool -ACLStrategised::empty() const -{ - return data->empty(); -} - -template -int -ACLStrategised::match(ACLChecklist *cl) -{ - ACLFilledChecklist *checklist = dynamic_cast(cl); - assert(checklist); - return matcher->match(data, checklist); -} - -template -int -ACLStrategised::match(MatchType const &toFind) -{ - return data->match(toFind); -} - -template -SBufList -ACLStrategised::dump() const -{ - return data->dump(); -} - -template -bool -ACLStrategised::valid () const -{ - return matcher->valid(); -} - -#endif /* SQUID_ACLSTRATEGISED_H */ - diff --git a/src/acl/Strategy.h b/src/acl/Strategy.h deleted file mode 100644 index a3712bcee9..0000000000 --- a/src/acl/Strategy.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 1996-2023 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. - */ - -#ifndef SQUID_ACLSTRATEGY_H -#define SQUID_ACLSTRATEGY_H - -#include "acl/Acl.h" -#include "acl/Data.h" -#include "acl/Options.h" - -class ACLFilledChecklist; - -template - -/// A matching algorithm. -class ACLStrategy -{ - -public: - typedef M MatchType; - - /* Replicate ACL API parts relevant to the matching algorithm. */ - virtual const Acl::Options &options() { return Acl::NoOptions(); } - virtual int match (ACLData * &, ACLFilledChecklist *) = 0; - virtual bool requiresRequest() const {return false;} - - virtual bool requiresReply() const {return false;} - - virtual bool valid() const {return true;} - - virtual ~ACLStrategy() {} -}; - -#endif /* SQUID_ACLSTRATEGY_H */ - diff --git a/src/acl/Tag.cc b/src/acl/Tag.cc index e7376e883f..6f7a90c76a 100644 --- a/src/acl/Tag.cc +++ b/src/acl/Tag.cc @@ -8,13 +8,14 @@ #include "squid.h" #include "acl/FilledChecklist.h" -#include "acl/StringData.h" #include "acl/Tag.h" #include "HttpRequest.h" int -ACLTagStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::TagCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (checklist->request != nullptr) return data->match (checklist->request->tag.termedBuf()); return 0; diff --git a/src/acl/Tag.h b/src/acl/Tag.h index 528eaad297..3541b96dd6 100644 --- a/src/acl/Tag.h +++ b/src/acl/Tag.h @@ -9,14 +9,21 @@ #ifndef SQUID_ACLTAG_H #define SQUID_ACLTAG_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" -class ACLTagStrategy : public ACLStrategy +namespace Acl { +/// a "tag" ACL +class TagCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLMYPORTNAME_H */ diff --git a/src/acl/Time.cc b/src/acl/Time.cc index 7dca02be6a..a5ca873acc 100644 --- a/src/acl/Time.cc +++ b/src/acl/Time.cc @@ -10,10 +10,10 @@ #include "squid.h" #include "acl/Time.h" -#include "acl/TimeData.h" +#include "time/gadgets.h" int -ACLTimeStrategy::match(ACLData * &data, ACLFilledChecklist *) +Acl::CurrentTimeCheck::match(ACLChecklist *) { return data->match(squid_curtime); } diff --git a/src/acl/Time.h b/src/acl/Time.h index 9a44fd4a47..30d1f5a9f5 100644 --- a/src/acl/Time.h +++ b/src/acl/Time.h @@ -8,15 +8,23 @@ #ifndef SQUID_ACLTIME_H #define SQUID_ACLTIME_H -#include "acl/Data.h" -#include "acl/Strategised.h" -class ACLTimeStrategy : public ACLStrategy +#include "acl/ParameterizedNode.h" +#include "acl/TimeData.h" +#include "mem/AllocatorProxy.h" + +namespace Acl { +/// a "time" ACL +class CurrentTimeCheck: public ParameterizedNode +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_ACLTIME_H */ diff --git a/src/acl/Url.cc b/src/acl/Url.cc index 143afc5c0c..6e9e91a754 100644 --- a/src/acl/Url.cc +++ b/src/acl/Url.cc @@ -10,14 +10,15 @@ #include "squid.h" #include "acl/FilledChecklist.h" -#include "acl/RegexData.h" #include "acl/Url.h" #include "HttpRequest.h" #include "rfc1738.h" int -ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::UrlCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + char *esc_buf = SBufToCstring(checklist->request->effectiveRequestUri()); rfc1738_unescape(esc_buf); int result = data->match(esc_buf); diff --git a/src/acl/Url.h b/src/acl/Url.h index d705f64af2..20d81b5137 100644 --- a/src/acl/Url.h +++ b/src/acl/Url.h @@ -10,15 +10,21 @@ #define SQUID_ACLURL_H #include "acl/Data.h" -#include "acl/Strategised.h" +#include "acl/ParameterizedNode.h" -class ACLUrlStrategy : public ACLStrategy +namespace Acl { +/// a "url_regex" ACL +class UrlCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + #endif /* SQUID_ACLURL_H */ diff --git a/src/acl/UrlLogin.cc b/src/acl/UrlLogin.cc index 598ceb2644..f56031bac3 100644 --- a/src/acl/UrlLogin.cc +++ b/src/acl/UrlLogin.cc @@ -10,14 +10,15 @@ #include "squid.h" #include "acl/FilledChecklist.h" -#include "acl/RegexData.h" #include "acl/UrlLogin.h" #include "HttpRequest.h" #include "rfc1738.h" int -ACLUrlLoginStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::UrlLoginCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (checklist->request->url.userInfo().isEmpty()) { debugs(28, 5, "URL has no user-info details. cannot match"); return 0; // nothing can match diff --git a/src/acl/UrlLogin.h b/src/acl/UrlLogin.h index e32ac064cb..7c579e9c71 100644 --- a/src/acl/UrlLogin.h +++ b/src/acl/UrlLogin.h @@ -9,17 +9,22 @@ #ifndef SQUID_ACLURLLOGIN_H #define SQUID_ACLURLLOGIN_H -#include "acl/Acl.h" #include "acl/Data.h" -#include "acl/Strategy.h" +#include "acl/ParameterizedNode.h" -class ACLUrlLoginStrategy : public ACLStrategy +namespace Acl { +/// a "urllogin" ACL +class UrlLoginCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + #endif /* SQUID_ACLURLLOGIN_H */ diff --git a/src/acl/UrlPath.cc b/src/acl/UrlPath.cc index 0467299c9a..714937f5a0 100644 --- a/src/acl/UrlPath.cc +++ b/src/acl/UrlPath.cc @@ -10,14 +10,15 @@ #include "squid.h" #include "acl/FilledChecklist.h" -#include "acl/RegexData.h" #include "acl/UrlPath.h" #include "HttpRequest.h" #include "rfc1738.h" int -ACLUrlPathStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::UrlPathCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + if (checklist->request->url.path().isEmpty()) return -1; diff --git a/src/acl/UrlPath.h b/src/acl/UrlPath.h index d86acfefbe..0ead4e6764 100644 --- a/src/acl/UrlPath.h +++ b/src/acl/UrlPath.h @@ -9,15 +9,22 @@ #ifndef SQUID_ACLURLPATH_H #define SQUID_ACLURLPATH_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" -class ACLUrlPathStrategy : public ACLStrategy +namespace Acl { +/// a "urlpath_regex" ACL +class UrlPathCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + #endif /* SQUID_ACLURLPATH_H */ diff --git a/src/acl/UrlPort.cc b/src/acl/UrlPort.cc index 2b01f5a8ec..bb81b769d3 100644 --- a/src/acl/UrlPort.cc +++ b/src/acl/UrlPort.cc @@ -12,8 +12,10 @@ #include "HttpRequest.h" int -ACLUrlPortStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) +Acl::UrlPortCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match(checklist->request->url.port().value_or(0)); } diff --git a/src/acl/UrlPort.h b/src/acl/UrlPort.h index 75d6f80025..83389bbbc0 100644 --- a/src/acl/UrlPort.h +++ b/src/acl/UrlPort.h @@ -9,15 +9,22 @@ #ifndef SQUID_ACLURLPORT_H #define SQUID_ACLURLPORT_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" -class ACLUrlPortStrategy : public ACLStrategy +namespace Acl { +/// a "port" ACL +class UrlPortCheck: public ParameterizedNode< ACLData > +{ public: - int match (ACLData * &, ACLFilledChecklist *) override; + /* ACL API */ + int match(ACLChecklist *) override; bool requiresRequest() const override {return true;} }; +} // namespace Acl + #endif /* SQUID_ACLURLPORT_H */ diff --git a/src/mem/Allocator.h b/src/mem/Allocator.h index a554881cc7..aa6b3eaaf9 100644 --- a/src/mem/Allocator.h +++ b/src/mem/Allocator.h @@ -29,6 +29,10 @@ public: objectSize(RoundedSize(sz)) {} + /// change the allocator description if we were only able to provide an + /// approximate description at object construction time + void relabel(const char * const aLabel) { label = aLabel; } + // TODO make this method const /** * fill the given object with statistical data about pool @@ -102,7 +106,7 @@ public: // XXX: no counter for the number of free() calls avoided /// brief description of objects returned by alloc() - const char *const label; + const char *label; /// the size (in bytes) of objects managed by this allocator const size_t objectSize; diff --git a/src/mem/AllocatorProxy.cc b/src/mem/AllocatorProxy.cc index 92de07b691..5ce7bd2cbd 100644 --- a/src/mem/AllocatorProxy.cc +++ b/src/mem/AllocatorProxy.cc @@ -52,6 +52,13 @@ Mem::AllocatorProxy::zeroBlocks(bool doIt) getAllocator()->zeroBlocks(doIt); } +void +Mem::AllocatorProxy::relabel(const char * const aLabel) +{ + getAllocator()->relabel(aLabel); + label = aLabel; +} + Mem::PoolMeter const & Mem::AllocatorProxy::getMeter() const { diff --git a/src/mem/AllocatorProxy.h b/src/mem/AllocatorProxy.h index 9c906ced30..c9cb8c5f03 100644 --- a/src/mem/AllocatorProxy.h +++ b/src/mem/AllocatorProxy.h @@ -82,6 +82,9 @@ public: void zeroBlocks(bool doIt); + /// \copydoc Mem::Allocator::relabel() + void relabel(const char * const aLabel); + private: Allocator *getAllocator() const; diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 4686842541..6538497990 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -1132,8 +1132,10 @@ oid2addr(oid * id, Ip::Address &addr, u_int size) } int -ACLSNMPCommunityStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) +Acl::SnmpCommunityCheck::match(ACLChecklist * const ch) { + const auto checklist = Filled(ch); + return data->match (checklist->snmp_community); } diff --git a/src/snmp_core.h b/src/snmp_core.h index dfc715db87..3f67c4fe1b 100644 --- a/src/snmp_core.h +++ b/src/snmp_core.h @@ -11,7 +11,8 @@ #ifndef SQUID_SNMP_CORE_H #define SQUID_SNMP_CORE_H -#include "acl/Strategy.h" +#include "acl/Data.h" +#include "acl/ParameterizedNode.h" #include "cache_snmp.h" #include "comm/forward.h" #include "ip/forward.h" @@ -52,11 +53,18 @@ const char * snmpDebugOid(oid * Name, snint Len, MemBuf &outbuf); void addr2oid(Ip::Address &addr, oid *Dest); void oid2addr(oid *Dest, Ip::Address &addr, u_int code); -class ACLSNMPCommunityStrategy: public ACLStrategy +namespace Acl +{ + +/// an "snmp_community" ACL +class SnmpCommunityCheck: public ParameterizedNode< ACLData > { public: - int match (ACLData *&data, ACLFilledChecklist *checklist) override; + /* ACL API */ + int match(ACLChecklist *) override; }; +} // namespace Acl + #endif /* SQUID_SNMP_CORE_H */ -- 2.47.2