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;
/* 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});
}
}
}
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);
return false;
}
- VLOG(log, ": done!" << endl);
+ VLOG_NO_PREFIX(log, ": done!" << endl);
++d_nsec3Hits;
res = RCode::NoError;
addToRRSet(now, soaSet, soaSignatures, zone, doDNSSEC, ret);
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) {
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) {
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());
}
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);
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<