From 5605c067aaee5fe9cb36ff54b32c73622c6a05a0 Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Thu, 27 Apr 2006 17:11:44 +0000 Subject: [PATCH] fix . zone refreshing bug (we didn't actually import what the root-servers were telling us) fix case of domain with nameservers with multiple IP addresses of which only one is lame add: --auth-zones, --forward-zones and --export-etc-hosts git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@780 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- pdns/backends/bind/zoneparser2.cc | 1 - pdns/pdns_recursor.cc | 144 ++++++++++++++++++ pdns/syncres.cc | 240 +++++++++++++++++++++--------- pdns/syncres.hh | 23 +++ 4 files changed, 333 insertions(+), 75 deletions(-) diff --git a/pdns/backends/bind/zoneparser2.cc b/pdns/backends/bind/zoneparser2.cc index 24c569f84..81a9235ae 100644 --- a/pdns/backends/bind/zoneparser2.cc +++ b/pdns/backends/bind/zoneparser2.cc @@ -275,7 +275,6 @@ bool ZoneParser::isType(const string &s) if(isClass(s)) return false; - return true; } diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 20bca2c58..ca068d487 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include "dnsparser.hh" #include "dnswriter.hh" #include "dnsrecords.hh" @@ -1146,6 +1147,143 @@ FDMultiplexer* getMultiplexer() exit(1); } +static void makeNameToIPZone(const string& hostname, const string& ip) +{ + SyncRes::AuthDomain ad; + DNSResourceRecord rr; + rr.qname=toCanonic("", hostname); + rr.d_place=DNSResourceRecord::ANSWER; + rr.ttl=86400; + rr.qtype=QType::SOA; + rr.content="localhost. root 1 604800 864002419200 604800"; + + ad.d_records.insert(rr); + + rr.qtype=QType::NS; + rr.content="localhost."; + + ad.d_records.insert(rr); + + rr.qtype=QType::A; + rr.content=ip; + ad.d_records.insert(rr); + + if(SyncRes::s_domainmap.count(rr.qname)) { + L<& parts) +{ + string address=parts[0]; + vector ipparts; + stringtok(ipparts, address,"."); + if(ipparts.size()!=4) + return; + + + SyncRes::AuthDomain ad; + DNSResourceRecord rr; + for(int n=3; n>=0 ; --n) { + rr.qname.append(ipparts[n]); + rr.qname.append(1,'.'); + } + rr.qname.append("in-addr.arpa."); + + rr.d_place=DNSResourceRecord::ANSWER; + rr.ttl=86400; + rr.qtype=QType::SOA; + rr.content="localhost. root 1 604800 864002419200 604800"; + + ad.d_records.insert(rr); + + rr.qtype=QType::NS; + rr.content="localhost."; + + ad.d_records.insert(rr); + rr.qtype=QType::PTR; + + for(unsigned int n=1; n < parts.size(); ++n) { + rr.content=toCanonic("", parts[n]); + ad.d_records.insert(rr); + } + + if(SyncRes::s_domainmap.count(rr.qname)) { + L< parts_t; + parts_t parts; + for(int n=0; n < 2 ; ++n ) { + parts.clear(); + stringtok(parts, ::arg()[n ? "forward-zones" : "auth-zones"], ",\t\n\r"); + for(parts_t::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { + SyncRes::AuthDomain ad; + pair headers=splitField(*iter, '='); + trim(headers.first); + trim(headers.second); + headers.first=toCanonic("", headers.first); + if(n==0) { + L<&ret, int depth, int& res) { - return false; + string prefix; + if(s_log) { + prefix=d_prefix; + prefix.append(depth, ' '); + } + + LOG< range; + + range=iter->second.d_records.equal_range(tie(qname)); // partial lookup + + ret.clear(); + AuthDomain::records_t::const_iterator ziter; + for(ziter=range.first; ziter!=range.second; ++ziter) { + if(ziter->qtype==qtype || ziter->qtype.getCode()==QType::CNAME) // let rest of nameserver do the legwork on this one + ret.push_back(*ziter); + } + if(ret.empty()) { + LOG<first) { + range=iter->second.d_records.equal_range(make_tuple(nsdomain,QType(QType::NS))); + if(range.first==range.second) + continue; + + for(ziter=range.first; ziter!=range.second; ++ziter) { + DNSResourceRecord rr=*ziter; + rr.d_place=DNSResourceRecord::AUTHORITY; + ret.push_back(rr); + } + } + if(ret.empty()) { + LOG<second.d_records.find(make_tuple(authdomain, QType(QType::SOA))); + if(ziter!=iter->second.d_records.end()) { + DNSResourceRecord rr=*ziter; + rr.d_place=DNSResourceRecord::AUTHORITY; + ret.push_back(rr); + } + else + LOG<&ret, int depth, set& beenthere) @@ -114,7 +173,7 @@ int SyncRes::doResolve(const string &qname, const QType &qtype, vector&bes }while(chopOffDotted(subdomain)); } +SyncRes::domainmap_t::const_iterator SyncRes::getBestAuthZone(string* qname) +{ + SyncRes::domainmap_t::const_iterator ret; + do { + ret=s_domainmap.find(*qname); + if(ret!=s_domainmap.end()) + break; + }while(chopOffDotted(*qname)); + return ret; +} /** doesn't actually do the work, leaves that to getBestNSFromCache */ string SyncRes::getBestNSNamesFromCache(const string &qname,set& nsset, int depth, set&beenthere) { string subdomain(qname); + string authdomain(qname); + + domainmap_t::const_iterator iter=getBestAuthZone(&authdomain); + if(iter!=s_domainmap.end()) { + nsset.insert(iter->second.d_server); + return authdomain; + } + set bestns; getBestNSFromCache(subdomain, bestns, depth, beenthere); @@ -431,8 +503,9 @@ struct TCacheComp /** returns -1 in case of no results, rcode otherwise */ -int SyncRes::doResolveAt(set nameservers, string auth, const string &qname, const QType &qtype, vector&ret, - int depth, set&beenthere) +int SyncRes::doResolveAt(set nameservers, string auth, const string &qname, const QType &qtype, + vector&ret, + int depth, set&beenthere) { string prefix; if(s_log) { @@ -458,80 +531,100 @@ int SyncRes::doResolveAt(set nameservers, string auth, LOG< remoteIPs_t; - remoteIPs_t remoteIPs=getAs(*tns, depth+1, beenthere); - if(remoteIPs.empty()) { - LOG<empty()) { + LOG<, set, TCacheComp > tcache_t; tcache_t tcache; @@ -650,9 +743,8 @@ int SyncRes::doResolveAt(set nameservers, string auth, nameservers=nsset; break; } - else { - LOG< nsspeeds_t; static nsspeeds_t s_nsSpeeds; + struct AuthDomain + { + string d_server; + typedef multi_index_container < + DNSResourceRecord, + indexed_by < + ordered_non_unique< + composite_key< DNSResourceRecord, + member, + member + >, + composite_key_compare > + > + > + > records_t; + records_t d_records; + }; + + + typedef map domainmap_t; + static domainmap_t s_domainmap; + typedef Throttle > throttle_t; static throttle_t s_throttle; struct timeval d_now; @@ -275,6 +297,7 @@ private: int depth, set&beenthere); int doResolve(const string &qname, const QType &qtype, vector&ret, int depth, set& beenthere); bool doOOBResolve(const string &qname, const QType &qtype, vector&ret, int depth, int &res); + domainmap_t::const_iterator getBestAuthZone(string* qname); bool doCNAMECacheCheck(const string &qname, const QType &qtype, vector&ret, int depth, int &res); bool doCacheCheck(const string &qname, const QType &qtype, vector&ret, int depth, int &res); void getBestNSFromCache(const string &qname, set&bestns, int depth, set& beenthere); -- 2.40.0