diff --git a/src/acl/Checklist.h b/src/acl/Checklist.h index 664751a1fa9..9e2d70fe66a 100644 --- a/src/acl/Checklist.h +++ b/src/acl/Checklist.h @@ -39,28 +39,6 @@ class ACLChecklist ACLChecklist(); virtual ~ACLChecklist(); - /** - * Start a non-blocking (async) check for a list of allow/deny rules. - * Each rule comes with a list of ACLs. - * - * The callback specified will be called with the result of the check. - * - * The first rule where all ACLs match wins. If there is such a rule, - * the result becomes that rule keyword (ACCESS_ALLOWED or ACCESS_DENIED). - * - * If there are rules but all ACL lists mismatch, an implicit rule is used. - * Its result is the negation of the keyword of the last seen rule. - * - * Some ACLs may stop the check prematurely by setting an exceptional - * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a - * match or mismatch. - * - * If there are no rules to check at all, the result becomes ACCESS_DUNNO. - * Calling this method with no rules to check wastes a lot of CPU cycles - * and will result in a DBG_CRITICAL debugging message. - */ - void nonBlockingCheck(ACLCB * callback, void *callback_data); - /** * Perform a blocking (immediate) check for a list of allow/deny rules. * Each rule comes with a list of ACLs. @@ -149,6 +127,29 @@ class ACLChecklist /// remember the name of the last ACL being evaluated void setLastCheckedName(const SBuf &name) { lastCheckedName_ = name; } +protected: + /** + * Start a non-blocking (async) check for a list of allow/deny rules. + * Each rule comes with a list of ACLs. + * + * The callback specified will be called with the result of the check. + * + * The first rule where all ACLs match wins. If there is such a rule, + * the result becomes that rule keyword (ACCESS_ALLOWED or ACCESS_DENIED). + * + * If there are rules but all ACL lists mismatch, an implicit rule is used. + * Its result is the negation of the keyword of the last seen rule. + * + * Some ACLs may stop the check prematurely by setting an exceptional + * check result (e.g., ACCESS_AUTH_REQUIRED) instead of declaring a + * match or mismatch. + * + * If there are no rules to check at all, the result becomes ACCESS_DUNNO. + * Calling this method with no rules to check wastes a lot of CPU cycles + * and will result in a DBG_CRITICAL debugging message. + */ + void nonBlockingCheck(ACLCB * callback, void *callback_data); + private: /// Calls non-blocking check callback with the answer and destroys self. /// If abortReason is provided, sets the final answer to ACCESS_DUNNO. diff --git a/src/acl/FilledChecklist.cc b/src/acl/FilledChecklist.cc index e52c941cd62..4d8f932d777 100644 --- a/src/acl/FilledChecklist.cc +++ b/src/acl/FilledChecklist.cc @@ -186,16 +186,17 @@ ACLFilledChecklist::markSourceDomainChecked() /* * There are two common ACLFilledChecklist lifecycles paths: * - * A) Using aclCheckFast(): The caller creates an ACLFilledChecklist object - * on stack and calls aclCheckFast(). + * "Fast" (always synchronous or "blocking"): The user constructs an + * ACLFilledChecklist object on stack, configures it as needed, and calls one + * or both of its fastCheck() methods. * - * B) Using aclNBCheck() and callbacks: The caller allocates an - * ACLFilledChecklist object (via operator new) and passes it to - * aclNBCheck(). Control eventually passes to ACLChecklist::checkCallback(), - * which will invoke the callback function as requested by the - * original caller of aclNBCheck(). This callback function must - * *not* delete the list. After the callback function returns, - * checkCallback() will delete the list (i.e., self). + * "Slow" (usually asynchronous or "non-blocking"): The user allocates an + * ACLFilledChecklist object on heap (via Make()), configures it as needed, + * and passes it to NonBlockingCheck() while specifying the callback function + * to call with check results. NonBlockingCheck() calls the callback function + * (if the corresponding cbdata is still valid), either immediately/directly + * (XXX) or eventually/asynchronously. After this callback obligations are + * fulfilled, checkCallback() deletes the checklist object (i.e. "this"). */ ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_request): dst_rdns(nullptr), diff --git a/src/acl/FilledChecklist.h b/src/acl/FilledChecklist.h index 358792a2ec5..cf5fa954b29 100644 --- a/src/acl/FilledChecklist.h +++ b/src/acl/FilledChecklist.h @@ -32,13 +32,27 @@ class ConnStateData; */ class ACLFilledChecklist: public ACLChecklist { - CBDATA_CLASS(ACLFilledChecklist); + CBDATA_CLASS_WITH_MAKE(ACLFilledChecklist); public: + /// Unlike regular Foo::Pointer types, this smart pointer is meant for use + /// during checklist configuration only, when it provides exception safety. + /// Any other/long-term checklist storage requires CbcPointer or equivalent. + using MakingPointer = std::unique_ptr; + ACLFilledChecklist(); ACLFilledChecklist(const acl_access *, HttpRequest *); ~ACLFilledChecklist() override; + /// Creates an ACLFilledChecklist object with given constructor arguments. + /// Callers are expected to eventually proceed with NonBlockingCheck(). + static MakingPointer Make(const acl_access *a, HttpRequest *r) { return MakingPointer(new ACLFilledChecklist(a, r)); } + + /// \copydoc ACLChecklist::nonBlockingCheck() + /// This public nonBlockingCheck() wrapper should be paired with Make(). The + /// pair prevents exception-caused Checklist memory leaks in caller code. + static void NonBlockingCheck(MakingPointer &&p, ACLCB *cb, void *data) { p->nonBlockingCheck(cb, data); (void)p.release(); } + /// configure client request-related fields for the first time void setRequest(HttpRequest *); diff --git a/src/adaptation/AccessCheck.cc b/src/adaptation/AccessCheck.cc index 475ecf25881..301a9971dc1 100644 --- a/src/adaptation/AccessCheck.cc +++ b/src/adaptation/AccessCheck.cc @@ -128,11 +128,11 @@ Adaptation::AccessCheck::checkCandidates() while (!candidates.empty()) { if (AccessRule *r = FindRule(topCandidate())) { /* BUG 2526: what to do when r->acl is empty?? */ - const auto acl_checklist = new ACLFilledChecklist(r->acl, filter.request); + auto acl_checklist = ACLFilledChecklist::Make(r->acl, filter.request); acl_checklist->updateAle(filter.al); acl_checklist->updateReply(filter.reply); acl_checklist->syncAle(filter.request, nullptr); - acl_checklist->nonBlockingCheck(AccessCheckCallbackWrapper, this); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), AccessCheckCallbackWrapper, this); return; } diff --git a/src/cbdata.h b/src/cbdata.h index 7b67098826c..edeac4fe6f5 100644 --- a/src/cbdata.h +++ b/src/cbdata.h @@ -255,12 +255,12 @@ cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size) /// declaration-generator used internally by CBDATA_CLASS() and CBDATA_CHILD() #define CBDATA_DECL_(type, methodSpecifiers) \ - public: \ void *operator new(size_t size) { \ assert(size == sizeof(type)); \ if (!CBDATA_##type) CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type)); \ return (type *)cbdataInternalAlloc(CBDATA_##type); \ } \ + public: \ void operator delete (void *address) { \ if (address) cbdataInternalFree(address); \ } \ @@ -286,12 +286,17 @@ class CbdataParent /// cbdata-enables a stand-alone class that is not a CbdataParent child /// sets the class declaration section to "private" /// use this at the start of your class declaration for consistency sake -#define CBDATA_CLASS(type) CBDATA_DECL_(type, noexcept) +#define CBDATA_CLASS(type) public: CBDATA_DECL_(type, noexcept) + +/// A CBDATA_CLASS() variant for classes that want to prevent accidental +/// operator new() calls by making that operator private and forcing external +/// users to call a Make() function instead. +#define CBDATA_CLASS_WITH_MAKE(type) private: CBDATA_DECL_(type, noexcept) /// cbdata-enables a final CbdataParent-derived class in a hierarchy /// sets the class declaration section to "private" /// use this at the start of your class declaration for consistency sake -#define CBDATA_CHILD(type) CBDATA_DECL_(type, final) \ +#define CBDATA_CHILD(type) public: CBDATA_DECL_(type, final) \ void finalizedInCbdataChild() final {} /// cbdata-enables a non-final CbdataParent-derived class T in a hierarchy. diff --git a/src/client_side.cc b/src/client_side.cc index 2a977e34d7e..38cd088e17a 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -2484,7 +2484,7 @@ ConnStateData::postHttpsAccept() CodeContext::Reset(connectAle); // TODO: Use these request/ALE when waiting for new bumped transactions. - const auto acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, request); + auto acl_checklist = ACLFilledChecklist::Make(Config.accessList.ssl_bump, request); fillChecklist(*acl_checklist); // Build a local AccessLogEntry to allow requiresAle() acls work acl_checklist->al = connectAle; @@ -2501,7 +2501,7 @@ ConnStateData::postHttpsAccept() ClientHttpRequest *http = context ? context->http : nullptr; const char *log_uri = http ? http->log_uri : nullptr; acl_checklist->syncAle(request, log_uri); - acl_checklist->nonBlockingCheck(httpsSslBumpAccessCheckDone, this); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), httpsSslBumpAccessCheckDone, this); #else fatal("FATAL: SSL-Bump requires --with-openssl"); #endif @@ -2967,12 +2967,12 @@ ConnStateData::startPeekAndSplice() sslServerBump->step = XactionStep::tlsBump2; // Run a accessList check to check if want to splice or continue bumping - const auto acl_checklist = new ACLFilledChecklist(Config.accessList.ssl_bump, sslServerBump->request.getRaw()); + auto acl_checklist = ACLFilledChecklist::Make(Config.accessList.ssl_bump, sslServerBump->request.getRaw()); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpNone)); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpClientFirst)); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpServerFirst)); fillChecklist(*acl_checklist); - acl_checklist->nonBlockingCheck(httpsSslBumpStep2AccessCheckDone, this); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), httpsSslBumpStep2AccessCheckDone, this); return; } @@ -3111,7 +3111,7 @@ ConnStateData::initiateTunneledRequest(HttpRequest::Pointer const &cause, const // TLS handshakes on non-bumping https_port. TODO: Discover these // problems earlier so that they can be classified/detailed better. debugs(33, 2, "Not able to compute URL, abort request tunneling for " << reason); - // TODO: throw when nonBlockingCheck() callbacks gain job protections + // TODO: throw when NonBlockingCheck() callbacks gain job protections static const auto d = MakeNamedErrorDetail("TUNNEL_TARGET"); updateError(ERR_INVALID_REQ, d); return false; @@ -3448,10 +3448,10 @@ varyEvaluateMatch(StoreEntry * entry, HttpRequest * request) } } -ACLFilledChecklist * +ACLFilledChecklist::MakingPointer clientAclChecklistCreate(const acl_access * acl, ClientHttpRequest * http) { - const auto checklist = new ACLFilledChecklist(acl, nullptr); + auto checklist = ACLFilledChecklist::Make(acl, nullptr); clientAclChecklistFill(*checklist, http); return checklist; } diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 4754573dd26..3deab499dc8 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -1835,10 +1835,10 @@ clientReplyContext::processReplyAccess () } /** Process http_reply_access lists */ - ACLFilledChecklist *replyChecklist = + auto replyChecklist = clientAclChecklistCreate(Config.accessList.reply, http); replyChecklist->updateReply(reply); - replyChecklist->nonBlockingCheck(ProcessReplyAccessResult, this); + ACLFilledChecklist::NonBlockingCheck(std::move(replyChecklist), ProcessReplyAccessResult, this); } void diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 1d432a8f524..8062bd1c2d9 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -438,13 +438,13 @@ clientFollowXForwardedForCheck(Acl::Answer answer, void *data) if ((addr = asciiaddr)) { request->indirect_client_addr = addr; request->x_forwarded_for_iterator.cut(l); - const auto ch = clientAclChecklistCreate(Config.accessList.followXFF, http); + auto ch = 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 */ ch->src_addr = request->indirect_client_addr; } if (++calloutContext->currentXffHopNumber < SQUID_X_FORWARDED_FOR_HOP_MAX) { - ch->nonBlockingCheck(clientFollowXForwardedForCheck, data); + ACLFilledChecklist::NonBlockingCheck(std::move(ch), clientFollowXForwardedForCheck, data); return; } const auto headerName = Http::HeaderLookupTable.lookup(Http::HdrType::X_FORWARDED_FOR).name; @@ -666,15 +666,15 @@ ClientRequestContext::clientAccessCheck() http->request->x_forwarded_for_iterator = http->request->header.getList(Http::HdrType::X_FORWARDED_FOR); /* begin by checking to see if we trust direct client enough to walk XFF */ - const auto acl_checklist = clientAclChecklistCreate(Config.accessList.followXFF, http); - acl_checklist->nonBlockingCheck(clientFollowXForwardedForCheck, this); + auto acl_checklist = clientAclChecklistCreate(Config.accessList.followXFF, http); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), clientFollowXForwardedForCheck, this); return; } #endif if (Config.accessList.http) { - const auto acl_checklist = clientAclChecklistCreate(Config.accessList.http, http); - acl_checklist->nonBlockingCheck(clientAccessCheckDoneWrapper, this); + auto acl_checklist = clientAclChecklistCreate(Config.accessList.http, http); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), clientAccessCheckDoneWrapper, this); } else { debugs(0, DBG_CRITICAL, "No http_access configuration found. This will block ALL traffic"); clientAccessCheckDone(ACCESS_DENIED); @@ -690,8 +690,8 @@ void ClientRequestContext::clientAccessCheck2() { if (Config.accessList.adapted_http) { - const auto acl_checklist = clientAclChecklistCreate(Config.accessList.adapted_http, http); - acl_checklist->nonBlockingCheck(clientAccessCheckDoneWrapper, this); + auto acl_checklist = clientAclChecklistCreate(Config.accessList.adapted_http, http); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), clientAccessCheckDoneWrapper, this); } else { debugs(85, 2, "No adapted_http_access configuration. default: ALLOW"); clientAccessCheckDone(ACCESS_ALLOWED); @@ -835,8 +835,8 @@ ClientRequestContext::clientRedirectStart() debugs(33, 5, "'" << http->uri << "'"); http->al->syncNotes(http->request); if (Config.accessList.redirector) { - const auto acl_checklist = clientAclChecklistCreate(Config.accessList.redirector, http); - acl_checklist->nonBlockingCheck(clientRedirectAccessCheckDone, this); + auto acl_checklist = clientAclChecklistCreate(Config.accessList.redirector, http); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), clientRedirectAccessCheckDone, this); } else redirectStart(http, clientRedirectDoneWrapper, this); } @@ -871,8 +871,8 @@ ClientRequestContext::clientStoreIdStart() debugs(33, 5,"'" << http->uri << "'"); if (Config.accessList.store_id) { - const auto acl_checklist = clientAclChecklistCreate(Config.accessList.store_id, http); - acl_checklist->nonBlockingCheck(clientStoreIdAccessCheckDone, this); + auto acl_checklist = clientAclChecklistCreate(Config.accessList.store_id, http); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), clientStoreIdAccessCheckDone, this); } else storeIdStart(http, clientStoreIdDoneWrapper, this); } @@ -1310,8 +1310,8 @@ void ClientRequestContext::checkNoCache() { if (Config.accessList.noCache) { - const auto acl_checklist = clientAclChecklistCreate(Config.accessList.noCache, http); - acl_checklist->nonBlockingCheck(checkNoCacheDoneWrapper, this); + auto acl_checklist = clientAclChecklistCreate(Config.accessList.noCache, http); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), checkNoCacheDoneWrapper, this); } else { /* unless otherwise specified, we try to cache. */ checkNoCacheDone(ACCESS_ALLOWED); @@ -1405,8 +1405,8 @@ ClientRequestContext::sslBumpAccessCheck() debugs(85, 5, "SslBump possible, checking ACL"); - ACLFilledChecklist *aclChecklist = clientAclChecklistCreate(Config.accessList.ssl_bump, http); - aclChecklist->nonBlockingCheck(sslBumpAccessCheckDoneWrapper, this); + auto aclChecklist = clientAclChecklistCreate(Config.accessList.ssl_bump, http); + ACLFilledChecklist::NonBlockingCheck(std::move(aclChecklist), sslBumpAccessCheckDoneWrapper, this); return true; } diff --git a/src/client_side_request.h b/src/client_side_request.h index e35962564cd..bff45673b39 100644 --- a/src/client_side_request.h +++ b/src/client_side_request.h @@ -10,6 +10,7 @@ #define SQUID_SRC_CLIENT_SIDE_REQUEST_H #include "AccessLogEntry.h" +#include "acl/FilledChecklist.h" #include "client_side.h" #include "clientStream.h" #include "http/forward.h" @@ -257,7 +258,7 @@ class ClientHttpRequest /* client http based routines */ char *clientConstructTraceEcho(ClientHttpRequest *); -ACLFilledChecklist *clientAclChecklistCreate(const acl_access *, ClientHttpRequest *); +ACLFilledChecklist::MakingPointer clientAclChecklistCreate(const acl_access *, ClientHttpRequest *); void clientAclChecklistFill(ACLFilledChecklist &, ClientHttpRequest *); void clientAccessCheck(ClientHttpRequest *); diff --git a/src/peer_digest.cc b/src/peer_digest.cc index 089a2db8780..aa0e89c6c48 100644 --- a/src/peer_digest.cc +++ b/src/peer_digest.cc @@ -42,9 +42,7 @@ static int peerDigestFetchReply(void *, char *, ssize_t); int peerDigestSwapInCBlock(void *, char *, ssize_t); int peerDigestSwapInMask(void *, char *, ssize_t); static int peerDigestFetchedEnough(DigestFetchState * fetch, char *buf, ssize_t size, const char *step_name); -static void peerDigestFetchStop(DigestFetchState * fetch, char *buf, const char *reason); -static void peerDigestFetchAbort(DigestFetchState * fetch, char *buf, const char *reason); -static void peerDigestReqFinish(DigestFetchState *, char *buf, const char *reason, int err); +static void finishAndDeleteFetch(DigestFetchState *, const char *reason, bool sawError); static void peerDigestFetchSetStats(DigestFetchState * fetch); static int peerDigestSetCBlock(PeerDigest * pd, const char *buf); static int peerDigestUseful(const PeerDigest * pd); @@ -331,12 +329,12 @@ peerDigestHandleReply(void *data, StoreIOBuffer receivedData) int newsize; if (receivedData.flags.error) { - peerDigestFetchAbort(fetch, fetch->buf, "failure loading digest reply from Store"); + finishAndDeleteFetch(fetch, "failure loading digest reply from Store", true); return; } if (!fetch->pd) { - peerDigestFetchAbort(fetch, fetch->buf, "digest disappeared while loading digest reply from Store"); + finishAndDeleteFetch(fetch, "digest disappeared while loading digest reply from Store", true); return; } @@ -411,7 +409,7 @@ peerDigestHandleReply(void *data, StoreIOBuffer receivedData) // that the parser does not regard EOF as a special condition (it is true now but may change // in the future). if (fetch->sc->atEof()) { - peerDigestFetchAbort(fetch, fetch->buf, "premature end of digest reply"); + finishAndDeleteFetch(fetch, "premature end of digest reply", true); return; } @@ -463,7 +461,7 @@ peerDigestFetchReply(void *data, char *buf, ssize_t size) assert(fetch->old_entry->mem_obj->request); if (!Store::Root().updateOnNotModified(fetch->old_entry, *fetch->entry)) { - peerDigestFetchAbort(fetch, buf, "header update failure after a 304 response"); + finishAndDeleteFetch(fetch, "header update failure after a 304 response", true); return -1; } @@ -481,12 +479,12 @@ peerDigestFetchReply(void *data, char *buf, ssize_t size) /* fetch->entry->mem_obj->request = nullptr; */ if (!fetch->pd->cd) { - peerDigestFetchAbort(fetch, buf, "304 without the old in-memory digest"); + finishAndDeleteFetch(fetch, "304 without the old in-memory digest", true); return -1; } // stay with the old in-memory digest - peerDigestFetchStop(fetch, buf, "Not modified"); + finishAndDeleteFetch(fetch, "Not modified", false); return -1; } else if (status == Http::scOkay) { /* get rid of old entry if any */ @@ -502,7 +500,7 @@ peerDigestFetchReply(void *data, char *buf, ssize_t size) fetch->state = DIGEST_READ_CBLOCK; } else { /* some kind of a bug */ - peerDigestFetchAbort(fetch, buf, reply.sline.reason()); + finishAndDeleteFetch(fetch, reply.sline.reason(), true); return -1; /* XXX -1 will abort stuff in ReadReply! */ } } @@ -534,14 +532,14 @@ peerDigestSwapInCBlock(void *data, char *buf, ssize_t size) fetch->state = DIGEST_READ_MASK; return StoreDigestCBlockSize; } else { - peerDigestFetchAbort(fetch, buf, "invalid digest cblock"); + finishAndDeleteFetch(fetch, "invalid digest cblock", true); return -1; } } /* need more data, do we have space? */ if (size >= SM_PAGE_SIZE) { - peerDigestFetchAbort(fetch, buf, "digest cblock too big"); + finishAndDeleteFetch(fetch, "digest cblock too big", true); return -1; } @@ -582,7 +580,7 @@ peerDigestSwapInMask(void *data, char *buf, ssize_t size) } static int -peerDigestFetchedEnough(DigestFetchState * fetch, char *buf, ssize_t size, const char *step_name) +peerDigestFetchedEnough(DigestFetchState * fetch, char *, ssize_t size, const char *step_name) { static const SBuf hostUnknown(""); // peer host (if any) SBuf host = hostUnknown; @@ -629,34 +627,15 @@ peerDigestFetchedEnough(DigestFetchState * fetch, char *buf, ssize_t size, const if (reason) { const int level = strstr(reason, "?!") ? 1 : 3; debugs(72, level, "" << step_name << ": peer " << host << ", exiting after '" << reason << "'"); - peerDigestReqFinish(fetch, buf, reason, !no_bug); + finishAndDeleteFetch(fetch, reason, !no_bug); } return reason != nullptr; } -/* call this when all callback data is valid and fetch must be stopped but - * no error has occurred (e.g. we received 304 reply and reuse old digest) */ -static void -peerDigestFetchStop(DigestFetchState * fetch, char *buf, const char *reason) -{ - assert(reason); - debugs(72, 2, "peerDigestFetchStop: peer " << fetch->pd->host << ", reason: " << reason); - peerDigestReqFinish(fetch, buf, reason, 0); -} - -/// diff reducer: handle a peer digest fetch failure -static void -peerDigestFetchAbort(DigestFetchState * fetch, char *buf, const char *reason) -{ - assert(reason); - peerDigestReqFinish(fetch, buf, reason, 1); -} - /* complete the digest transfer, update stats, unlock/release everything */ static void -peerDigestReqFinish(DigestFetchState * fetch, char * /* buf */, - const char *reason, int err) +finishAndDeleteFetch(DigestFetchState * const fetch, const char * const reason, const bool err) { assert(reason); diff --git a/src/peer_select.cc b/src/peer_select.cc index ead91c0f991..632c2e8b763 100644 --- a/src/peer_select.cc +++ b/src/peer_select.cc @@ -613,18 +613,18 @@ PeerSelector::selectMore() if (always_direct == ACCESS_DUNNO) { debugs(44, 3, "direct = " << DirectStr[direct] << " (always_direct to be checked)"); /** check always_direct; */ - const auto ch = new ACLFilledChecklist(Config.accessList.AlwaysDirect, request); + auto ch = ACLFilledChecklist::Make(Config.accessList.AlwaysDirect, request); ch->al = al; ch->syncAle(request, nullptr); - ch->nonBlockingCheck(CheckAlwaysDirectDone, this); + ACLFilledChecklist::NonBlockingCheck(std::move(ch), CheckAlwaysDirectDone, this); return; } else if (never_direct == ACCESS_DUNNO) { debugs(44, 3, "direct = " << DirectStr[direct] << " (never_direct to be checked)"); /** check never_direct; */ - const auto ch = new ACLFilledChecklist(Config.accessList.NeverDirect, request); + auto ch = ACLFilledChecklist::Make(Config.accessList.NeverDirect, request); ch->al = al; ch->syncAle(request, nullptr); - ch->nonBlockingCheck(CheckNeverDirectDone, this); + ACLFilledChecklist::NonBlockingCheck(std::move(ch), CheckNeverDirectDone, this); return; } else if (request->flags.noDirect) { /** if we are accelerating, direct is not an option. */ diff --git a/src/security/PeerConnector.cc b/src/security/PeerConnector.cc index 48fbbf45c13..7fdffebf721 100644 --- a/src/security/PeerConnector.cc +++ b/src/security/PeerConnector.cc @@ -169,9 +169,9 @@ Security::PeerConnector::initialize(Security::SessionPointer &serverSession) // TODO: Remove ACLFilledChecklist::sslErrors and other pre-computed // state in favor of the ACLs accessing current/fresh info directly. if (acl_access *acl = ::Config.ssl_client.cert_error) { - const auto check = new ACLFilledChecklist(acl, request.getRaw()); + auto check = ACLFilledChecklist::Make(acl, request.getRaw()); fillChecklist(*check); - SSL_set_ex_data(serverSession.get(), ssl_ex_index_cert_error_check, check); + SSL_set_ex_data(serverSession.get(), ssl_ex_index_cert_error_check, check.release()); } } diff --git a/src/ssl/PeekingPeerConnector.cc b/src/ssl/PeekingPeerConnector.cc index 2f087368122..87aaeb1cbb2 100644 --- a/src/ssl/PeekingPeerConnector.cc +++ b/src/ssl/PeekingPeerConnector.cc @@ -69,7 +69,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSplice() { handleServerCertificate(); - const auto acl_checklist = new ACLFilledChecklist(::Config.accessList.ssl_bump, request.getRaw()); + auto acl_checklist = ACLFilledChecklist::Make(::Config.accessList.ssl_bump, request.getRaw()); acl_checklist->al = al; acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpNone)); acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpPeek)); @@ -84,7 +84,7 @@ Ssl::PeekingPeerConnector::checkForPeekAndSplice() if (!srvBio->canBump()) acl_checklist->banAction(Acl::Answer(ACCESS_ALLOWED, Ssl::bumpBump)); acl_checklist->syncAle(request.getRaw(), nullptr); - acl_checklist->nonBlockingCheck(Ssl::PeekingPeerConnector::cbCheckForPeekAndSpliceDone, this); + ACLFilledChecklist::NonBlockingCheck(std::move(acl_checklist), Ssl::PeekingPeerConnector::cbCheckForPeekAndSpliceDone, this); } void