From: Otto Moerbeek Date: Wed, 27 Sep 2023 07:46:16 +0000 (+0200) Subject: When we have authoritative NS records in cache that do not lead to X-Git-Tag: rec-5.0.0-alpha2~18^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=487dadecad3235a21389e6f2873aa5515f954b3c;p=thirdparty%2Fpdns.git When we have authoritative NS records in cache that do not lead to any usable address, wipe the NS records so a query of NS records to theprant leads to new NS records being inserted into the cache. Previously the presence of the authoritaivbe records would prevent that to happen. Queries would *use* the freshly retrieved parent records, but they would not end up in the cache (the presence of authoritative NS records prevents that) leading to repeated queries to the parent. --- diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 0e4822bede..26c38214d7 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -2233,7 +2233,7 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector vector ns; *flawedNSSet = false; - if (g_recCache->get(d_now.tv_sec, subdomain, QType::NS, flags, &ns, d_cacheRemote, d_routingTag) > 0) { + if (bool isAuth = false; g_recCache->get(d_now.tv_sec, subdomain, QType::NS, flags, &ns, d_cacheRemote, d_routingTag, nullptr, nullptr, nullptr, nullptr, &isAuth) > 0) { if (s_maxnsperresolve > 0 && ns.size() > s_maxnsperresolve) { vector selected; selected.reserve(s_maxnsperresolve); @@ -2269,10 +2269,15 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector else { *flawedNSSet = true; LOG(prefix << qname << ": NS in cache for '" << subdomain << "', but needs glue (" << nrr->getNS() << ") which we miss or is expired" << endl); - g_recCache->doWipeCache(subdomain, false, QType::NS); } } } + if (*flawedNSSet && bestns.empty() && isAuth) { + // The authoritative (child) NS records did not produce any usable addresses, wipe them, so + // these useless records do not prevent parent records to be inserted into the cache + LOG(prefix << qname << ": Wiping flawed authoritative NS records for " << subdomain << endl); + g_recCache->doWipeCache(subdomain, false, QType::NS); + } if (!bestns.empty()) { GetBestNSAnswer answer;