From: bert hubert Date: Sat, 28 Nov 2015 11:38:05 +0000 (+0100) Subject: make nxdomains/noerror responses work. We validate the NSEC/NSEC3 records, but don... X-Git-Tag: dnsdist-1.0.0-alpha1~178 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=620db2c8fb50be9e2dd1dbd780ee56e2364b16d8;p=pdns make nxdomains/noerror responses work. We validate the NSEC/NSEC3 records, but don't yet prove they cover the right things. --- diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 31ab17f04..768406606 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -39,6 +39,7 @@ #include #include #include "logger.hh" +#include "validate.hh" #include "misc.hh" #include "arguments.hh" #include "lwres.hh" @@ -748,6 +749,14 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vectord_qname; sqt=QType::SOA; + if(d_doDNSSEC) { + for(const auto& p : ni->d_dnssecProof) { + for(const auto& rec: p.second.records) + ret.push_back(rec); + for(const auto& rec: p.second.signatures) + ret.push_back(rec); + } + } moveCacheItemToBack(t_sstorage->negcache, ni); break; } @@ -789,7 +798,7 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vector& records, const set& types) +{ + recsig_t ret; + for(const auto& rec : records) { + if(rec.d_type == QType::RRSIG) { + auto rrs=getRR(rec); + if(types.count(rrs->d_type)) + ret[make_pair(rec.d_name, rrs->d_type)].signatures.push_back(rec); + } + else if(types.count(rec.d_type)) + ret[make_pair(rec.d_name, rec.d_type)].records.push_back(rec); + } + return ret; +} + +static void addNXNSECS(vector&ret, const vector& records) +{ + auto csp = harvestRecords(records, {QType::NSEC, QType::NSEC3, QType::SOA}); + for(const auto& c : csp) { + if(c.first.second == QType::NSEC || c.first.second == QType::NSEC3 || c.first.second == QType::SOA) { + if(c.first.second !=QType::SOA) { + for(const auto& rec : c.second.records) + ret.push_back(rec); + } + for(const auto& rec : c.second.signatures) + ret.push_back(rec); + } + } +} + /** returns -1 in case of no results, rcode otherwise */ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype, vector&ret, @@ -1199,7 +1239,7 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe ne.d_ttd=d_now.tv_sec + rec.d_ttl; ne.d_name=qname; ne.d_qtype=QType(0); // this encodes 'whole record' - + ne.d_dnssecProof = harvestRecords(lwr.d_records, {QType::NSEC, QType::NSEC3}); replacing_insert(t_sstorage->negcache, ne); if(s_rootNXTrust && auth.isRoot()) { ne.d_name = getLastLabel(ne.d_name); @@ -1261,6 +1301,7 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe ne.d_ttd=d_now.tv_sec + rec.d_ttl; ne.d_name=qname; ne.d_qtype=qtype; + ne.d_dnssecProof = harvestRecords(lwr.d_records, {QType::NSEC, QType::NSEC3}); if(qtype.getCode()) { // prevents us from blacking out a whole domain replacing_insert(t_sstorage->negcache, ne); } @@ -1290,10 +1331,14 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe } if(lwr.d_rcode==RCode::NXDomain) { LOG(prefix< records; + vector signatures; +}; +typedef map, BothRecordsAndSignatures> recsig_t; + +recsig_t harvestRecords(const std::vector& records, const std::set& types); + + struct NegCacheEntry { DNSName d_name; @@ -38,6 +49,7 @@ struct NegCacheEntry { return d_ttd; } + recsig_t d_dnssecProof; };