@@ -4689,6 +4689,8 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string&
46894689 }
46904690
46914691 bool seenBogusRRSet = false ;
4692+ std::vector<tcache_t ::value_type> aggrCacheRecords;
4693+ bool insertIntoAggressiveCache = false ;
46924694 for (auto tCacheEntry = tcache.begin (); tCacheEntry != tcache.end (); ++tCacheEntry) {
46934695
46944696 if (tCacheEntry->second .records .empty ()) { // this happens when we did store signatures, but passed on the records themselves
@@ -4893,14 +4895,35 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string&
48934895
48944896 if (g_aggressiveNSECCache && (tCacheEntry->first .type == QType::NSEC || tCacheEntry->first .type == QType::NSEC3 ) && recordState == vState::Secure && !seenAuth.empty ()) {
48954897 // Good candidate for NSEC{,3} caching
4896- g_aggressiveNSECCache->insertNSEC (seenAuth, tCacheEntry->first .name , tCacheEntry->second .records .at (0 ), tCacheEntry->second .signatures , tCacheEntry->first .type == QType::NSEC3 , qname, qtype);
4898+ aggrCacheRecords.emplace_back (*tCacheEntry);
4899+ if (!insertIntoAggressiveCache) {
4900+ if (tCacheEntry->first .type == QType::NSEC ) {
4901+ // NSECs have no additonal condition, just take them
4902+ insertIntoAggressiveCache = true ;
4903+ }
4904+ else if (tCacheEntry->first .type == QType::NSEC3 && !AggressiveNSECCache::nsec3Disabled ()) {
4905+ // If at least one of the NSEC3s covers quite some names, we will take all of them, as likely all of them are needed for a denial proof.
4906+ if (auto content = getRR<NSEC3RecordContent>(tCacheEntry->second .records .at (0 )); content != nullptr ) {
4907+ if (!AggressiveNSECCache::isSmallCoveringNSEC3 (tCacheEntry->first .name , content->d_nexthash )) {
4908+ insertIntoAggressiveCache = true ;
4909+ }
4910+ }
4911+ }
4912+ }
48974913 }
48984914
48994915 if (tCacheEntry->first .place == DNSResourceRecord::ANSWER && ednsmask) {
49004916 d_wasVariable = true ;
49014917 }
49024918 }
49034919
4920+ // The primary loop determined if we want to take the NSEC(3) records
4921+ if (insertIntoAggressiveCache) {
4922+ for (const auto & entry : aggrCacheRecords) {
4923+ g_aggressiveNSECCache->insertNSEC (seenAuth, entry.first .name , entry.second .records .at (0 ), entry.second .signatures , entry.first .type == QType::NSEC3 , qname, qtype);
4924+ }
4925+ }
4926+
49044927 if (gatherWildcardProof) {
49054928 if (auto wcIt = wildcardCandidates.find (qname); wcIt != wildcardCandidates.end () && !wcIt->second ) {
49064929 // the queried name was not expanded from a wildcard, a record in the CNAME chain was, so we don't need to gather wildcard proof now: we will do that when looking up the CNAME chain
0 commit comments