From: Remi Gacogne Date: Wed, 13 Jan 2021 11:10:03 +0000 (+0100) Subject: rec: Account for the NSEC(3) denial TTL in expanded wildcard answers X-Git-Tag: dnsdist-1.6.0-alpha1~43^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=222ce6bfee7718df70dcaa3e22bb42a3ddf66ad1;p=thirdparty%2Fpdns.git rec: Account for the NSEC(3) denial TTL in expanded wildcard answers --- diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 16eb0ca0f4..eb9d010458 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -2312,11 +2312,12 @@ bool SyncRes::validationEnabled() const return g_dnssecmode != DNSSECMode::Off && g_dnssecmode != DNSSECMode::ProcessNoValidate; } -uint32_t SyncRes::computeLowestTTD(const std::vector& records, const std::vector >& signatures, uint32_t signaturesTTL) const +uint32_t SyncRes::computeLowestTTD(const std::vector& records, const std::vector >& signatures, uint32_t signaturesTTL, const std::vector>& authorityRecs) const { uint32_t lowestTTD = std::numeric_limits::max(); - for(const auto& record : records) + for (const auto& record : records) { lowestTTD = min(lowestTTD, record.d_ttl); + } /* even if it was not requested for that request (Process, and neither AD nor DO set), it might be requested at a later time so we need to be careful with the TTL. */ @@ -2327,12 +2328,27 @@ uint32_t SyncRes::computeLowestTTD(const std::vector& records, const for(const auto& sig : signatures) { if (isRRSIGNotExpired(d_now.tv_sec, sig)) { - // we don't decerement d_sigexpire by 'now' because we actually want a TTD, not a TTL */ + // we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */ lowestTTD = min(lowestTTD, static_cast(sig->d_sigexpire)); } } } + for (const auto& entry : authorityRecs) { + /* be careful, this is still a TTL here */ + lowestTTD = min(lowestTTD, static_cast(entry->d_ttl + d_now.tv_sec)); + + if (entry->d_type == QType::RRSIG && validationEnabled()) { + auto rrsig = getRR(*entry); + if (rrsig) { + if (isRRSIGNotExpired(d_now.tv_sec, rrsig)) { + // we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */ + lowestTTD = min(lowestTTD, static_cast(rrsig->d_sigexpire)); + } + } + } + } + return lowestTTD; } @@ -3099,12 +3115,13 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, LWResult& lwr } // supplant - for(tcache_t::iterator i = tcache.begin(); i != tcache.end(); ++i) { - if((i->second.records.size() + i->second.signatures.size()) > 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2) - uint32_t lowestTTD=computeLowestTTD(i->second.records, i->second.signatures, i->second.signaturesTTL); + for (auto& entry : tcache) { + if ((entry.second.records.size() + entry.second.signatures.size() + authorityRecs.size()) > 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2) + uint32_t lowestTTD = computeLowestTTD(entry.second.records, entry.second.signatures, entry.second.signaturesTTL, authorityRecs); - for(auto& record : i->second.records) + for (auto& record : entry.second.records) { record.d_ttl = lowestTTD; // boom + } } // cout<<"Have "<second.records.size()<<" records and "<second.signatures.size()<<" signatures for "<first.name; diff --git a/pdns/syncres.hh b/pdns/syncres.hh index 491cb9f1f2..1ee7eb1a8e 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -848,7 +848,7 @@ private: boost::optional getEDNSSubnetMask(const DNSName&dn, const ComboAddress& rem); bool validationEnabled() const; - uint32_t computeLowestTTD(const std::vector& records, const std::vector >& signatures, uint32_t signaturesTTL) const; + uint32_t computeLowestTTD(const std::vector& records, const std::vector >& signatures, uint32_t signaturesTTL, const std::vector>& authorityRecs) const; void updateValidationState(vState& state, const vState stateUpdate); vState validateRecordsWithSigs(unsigned int depth, const DNSName& qname, const QType& qtype, const DNSName& name, const QType& type, const std::vector& records, const std::vector >& signatures); vState validateDNSKeys(const DNSName& zone, const std::vector& dnskeys, const std::vector >& signatures, unsigned int depth);