From: Kees Monshouwer Date: Wed, 6 Apr 2016 07:25:19 +0000 (+0200) Subject: redo NSEC3 in bind backend X-Git-Tag: dnsdist-1.0.0-beta1~24^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=444ca1fe7d164dd1db9f4bc2f99ef5fc1d371c45;p=thirdparty%2Fpdns.git redo NSEC3 in bind backend --- diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index d7b081761c..fe95a29482 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -1,4 +1,4 @@ - /* +/* PowerDNS Versatile Database Driven Nameserver Copyright (C) 2002 - 2014 PowerDNS.COM BV @@ -457,15 +457,9 @@ void Bind2Backend::parseZoneFile(BB2DomainInfo *bbd) if(rr.qtype.getCode() == QType::NSEC || rr.qtype.getCode() == QType::NSEC3) continue; // we synthesise NSECs on demand - if(nsec3zone) { - if(rr.qtype.getCode() != QType::NSEC3 && rr.qtype.getCode() != QType::RRSIG) - hashed=toBase32Hex(hashQNameWithSalt(ns3pr, rr.qname)); - else - hashed=""; - } - insertRecord(*bbd, rr.qname, rr.qtype, rr.content, rr.ttl, hashed); + insertRecord(*bbd, rr.qname, rr.qtype, rr.content, rr.ttl, ""); } - fixupAuth(bbd->d_records.getWRITABLE()); + fixupOrderAndAuth(*bbd, nsec3zone, ns3pr); doEmptyNonTerminals(*bbd, nsec3zone, ns3pr); bbd->setCtime(); bbd->d_loaded=true; @@ -656,43 +650,55 @@ void Bind2Backend::reload() } } -void Bind2Backend::fixupAuth(shared_ptr records) +void Bind2Backend::fixupOrderAndAuth(BB2DomainInfo& bbd, bool nsec3zone, NSEC3PARAMRecordContent ns3pr) { - pair range; - DNSName sqname; - - recordstorage_t nssets; - for(const Bind2DNSRecord& bdr : *records) { - if(bdr.qtype==QType::NS) - nssets.insert(bdr); + shared_ptr records = bbd.d_records.getWRITABLE(); + recordstorage_t::const_iterator iter; + + bool skip; + DNSName shorter; + set nssets, dssets; + + for(const auto& bdr: *records) { + if(!bdr.qname.isRoot() && bdr.qtype == QType::NS) + nssets.insert(bdr.qname); + else if(bdr.qtype == QType::DS) + dssets.insert(bdr.qname); } - - for(const Bind2DNSRecord& bdr : *records) { - bdr.auth=true; - - if(bdr.qtype == QType::DS) // as are delegation signer records - continue; - sqname = bdr.qname; - - do { - if(sqname.empty() || sqname.isRoot()) // this is auth of course! - continue; - if(bdr.qtype == QType::NS || nssets.count(sqname)) { // NS records which are not apex are unauth by definition - bdr.auth=false; - } - } while(sqname.chopOff()); + for(auto iter = records->begin(); iter != records->end(); iter++) { + skip = false; + shorter = iter->qname; + + if (!iter->qname.isRoot() && shorter.chopOff() && !iter->qname.isRoot()) { + do { + if(nssets.count(shorter)) { + skip = true; + break; + } + } while(shorter.chopOff() && !iter->qname.isRoot()); + } + + iter->auth = (!skip && (iter->qtype == QType::DS || iter->qtype == QType::RRSIG || !nssets.count(iter->qname))); + + if(!skip && nsec3zone && iter->qtype != QType::RRSIG && (iter->auth || (iter->qtype == QType::NS && !ns3pr.d_flags) || dssets.count(iter->qname))) { + Bind2DNSRecord bdr = *iter; + bdr.nsec3hash = toBase32Hex(hashQNameWithSalt(ns3pr, bdr.qname+bbd.d_name)); + records->replace(iter, bdr); + } + + // cerr<qname.toString()<<"\t"<qtype).getName()<<"\t"<nsec3hash<<"\t"<auth< records = bbd.d_records.get(); - bool auth, doent=true; + + bool auth; + DNSName shorter; set qnames; map nonterm; - DNSName shorter; - string hashed; uint32_t maxent = ::arg().asNum("max-ent-entries"); @@ -700,13 +706,13 @@ void Bind2Backend::doEmptyNonTerminals(BB2DomainInfo& bbd, bool nsec3zone, NSEC3 qnames.insert(bdr.qname); for(const auto& bdr : *records) { - shorter=bdr.qname; if (!bdr.auth && bdr.qtype == QType::NS) - auth=(!nsec3zone || !ns3pr.d_flags); + auth = (!nsec3zone || !ns3pr.d_flags); else - auth=bdr.auth; + auth = bdr.auth; + shorter = bdr.qname; while(shorter.chopOff()) { if(!qnames.count(shorter)) @@ -714,31 +720,31 @@ void Bind2Backend::doEmptyNonTerminals(BB2DomainInfo& bbd, bool nsec3zone, NSEC3 if(!(maxent)) { L<(shorter, auth)); --maxent; } else if (auth) - nonterm[shorter]=true; + nonterm[shorter] = true; } } - if(!doent) - return; } DNSResourceRecord rr; - rr.qtype="#0"; - rr.content=""; - rr.ttl=0; - for(auto &nt: nonterm) + rr.qtype = "#0"; + rr.content = ""; + rr.ttl = 0; + for(auto& nt : nonterm) { - rr.qname=nt.first+bbd.d_name; - if(nsec3zone) - hashed=toBase32Hex(hashQNameWithSalt(ns3pr, rr.qname)); + string hashed; + rr.qname = nt.first + bbd.d_name; + if(nsec3zone && nt.second) + hashed = toBase32Hex(hashQNameWithSalt(ns3pr, rr.qname)); insertRecord(bbd, rr.qname, rr.qtype, rr.content, rr.ttl, hashed, &nt.second); + + // cerr<::type records_by_hashindex_t; - records_by_hashindex_t& hashindex=boost::multi_index::get(*bbd.d_records.getWRITABLE()); // needlessly dangerous - -// for(const Bind2DNSRecord& bdr : hashindex) { -// cerr<<"Hash: "<(*bbd.d_records.getWRITABLE()); - if (before.empty()) { - iter = hashindex.upper_bound(lqname); - - if(iter != hashindex.begin() && (iter == hashindex.end() || iter->nsec3hash > lqname)) - { - iter--; - } - - if(iter == hashindex.begin() && (iter->nsec3hash > lqname)) - { - iter = hashindex.end(); - } + records_by_hashindex_t::const_iterator iter, first; + first = hashindex.upper_bound(""); // skip records without a hash - wraponce = false; - while(iter == hashindex.end() || (!iter->auth && !(iter->qtype == QType::NS && iter->qname!= auth && !ns3pr.d_flags)) || iter->nsec3hash.empty()) - { - iter--; - if(iter == hashindex.begin()) { - if (!wraponce) { - iter = hashindex.end(); - wraponce = true; - } - else { - before.clear(); - after.clear(); - return false; - } - } - } + // for(auto iter = first; iter != hashindex.end(); iter++) + // cerr<nsec3hash<nsec3hash; + after = first->nsec3hash; + } else { + after = iter->nsec3hash; + if (iter != first) + --iter; + else + iter = --hashindex.end(); before = iter->nsec3hash; - unhashed = iter->qname + auth; - // cerr<<"before: "<<(iter->nsec3hash)<<"/"<<(iter->qname)<auth && !(iter->qtype == QType::NS && iter->qname != auth && !ns3pr.d_flags)) || iter->nsec3hash.empty()) - { - iter++; - if(iter == hashindex.end()) { - if (!wraponce) { - iter = hashindex.begin(); - wraponce = true; - } - else { - before.clear(); - after.clear(); - return false; - } - } } + unhashed = iter->qname+bbd.d_name; - after = iter->nsec3hash; - // cerr<<"after: "<<(iter->nsec3hash)<<"/"<<(iter->qname)<&parts, Utility::pid_t ppid); static string DLReloadNowHandler(const vector&parts, Utility::pid_t ppid); static string DLAddDomainHandler(const vector&parts, Utility::pid_t ppid); - static void fixupAuth(shared_ptr records); + static void fixupOrderAndAuth(BB2DomainInfo& bbd, bool nsec3zone, NSEC3PARAMRecordContent ns3pr); void doEmptyNonTerminals(BB2DomainInfo& bbd, bool nsec3zone, NSEC3PARAMRecordContent ns3pr); void loadConfig(string *status=0); static void nukeZoneRecords(BB2DomainInfo *bbd);