diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index e6b542537f3d..d5e9623754ef 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1675,7 +1675,7 @@ static string resToString(int res) return res >= 0 ? RCode::to_s(res) : std::to_string(res); } -int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context) // NOLINT(readability-function-cognitive-complexity) +int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context, bool* doneResolveFromCache) // NOLINT(readability-function-cognitive-complexity) { auto prefix = getPrefix(depth); auto luaconfsLocal = g_luaconfs.getLocal(); @@ -1733,6 +1733,9 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector scanForCNAMELoop(const DNSName& name, const vect return {false, numCNames}; } -bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse, bool checkForDups) // NOLINT(readability-function-cognitive-complexity) +bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse, bool checkForDups, bool* cnameTargetInCache) // NOLINT(readability-function-cognitive-complexity) { vector cset; vector> signatures; @@ -2724,10 +2732,17 @@ bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector< Context cnameContext; // Be aware that going out on the network might be disabled (cache-only), for example because we are in QM Step0, // so you can't trust that a real lookup will have been made. - res = doResolve(newTarget, qtype, ret, depth + 1, beenthere, cnameContext); + bool fromCache = false; + res = doResolve(newTarget, qtype, ret, depth + 1, beenthere, cnameContext, &fromCache); LOG(prefix << qname << ": Updating validation state for response to " << qname << " from " << context.state << " with the state from the DNAME/CNAME quest: " << cnameContext.state << endl); updateValidationState(qname, context.state, cnameContext.state, prefix); + if (fromCache && foundQT == QType::CNAME) { + if (cnameTargetInCache != nullptr) { + *cnameTargetInCache = true; + } + } + return true; } } diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 6b31b300a236..118d7f8a767c 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -637,14 +637,14 @@ private: bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, QType qtype, LWResult& lwr, boost::optional& ednsmask, const DNSName& auth, bool sendRDQuery, bool wasForwarded, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool doDoT, bool& truncated, bool& spoofed, boost::optional& extendedError, bool dontThrottle = false); bool processAnswer(unsigned int depth, const string& prefix, LWResult& lwr, const DNSName& qname, QType qtype, DNSName& auth, bool wasForwarded, const boost::optional& ednsmask, bool sendRDQuery, NsSet& nameservers, std::vector& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state, const ComboAddress& remoteIP); - int doResolve(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context); + int doResolve(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context, bool* doneResolveFromCache = nullptr); int doResolveNoQNameMinimization(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context, bool* fromCache = nullptr, StopAtDelegation* stopAtDelegation = nullptr); bool doOOBResolve(const AuthDomain& domain, const DNSName& qname, QType qtype, vector& ret, int& res); bool doOOBResolve(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res); static bool isRecursiveForwardOrAuth(const DNSName& qname); static bool isForwardOrAuth(const DNSName& qname); static domainmap_t::const_iterator getBestAuthZone(DNSName* qname); - bool doCNAMECacheCheck(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse, bool checkForDups); + bool doCNAMECacheCheck(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse, bool checkForDups, bool* cnameTargetInCache); bool doCacheCheck(const DNSName& qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context); void getBestNSFromCache(const DNSName& qname, QType qtype, vector& bestns, bool* flawedNSSet, unsigned int depth, const string& prefix, set& beenthere, const boost::optional& cutOffDomain = boost::none); DNSName getBestNSNamesFromCache(const DNSName& qname, QType qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, const string& prefix, set& beenthere);