From: Otto Moerbeek Date: Wed, 20 Nov 2024 09:46:34 +0000 (+0100) Subject: rec: Remember which query led to aggresive cache insert/update X-Git-Tag: rec-5.2.0-beta1~10^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=544bab7ce3f09f3a54d5a3769a9b0b6f240a39bb;p=thirdparty%2Fpdns.git rec: Remember which query led to aggresive cache insert/update And report this in cache dump and traces Fixes #14855 --- diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index 6909445bdb..388c720016 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -269,7 +269,7 @@ bool AggressiveNSECCache::isSmallCoveringNSEC3(const DNSName& owner, const std:: return commonPrefixIsLong(ownerHash, nextHash, AggressiveNSECCache::s_maxNSEC3CommonPrefix); } -void AggressiveNSECCache::insertNSEC(const DNSName& zone, const DNSName& owner, const DNSRecord& record, const std::vector>& signatures, bool nsec3) +void AggressiveNSECCache::insertNSEC(const DNSName& zone, const DNSName& owner, const DNSRecord& record, const std::vector>& signatures, bool nsec3, const DNSName& qname, QType qtype) { if (nsec3 && nsec3Disabled()) { return; @@ -345,21 +345,21 @@ void AggressiveNSECCache::insertNSEC(const DNSName& zone, const DNSName& owner, /* the TTL is already a TTD by now */ if (!nsec3 && isWildcardExpanded(owner.countLabels(), *signatures.at(0))) { DNSName realOwner = getNSECOwnerName(owner, signatures); - auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, realOwner, next, record.d_ttl}); + auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, realOwner, next, qname, record.d_ttl, qtype}); if (pair.second) { ++d_entriesCount; } else { - zoneEntry->d_entries.replace(pair.first, {record.getContent(), signatures, std::move(realOwner), next, record.d_ttl}); + zoneEntry->d_entries.replace(pair.first, {record.getContent(), signatures, std::move(realOwner), next, qname, record.d_ttl, qtype}); } } else { - auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, owner, next, record.d_ttl}); + auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, owner, next, qname, record.d_ttl, qtype}); if (pair.second) { ++d_entriesCount; } else { - zoneEntry->d_entries.replace(pair.first, {record.getContent(), signatures, owner, std::move(next), record.d_ttl}); + zoneEntry->d_entries.replace(pair.first, {record.getContent(), signatures, owner, std::move(next), qname, record.d_ttl, qtype}); } } } @@ -572,7 +572,7 @@ bool AggressiveNSECCache::getNSEC3Denial(time_t now, std::shared_ptr(exactNSEC3.d_record); if (!nsec3 || nsec3->d_iterations != iterations || nsec3->d_salt != salt) { VLOG_NO_PREFIX(log, " but the content is not valid, or has a different salt or iterations count" << endl); @@ -603,7 +603,7 @@ bool AggressiveNSECCache::getNSEC3Denial(time_t now, std::shared_ptr(closestNSEC3.d_record); if (!nsec3 || nsec3->d_iterations != iterations || nsec3->d_salt != salt) { @@ -839,7 +839,7 @@ bool AggressiveNSECCache::getDenial(time_t now, const DNSName& name, const QType return false; } - VLOG_NO_PREFIX(log, ": found a possible NSEC at " << entry.d_owner << " "); + VLOG_NO_PREFIX(log, ": found a possible NSEC at " << entry.d_owner << " inserted by " << entry.d_qname << '/' << entry.d_qtype << ' '); // note that matchesNSEC() takes care of ruling out ancestor NSECs for us auto denial = matchesNSEC(name, type.getCode(), entry.d_owner, *content, entry.d_signatures, log); if (denial == dState::NODENIAL || denial == dState::INCONCLUSIVE) { @@ -930,7 +930,7 @@ size_t AggressiveNSECCache::dumpToFile(pdns::UniqueFilePtr& filePtr, const struc for (const auto& entry : zone->d_entries) { int64_t ttl = entry.d_ttd - now.tv_sec; try { - fprintf(filePtr.get(), "%s %" PRId64 " IN %s %s\n", entry.d_owner.toString().c_str(), ttl, zone->d_nsec3 ? "NSEC3" : "NSEC", entry.d_record->getZoneRepresentation().c_str()); + fprintf(filePtr.get(), "%s %" PRId64 " IN %s %s by %s/%s\n", entry.d_owner.toString().c_str(), ttl, zone->d_nsec3 ? "NSEC3" : "NSEC", entry.d_record->getZoneRepresentation().c_str(), entry.d_qname.toString().c_str(), entry.d_qtype.toString().c_str()); for (const auto& signature : entry.d_signatures) { fprintf(filePtr.get(), "- RRSIG %s\n", signature->getZoneRepresentation().c_str()); } diff --git a/pdns/recursordist/aggressive_nsec.hh b/pdns/recursordist/aggressive_nsec.hh index bd3069daae..22983c590a 100644 --- a/pdns/recursordist/aggressive_nsec.hh +++ b/pdns/recursordist/aggressive_nsec.hh @@ -61,7 +61,7 @@ public: return s_maxNSEC3CommonPrefix == 0; } - void insertNSEC(const DNSName& zone, const DNSName& owner, const DNSRecord& record, const std::vector>& signatures, bool nsec3); + void insertNSEC(const DNSName& zone, const DNSName& owner, const DNSRecord& record, const std::vector>& signatures, bool nsec3, const DNSName& qname = g_rootdnsname, QType qtype = QType::ENT); bool getDenial(time_t, const DNSName& name, const QType& type, std::vector& ret, int& res, const ComboAddress& who, const boost::optional& routingTag, bool doDNSSEC, pdns::validation::ValidationContext& validationContext, const OptLog& log = std::nullopt); void removeZoneInfo(const DNSName& zone, bool subzones); @@ -127,7 +127,9 @@ private: DNSName d_owner; DNSName d_next; + DNSName d_qname; // of the query data that lead to this entry being created/updated time_t d_ttd; + QType d_qtype; // of the query data that lead to this entry being created/updated }; typedef multi_index_container< diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 9951f91a50..e6b542537f 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -4874,7 +4874,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& if (g_aggressiveNSECCache && (tCacheEntry->first.type == QType::NSEC || tCacheEntry->first.type == QType::NSEC3) && recordState == vState::Secure && !seenAuth.empty()) { // Good candidate for NSEC{,3} caching - g_aggressiveNSECCache->insertNSEC(seenAuth, tCacheEntry->first.name, tCacheEntry->second.records.at(0), tCacheEntry->second.signatures, tCacheEntry->first.type == QType::NSEC3); + g_aggressiveNSECCache->insertNSEC(seenAuth, tCacheEntry->first.name, tCacheEntry->second.records.at(0), tCacheEntry->second.signatures, tCacheEntry->first.type == QType::NSEC3, qname, qtype); } if (tCacheEntry->first.place == DNSResourceRecord::ANSWER && ednsmask) {