From 01402d56846a3a61811ebd4e6bc97e53f908e568 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Thu, 5 Feb 2015 19:53:54 +0100 Subject: [PATCH] trust root nxdomains --- pdns/pdns_recursor.cc | 2 + pdns/syncres.cc | 85 +++++++++++++++++++++++++++++-------------- pdns/syncres.hh | 2 +- 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 86f556e90..fe08faaae 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1989,6 +1989,7 @@ int serviceMain(int argc, char*argv[]) SyncRes::s_serverID=::arg()["server-id"]; SyncRes::s_maxqperq=::arg().asNum("max-qperq"); SyncRes::s_maxtotusec=1000*::arg().asNum("max-total-msec"); + SyncRes::s_rootNXTrust = ::arg().mustDo( "root-nx-trust"); if(SyncRes::s_serverID.empty()) { char tmp[128]; gethostname(tmp, sizeof(tmp)-1); @@ -2312,6 +2313,7 @@ int main(int argc, char **argv) ::arg().setSwitch( "disable-edns", "Disable EDNS - EXPERIMENTAL, LEAVE DISABLED" )= ""; ::arg().setSwitch( "disable-packetcache", "Disable packetcache" )= "no"; ::arg().setSwitch( "pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads")=""; + ::arg().setSwitch( "root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist")=""; ::arg().setSwitch( "any-to-tcp","Answer ANY queries with tc=1, shunting to TCP" )="no"; ::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate")="1680"; ::arg().set("minimum-ttl-override", "Set under adverse conditions, a minimum TTL")="0"; diff --git a/pdns/syncres.cc b/pdns/syncres.cc index b48b07463..b59826718 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -63,6 +63,7 @@ uint64_t SyncRes::s_unreachables; unsigned int SyncRes::s_minimumTTL; bool SyncRes::s_doIPv6; bool SyncRes::s_nopacketcache; +bool SyncRes::s_rootNXTrust; unsigned int SyncRes::s_maxqperq; unsigned int SyncRes::s_maxtotusec; string SyncRes::s_serverID; @@ -678,7 +679,16 @@ bool SyncRes::doCNAMECacheCheck(const string &qname, const QType &qtype, vector< } +static const string getLastLabel(const std::string& qname) +{ + string ret=qname.substr(0, qname.length()-1); + string::size_type pos = ret.rfind('.'); + if(pos != string::npos) { + ret = ret.substr(pos+1) + "."; + } + return ret; +} bool SyncRes::doCacheCheck(const string &qname, const QType &qtype, vector&ret, int depth, int &res) { @@ -693,37 +703,54 @@ bool SyncRes::doCacheCheck(const string &qname, const QType &qtype, vector "< range=t_sstorage->negcache.equal_range(tie(qname)); - negcache_t::iterator ni; - for(ni=range.first; ni != range.second; ni++) { - // we have something - if(ni->d_qtype.getCode() == 0 || ni->d_qtype == qtype) { - res=0; - if((uint32_t)d_now.tv_sec < ni->d_ttd) { - sttl=ni->d_ttd - d_now.tv_sec; - if(ni->d_qtype.getCode()) { - LOG(prefix<d_qname<<"' for another "<d_qname<<"' for another "<d_qname; - sqt=QType::SOA; - moveCacheItemToBack(t_sstorage->negcache, ni); - break; - } - else { - LOG(prefix<negcache, ni); + pair range; + QType qtnull(0); + range.first=t_sstorage->negcache.find(tie(getLastLabel(qname), qtnull)); + // cerr<< "eq: "<<(range.first != t_sstorage->negcache.end() )<negcache.end() + && range.first->d_qname=="." && (uint32_t)d_now.tv_sec < range.first->d_ttd ) { + sttl=range.first->d_ttd - d_now.tv_sec; + + cerr<d_name<<"' & '"<d_qname<<"' for another "<d_qname; + sqt=QType::SOA; + moveCacheItemToBack(t_sstorage->negcache, range.first); + + giveNegative=true; + } + else { + range=t_sstorage->negcache.equal_range(tie(qname)); + negcache_t::iterator ni; + for(ni=range.first; ni != range.second; ni++) { + // we have something + if(ni->d_qtype.getCode() == 0 || ni->d_qtype == qtype) { + res=0; + if((uint32_t)d_now.tv_sec < ni->d_ttd) { + sttl=ni->d_ttd - d_now.tv_sec; + if(ni->d_qtype.getCode()) { + LOG(prefix<d_qname<<"' for another "<d_qname<<"' for another "<d_qname; + sqt=QType::SOA; + moveCacheItemToBack(t_sstorage->negcache, ni); + break; + } + else { + LOG(prefix<negcache, ni); + } } } } - set cset; bool found=false, expired=false; @@ -1123,6 +1150,10 @@ int SyncRes::doResolveAt(set nameservers, string auth, ne.d_qtype=QType(0); // this encodes 'whole record' replacing_insert(t_sstorage->negcache, ne); + if(s_rootNXTrust && auth==".") { + ne.d_name = getLastLabel(ne.d_name); + replacing_insert(t_sstorage->negcache, ne); + } negindic=true; } diff --git a/pdns/syncres.hh b/pdns/syncres.hh index d77023181..f365ee76c 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -387,7 +387,7 @@ public: static bool s_noEDNSPing; static bool s_noEDNS; - + static bool s_rootNXTrust; struct AuthDomain { vector d_servers; -- 2.40.0