Skip to content

Commit

Permalink
Merge pull request #14858 from omoerbeek/rec-aggr-cache-origin
Browse files Browse the repository at this point in the history
rec: Remember which query led to aggresive cache insert/update
  • Loading branch information
omoerbeek authored Nov 21, 2024
2 parents 619958e + 26d461c commit 09df974
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 18 deletions.
20 changes: 10 additions & 10 deletions pdns/recursordist/aggressive_nsec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::shared_ptr<const RRSIGRecordContent>>& signatures, bool nsec3)
void AggressiveNSECCache::insertNSEC(const DNSName& zone, const DNSName& owner, const DNSRecord& record, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, bool nsec3, const DNSName& qname, QType qtype)
{
if (nsec3 && nsec3Disabled()) {
return;
Expand Down Expand Up @@ -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});
}
}
}
Expand Down Expand Up @@ -572,7 +572,7 @@ bool AggressiveNSECCache::getNSEC3Denial(time_t now, std::shared_ptr<LockGuarded

ZoneEntry::CacheEntry exactNSEC3;
if (getNSEC3(now, zoneEntry, nameHash, exactNSEC3)) {
VLOG(log, name << ": Found a direct NSEC3 match for " << nameHash);
VLOG(log, name << ": Found a direct NSEC3 match for " << nameHash << " inserted by " << exactNSEC3.d_qname << '/' << exactNSEC3.d_qtype);
auto nsec3 = std::dynamic_pointer_cast<const NSEC3RecordContent>(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);
Expand Down Expand Up @@ -603,7 +603,7 @@ bool AggressiveNSECCache::getNSEC3Denial(time_t now, std::shared_ptr<LockGuarded
return false;
}

VLOG(log, ": done!" << endl);
VLOG_NO_PREFIX(log, ": done!" << endl);
++d_nsec3Hits;
res = RCode::NoError;
addToRRSet(now, soaSet, soaSignatures, zone, doDNSSEC, ret);
Expand All @@ -621,7 +621,7 @@ bool AggressiveNSECCache::getNSEC3Denial(time_t now, std::shared_ptr<LockGuarded
remainingLabels--;

if (getNSEC3(now, zoneEntry, closestHash, closestNSEC3)) {
VLOG(log, name << ": Found closest encloser at " << closestEncloser << " (" << closestHash << ")" << endl);
VLOG(log, name << ": Found closest encloser at " << closestEncloser << " (" << closestHash << ") inserted by " << closestNSEC3.d_qname << '/' << closestNSEC3.d_qtype << endl);

auto nsec3 = std::dynamic_pointer_cast<const NSEC3RecordContent>(closestNSEC3.d_record);
if (!nsec3 || nsec3->d_iterations != iterations || nsec3->d_salt != salt) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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());
}
Expand Down
4 changes: 3 additions & 1 deletion pdns/recursordist/aggressive_nsec.hh
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public:
return s_maxNSEC3CommonPrefix == 0;
}

void insertNSEC(const DNSName& zone, const DNSName& owner, const DNSRecord& record, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, bool nsec3);
void insertNSEC(const DNSName& zone, const DNSName& owner, const DNSRecord& record, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, bool nsec3, const DNSName& qname = g_rootdnsname, QType qtype = QType::ENT);
bool getDenial(time_t, const DNSName& name, const QType& type, std::vector<DNSRecord>& ret, int& res, const ComboAddress& who, const boost::optional<std::string>& routingTag, bool doDNSSEC, pdns::validation::ValidationContext& validationContext, const OptLog& log = std::nullopt);

void removeZoneInfo(const DNSName& zone, bool subzones);
Expand Down Expand Up @@ -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<
Expand Down
2 changes: 1 addition & 1 deletion pdns/recursordist/syncres.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
12 changes: 6 additions & 6 deletions pdns/recursordist/test-aggressive_nsec_cc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1231,12 +1231,12 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump)

std::vector<std::string> expected;
expected.emplace_back("; Zone powerdns.com.\n");
expected.emplace_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC\n");
expected.emplace_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC by ./TYPE0\n");
expected.emplace_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");
expected.emplace_back("z.powerdns.com. 10 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC\n");
expected.emplace_back("z.powerdns.com. 10 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC by ./TYPE0\n");
expected.emplace_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");
expected.emplace_back("; Zone powerdns.org.\n");
expected.emplace_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3\n");
expected.emplace_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3 by ./TYPE0\n");
expected.emplace_back("- RRSIG NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");

struct timeval now
Expand Down Expand Up @@ -1286,12 +1286,12 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump)

expected.clear();
expected.emplace_back("; Zone powerdns.com.\n");
expected.emplace_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC\n");
expected.emplace_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC by ./TYPE0\n");
expected.emplace_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");
expected.emplace_back("z.powerdns.com. 30 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC\n");
expected.emplace_back("z.powerdns.com. 30 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC by ./TYPE0\n");
expected.emplace_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");
expected.emplace_back("; Zone powerdns.org.\n");
expected.emplace_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3\n");
expected.emplace_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3 by ./TYPE0\n");
expected.emplace_back("- RRSIG NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data\n");

rec.d_name = DNSName("z.powerdns.com");
Expand Down

0 comments on commit 09df974

Please sign in to comment.