]> granicus.if.org Git - pdns/commitdiff
Use DNSName for Bind backend
authorAki Tuomi <cmouse@cmouse.fi>
Tue, 16 Jun 2015 04:54:09 +0000 (07:54 +0300)
committermind04 <mind04@monshouwer.org>
Tue, 30 Jun 2015 06:12:49 +0000 (08:12 +0200)
WARNING: DNSSEC broken on this commit.

modules/bindbackend/bindbackend2.cc
modules/bindbackend/bindbackend2.hh
modules/bindbackend/binddnssec.cc

index f0426239ea08a13542e21356fc7cef099a8109bc..6e8afeedd97438a65a9e575ea315c224f8447318 100644 (file)
@@ -138,7 +138,7 @@ bool Bind2Backend::safeGetBBDomainInfo(int id, BB2DomainInfo* bbd)
   return true;
 }
 
-bool Bind2Backend::safeGetBBDomainInfo(const std::string& name, BB2DomainInfo* bbd)
+bool Bind2Backend::safeGetBBDomainInfo(const DNSName& name, BB2DomainInfo* bbd)
 {
   ReadLock rl(&s_state_lock);
   typedef state_t::index<NameTag>::type nameindex_t;
@@ -151,7 +151,7 @@ bool Bind2Backend::safeGetBBDomainInfo(const std::string& name, BB2DomainInfo* b
   return true;
 }
 
-bool Bind2Backend::safeRemoveBBDomainInfo(const std::string& name)
+bool Bind2Backend::safeRemoveBBDomainInfo(const DNSName& name)
 {
   WriteLock rl(&s_state_lock);
   typedef state_t::index<NameTag>::type nameindex_t;
@@ -211,7 +211,7 @@ bool Bind2Backend::startTransaction(const DNSName &qname, int id)
     }
     
     *d_of<<"; Written by PowerDNS, don't edit!"<<endl;
-    *d_of<<"; Zone '"+bbd.d_name+"' retrieved from master "<<endl<<"; at "<<nowTime()<<endl; // insert master info here again
+    *d_of<<"; Zone '"+bbd.d_name.toStringNoDot()+"' retrieved from master "<<endl<<"; at "<<nowTime()<<endl; // insert master info here again
     
     return true;
   }
@@ -254,15 +254,16 @@ bool Bind2Backend::abortTransaction()
 
 bool Bind2Backend::feedRecord(const DNSResourceRecord &r, string *ordername)
 {
-  string qname=r.qname.toString();
+  DNSName qname=r.qname;
 
   BB2DomainInfo bbd;
   safeGetBBDomainInfo(d_transaction_id, &bbd);
 
-  string domain = bbd.d_name;
+  DNSName domain = bbd.d_name;
 
-  if(!stripDomainSuffix(&qname,domain)) 
-    throw DBException("out-of-zone data '"+qname+"' during AXFR of zone '"+domain+"'");
+  qname = qname.makeRelative(domain);
+  if(qname.empty())
+    throw DBException("out-of-zone data '"+r.qname.toStringNoDot()+"' during AXFR of zone '"+domain.toStringNoDot()+"'");
 
   string content=r.content;
 
@@ -271,13 +272,15 @@ bool Bind2Backend::feedRecord(const DNSResourceRecord &r, string *ordername)
   case QType::MX:
   case QType::SRV:
   case QType::CNAME:
-  case QType::NS:
-    if(!stripDomainSuffix(&content, domain))
-      content=stripDot(content)+".";
-    *d_of<<qname<<"\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<content<<endl;
-    break;
+  case QType::NS: {
+      DNSName content2 = DNSName(content).makeRelative(domain);
+      if (content2.empty())
+        content2=content;
+      *d_of<<qname.toString()<<"\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<content2.toString()<<endl;
+      break;
+    }
   default:
-    *d_of<<qname<<"\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<r.content<<endl;
+    *d_of<<qname.toString()<<"\t"<<r.ttl<<"\t"<<r.qtype.getName()<<"\t"<<r.content<<endl;
     break;
   }
   return true;
@@ -385,7 +388,7 @@ void Bind2Backend::getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains)
   }
 }
 
-bool Bind2Backend::getDomainInfo(const string &domain, DomainInfo &di)
+bool Bind2Backend::getDomainInfo(const DNSName& domain, DomainInfo &di)
 {
   BB2DomainInfo bbd;
   if(!safeGetBBDomainInfo(domain, &bbd))
@@ -410,7 +413,7 @@ bool Bind2Backend::getDomainInfo(const string &domain, DomainInfo &di)
   return true;
 }
 
-void Bind2Backend::alsoNotifies(const string &domain, set<string> *ips)
+void Bind2Backend::alsoNotifies(const DNSName& domain, set<string> *ips)
 {
   // combine global list with local list
   for(set<string>::iterator i = this->alsoNotify.begin(); i != this->alsoNotify.end(); i++) {
@@ -453,7 +456,7 @@ void Bind2Backend::parseZoneFile(BB2DomainInfo *bbd)
       else
         hashed="";
     }
-    insertRecord(*bbd, rr.qname.toString(), rr.qtype, rr.content, rr.ttl, hashed);
+    insertRecord(*bbd, rr.qname, rr.qtype, rr.content, rr.ttl, hashed);
   }
   fixupAuth(bbd->d_records.getWRITABLE());
   doEmptyNonTerminals(*bbd, nsec3zone, ns3pr);
@@ -465,18 +468,18 @@ void Bind2Backend::parseZoneFile(BB2DomainInfo *bbd)
 
 /** THIS IS AN INTERNAL FUNCTION! It does moadnsparser prio impedance matching
     Much of the complication is due to the efforts to benefit from std::string reference counting copy on write semantics */
-void Bind2Backend::insertRecord(BB2DomainInfo& bb2, const string &qnameu, const QType &qtype, const string &content, int ttl, const std::string& hashed, bool *auth)
+void Bind2Backend::insertRecord(BB2DomainInfo& bb2, const DNSName &qname, const QType &qtype, const string &content, int ttl, const std::string& hashed, bool *auth)
 {
   Bind2DNSRecord bdr;
   shared_ptr<recordstorage_t> records = bb2.d_records.getWRITABLE();
-  bdr.qname=toLowerCanonic(qnameu);
+  bdr.qname=qname;
 
   if(bb2.d_name.empty())
     ;
-  else if(dottedEndsOn(bdr.qname, bb2.d_name))
-    bdr.qname.resize(max(0, static_cast<int>(bdr.qname.length() - (bb2.d_name.length() + 1))));
+  else if(bdr.qname.isPartOf(bb2.d_name))
+    bdr.qname = bdr.qname.makeRelative(bb2.d_name);
   else {
-    string msg = "Trying to insert non-zone data, name='"+bdr.qname+"', qtype="+qtype.getName()+", zone='"+bb2.d_name+"'";
+    string msg = "Trying to insert non-zone data, name='"+bdr.qname.toStringNoDot()+"', qtype="+qtype.getName()+", zone='"+bb2.d_name.toStringNoDot()+"'";
     if(s_ignore_broken_records) {
         L<<Logger::Warning<<msg<< " ignored" << endl;
         return;
@@ -485,12 +488,12 @@ void Bind2Backend::insertRecord(BB2DomainInfo& bb2, const string &qnameu, const
       throw PDNSException(msg);
   }
 
-  bdr.qname.swap(bdr.qname);
+//  bdr.qname.swap(bdr.qname);
 
   if(!records->empty() && bdr.qname==boost::prior(records->end())->qname)
     bdr.qname=boost::prior(records->end())->qname;
 
-  bdr.qname=labelReverse(bdr.qname);
+  bdr.qname=bdr.qname.labelReverse();
   bdr.qtype=qtype.getCode();
   bdr.content=content; 
   bdr.nsec3hash = hashed;
@@ -532,7 +535,7 @@ string Bind2Backend::DLDomStatusHandler(const vector<string>&parts, Utility::pid
     for(vector<string>::const_iterator i=parts.begin()+1;i<parts.end();++i) {
       BB2DomainInfo bbd;
       if(safeGetBBDomainInfo(*i, &bbd)) {      
-        ret<< *i << ": "<< (bbd.d_loaded ? "": "[rejected]") <<"\t"<<bbd.d_status<<"\n";      
+        ret<< *i << ": "<< (bbd.d_loaded ? "": "[rejected]") <<"\t"<<bbd.d_status<<"\n";
     }
       else
         ret<< *i << " no such domain\n";
@@ -541,7 +544,7 @@ string Bind2Backend::DLDomStatusHandler(const vector<string>&parts, Utility::pid
   else {
     ReadLock rl(&s_state_lock);
     for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) {
-      ret<< i->d_name << ": "<< (i->d_loaded ? "": "[rejected]") <<"\t"<<i->d_status<<"\n";      
+      ret<< i->d_name.toStringNoDot() << ": "<< (i->d_loaded ? "": "[rejected]") <<"\t"<<i->d_status<<"\n";
     }
   }
 
@@ -557,7 +560,7 @@ string Bind2Backend::DLListRejectsHandler(const vector<string>&parts, Utility::p
   ReadLock rl(&s_state_lock);
   for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) {
     if(!i->d_loaded)
-      ret<<i->d_name<<"\t"<<i->d_status<<endl;
+      ret<<i->d_name.toStringNoDot()<<"\t"<<i->d_status<<endl;
   }
   return ret.str();
 }
@@ -567,7 +570,7 @@ string Bind2Backend::DLAddDomainHandler(const vector<string>&parts, Utility::pid
   if(parts.size() < 3)
     return "ERROR: Domain name and zone filename are required";
 
-  string domainname = toLowerCanonic(parts[1]);
+  DNSName domainname(parts[1]);
   const string &filename = parts[2];
   BB2DomainInfo bbd;
   if(safeGetBBDomainInfo(domainname, &bbd))
@@ -582,8 +585,8 @@ string Bind2Backend::DLAddDomainHandler(const vector<string>&parts, Utility::pid
 
   safePutBBDomainInfo(bbd);
 
-  L<<Logger::Warning<<"Zone "<<domainname<< " loaded"<<endl;
-  return "Loaded zone " + domainname + " from " + filename;
+  L<<Logger::Warning<<"Zone "<<domainname.toStringNoDot()<< " loaded"<<endl;
+  return "Loaded zone " + domainname.toStringNoDot() + " from " + filename;
 }
 
 Bind2Backend::Bind2Backend(const string &suffix, bool loadZones)
@@ -649,7 +652,7 @@ void Bind2Backend::reload()
 void Bind2Backend::fixupAuth(shared_ptr<recordstorage_t> records)
 {
   pair<recordstorage_t::const_iterator, recordstorage_t::const_iterator> range;
-  string sqname;
+  DNSName sqname;
   
   recordstorage_t nssets;
   BOOST_FOREACH(const Bind2DNSRecord& bdr, *records) {
@@ -663,15 +666,15 @@ void Bind2Backend::fixupAuth(shared_ptr<recordstorage_t> records)
     if(bdr.qtype == QType::DS) // as are delegation signer records
       continue;
 
-    sqname = labelReverse(bdr.qname);
+    sqname = bdr.qname.labelReverse();
     
     do {
-      if(sqname.empty()) // this is auth of course!
+      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(chopOff(sqname));
+    } while(sqname.chopOff());
   }
 }
 
@@ -679,36 +682,37 @@ void Bind2Backend::doEmptyNonTerminals(BB2DomainInfo& bbd, bool nsec3zone, NSEC3
 {
   shared_ptr<const recordstorage_t> records = bbd.d_records.get();
   bool auth, doent=true;
-  set<string> qnames;
-  map<string, bool> nonterm;
-  string shorter, hashed;
+  set<DNSName> qnames;
+  map<DNSName, bool> nonterm;
+  DNSName shorter;
+  string hashed;
 
   uint32_t maxent = ::arg().asNum("max-ent-entries");
 
-  BOOST_FOREACH(const Bind2DNSRecord& bdr, *records)
-    qnames.insert(labelReverse(bdr.qname));
+  for(const auto& bdr : *records)
+    qnames.insert(bdr.qname.labelReverse());
 
-  BOOST_FOREACH(const Bind2DNSRecord& bdr, *records) {
-    shorter=labelReverse(bdr.qname);
+  for(const auto& bdr : *records) {
+    shorter=bdr.qname.labelReverse();
 
     if (!bdr.auth && bdr.qtype == QType::NS)
       auth=(!nsec3zone || !ns3pr.d_flags);
     else
       auth=bdr.auth;
 
-    while(chopOff(shorter))
+    while(shorter.chopOff())
     {
       if(!qnames.count(shorter))
       {
         if(!(maxent))
         {
-          L<<Logger::Error<<"Zone '"<<bbd.d_name<<"' has too many empty non terminals."<<endl;
+          L<<Logger::Error<<"Zone '"<<bbd.d_name.toStringNoDot()<<"' has too many empty non terminals."<<endl;
           doent=false;
           break;
         }
 
         if (!nonterm.count(shorter)) {
-          nonterm.insert(pair<string, bool>(shorter, auth));
+          nonterm.insert(pair<DNSName, bool>(shorter, auth));
           --maxent;
         } else if (auth)
           nonterm[shorter]=true;
@@ -722,13 +726,12 @@ void Bind2Backend::doEmptyNonTerminals(BB2DomainInfo& bbd, bool nsec3zone, NSEC3
   rr.qtype="#0";
   rr.content="";
   rr.ttl=0;
-  pair<string, bool> nt;
-  BOOST_FOREACH(nt, nonterm)
+  for(auto &nt: nonterm)
   {
-    rr.qname=nt.first+"."+bbd.d_name+".";
+    rr.qname=nt.first+bbd.d_name;
     if(nsec3zone)
-      hashed=toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, rr.qname));
-    insertRecord(bbd, rr.qname.toString(), rr.qtype, rr.content, rr.ttl, hashed, &nt.second);
+      hashed=toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, rr.qname.toString()));
+    insertRecord(bbd, rr.qname, rr.qtype, rr.content, rr.ttl, hashed, &nt.second);
   }
 }
 
@@ -754,7 +757,7 @@ void Bind2Backend::loadConfig(string* status)
 
     L<<Logger::Warning<<d_logprefix<<" Parsing "<<domains.size()<<" domain(s), will report when done"<<endl;
     
-    set<string> oldnames, newnames;
+    set<DNSName> oldnames, newnames;
     {
       ReadLock rl(&s_state_lock);
       BOOST_FOREACH(const BB2DomainInfo& bbd, s_state) {
@@ -780,7 +783,7 @@ void Bind2Backend::loadConfig(string* status)
         ++i) 
       {
         if(i->type!="master" && i->type!="slave") {
-          L<<Logger::Warning<<d_logprefix<<" Warning! Skipping '"<<i->type<<"' zone '"<<i->name<<"'"<<endl;
+          L<<Logger::Warning<<d_logprefix<<" Warning! Skipping '"<<i->type<<"' zone '"<<i->name.toStringNoDot()<<"'"<<endl;
           continue;
         }
 
@@ -794,7 +797,7 @@ void Bind2Backend::loadConfig(string* status)
         }
         
         // overwrite what we knew about the domain
-        bbd.d_name=toLowerCanonic(i->name);
+        bbd.d_name=i->name;
         bool filenameChanged = (bbd.d_filename!=i->filename);
         bbd.d_filename=i->filename;
         bbd.d_masters=i->masters;
@@ -802,14 +805,14 @@ void Bind2Backend::loadConfig(string* status)
 
         newnames.insert(bbd.d_name);
         if(filenameChanged || !bbd.d_loaded || !bbd.current()) {
-          L<<Logger::Info<<d_logprefix<<" parsing '"<<i->name<<"' from file '"<<i->filename<<"'"<<endl;
+          L<<Logger::Info<<d_logprefix<<" parsing '"<<i->name.toStringNoDot()<<"' from file '"<<i->filename<<"'"<<endl;
 
           try {
             parseZoneFile(&bbd);
           }
           catch(PDNSException &ae) {
             ostringstream msg;
-            msg<<" error at "+nowTime()+" parsing '"<<i->name<<"' from file '"<<i->filename<<"': "<<ae.reason;
+            msg<<" error at "+nowTime()+" parsing '"<<i->name.toStringNoDot()<<"' from file '"<<i->filename<<"': "<<ae.reason;
 
             if(status)
               *status+=msg.str();
@@ -820,7 +823,7 @@ void Bind2Backend::loadConfig(string* status)
           }
           catch(std::exception &ae) {
             ostringstream msg;
-            msg<<" error at "+nowTime()+" parsing '"<<i->name<<"' from file '"<<i->filename<<"': "<<ae.what();
+            msg<<" error at "+nowTime()+" parsing '"<<i->name.toStringNoDot()<<"' from file '"<<i->filename<<"': "<<ae.what();
 
             if(status)
               *status+=msg.str();
@@ -832,12 +835,12 @@ void Bind2Backend::loadConfig(string* status)
          
         }
       }
-    vector<string> diff;
+    vector<DNSName> diff;
 
     set_difference(oldnames.begin(), oldnames.end(), newnames.begin(), newnames.end(), back_inserter(diff));
     unsigned int remdomains=diff.size();
     
-    BOOST_FOREACH(const std::string& name, diff) {
+    for(const DNSName& name: diff) {
       safeRemoveBBDomainInfo(name);
     }
 
@@ -864,43 +867,42 @@ void Bind2Backend::queueReloadAndStore(unsigned int id)
     parseZoneFile(&bbold);
     bbold.d_checknow=false;
     safePutBBDomainInfo(bbold);
-    L<<Logger::Warning<<"Zone '"<<bbold.d_name<<"' ("<<bbold.d_filename<<") reloaded"<<endl;
+    L<<Logger::Warning<<"Zone '"<<bbold.d_name.toStringNoDot()<<"' ("<<bbold.d_filename<<") reloaded"<<endl;
   }
   catch(PDNSException &ae) {
     ostringstream msg;
-    msg<<" error at "+nowTime()+" parsing '"<<bbold.d_name<<"' from file '"<<bbold.d_filename<<"': "<<ae.reason;
+    msg<<" error at "+nowTime()+" parsing '"<<bbold.d_name.toStringNoDot()<<"' from file '"<<bbold.d_filename<<"': "<<ae.reason;
     bbold.d_status=msg.str();
     safePutBBDomainInfo(bbold);
   }
   catch(std::exception &ae) {
     ostringstream msg;
-    msg<<" error at "+nowTime()+" parsing '"<<bbold.d_name<<"' from file '"<<bbold.d_filename<<"': "<<ae.what();
+    msg<<" error at "+nowTime()+" parsing '"<<bbold.d_name.toStringNoDot()<<"' from file '"<<bbold.d_filename<<"': "<<ae.what();
     bbold.d_status=msg.str();
     safePutBBDomainInfo(bbold);
   }
 }
 
-bool Bind2Backend::findBeforeAndAfterUnhashed(BB2DomainInfo& bbd, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
+bool Bind2Backend::findBeforeAndAfterUnhashed(BB2DomainInfo& bbd, const DNSName& qname, DNSName& unhashed, string& before, string& after)
 {
-  string domain=qname.toString();
   shared_ptr<const recordstorage_t> records = bbd.d_records.get();
-  recordstorage_t::const_iterator iter = records->upper_bound(domain);
+  recordstorage_t::const_iterator iter = records->upper_bound(qname);
 
   if (before.empty()){
     //cout<<"starting before for: '"<<domain<<"'"<<endl;
-    iter = records->upper_bound(domain);
+    iter = records->upper_bound(qname);
 
-    while(iter == records->end() || (iter->qname) > domain || (!(iter->auth) && (!(iter->qtype == QType::NS))) || (!(iter->qtype)))
+    while(iter == records->end() || (qname < iter->qname) || (!(iter->auth) && (!(iter->qtype == QType::NS))) || (!(iter->qtype)))
       iter--;
 
-    before=iter->qname;
+    before=iter->qname.toString(" ",false);
   }
   else {
-    before=domain;
+    before=qname.toString(" ",false);
   }
 
   //cerr<<"Now after"<<endl;
-  iter = records->upper_bound(domain);
+  iter = records->upper_bound(qname);
 
   if(iter == records->end()) {
     //cerr<<"\tFound the end, begin storage: '"<<bbd.d_records->begin()->qname<<"', '"<<bbd.d_name<<"'"<<endl;
@@ -918,20 +920,20 @@ bool Bind2Backend::findBeforeAndAfterUnhashed(BB2DomainInfo& bbd, const DNSName&
         break;
       }
     }
-    after = (iter)->qname;
+    after = (iter)->qname.toString(" ",false);
   }
 
-  //cerr<<"Before: '"<<before<<"', after: '"<<after<<"'\n";
+  cerr<<"Before: '"<<before<<"', after: '"<<after<<"'\n";
   return true;
 }
 
-bool Bind2Backend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after)
+bool Bind2Backend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, DNSName& unhashed, std::string& before, std::string& after)
 {
   BB2DomainInfo bbd;
   safeGetBBDomainInfo(id, &bbd);
 
   NSEC3PARAMRecordContent ns3pr;
-  string auth=bbd.d_name;
+  DNSName auth=bbd.d_name;
     
   bool nsec3zone;
   if (d_hybrid) {
@@ -941,9 +943,9 @@ bool Bind2Backend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string
     nsec3zone=getNSEC3PARAM(auth, &ns3pr);
 
   if(!nsec3zone) {
+    DNSName dqname(qname);
     //cerr<<"in bind2backend::getBeforeAndAfterAbsolute: no nsec3 for "<<auth<<endl;
-    return findBeforeAndAfterUnhashed(bbd, qname, unhashed, before, after);
-  
+    return findBeforeAndAfterUnhashed(bbd, dqname, unhashed, before, after);
   }
   else {
     string lqname = toLower(qname);
@@ -989,7 +991,7 @@ bool Bind2Backend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string
       }
 
       before = iter->nsec3hash;
-      unhashed = dotConcat(labelReverse(iter->qname), auth);
+      unhashed = iter->qname.labelReverse() + auth;
       // cerr<<"before: "<<(iter->nsec3hash)<<"/"<<(iter->qname)<<endl;
     }
     else {
@@ -1024,21 +1026,23 @@ bool Bind2Backend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string
     //cerr<<"Before: '"<<before<<"', after: '"<<after<<"'\n";
     return true;
   }
+  return false;
 }
 
 void Bind2Backend::lookup(const QType &qtype, const DNSName &qname, DNSPacket *pkt_p, int zoneId )
 {
   d_handle.reset();
-  string domain=qname.toString();
+  DNSName domain(qname);
 
   static bool mustlog=::arg().mustDo("query-logging");
   if(mustlog) 
-    L<<Logger::Warning<<"Lookup for '"<<qtype.getName()<<"' of '"<<domain<<"'"<<endl;
+    L<<Logger::Warning<<"Lookup for '"<<qtype.getName()<<"' of '"<<domain.toStringNoDot()<<"'"<<endl;
   bool found=false;
   BB2DomainInfo bbd;
+
   do {
     found = safeGetBBDomainInfo(domain, &bbd);
-  } while ((!found || (zoneId != (int)bbd.d_id && zoneId != -1)) && chopOff(domain));
+  } while ((!found || (zoneId != (int)bbd.d_id && zoneId != -1)) && domain.chopOff());
 
   if(!found) {
     if(mustlog)
@@ -1048,31 +1052,31 @@ void Bind2Backend::lookup(const QType &qtype, const DNSName &qname, DNSPacket *p
   }
 
   if(mustlog)
-    L<<Logger::Warning<<"Found a zone '"<<domain<<"' (with id " << bbd.d_id<<") that might contain data "<<endl;
+    L<<Logger::Warning<<"Found a zone '"<<domain.toStringNoDot()<<"' (with id " << bbd.d_id<<") that might contain data "<<endl;
     
   d_handle.id=bbd.d_id;
   
   DLOG(L<<"Bind2Backend constructing handle for search for "<<qtype.getName()<<" for "<<
-       qname<<endl);
+       qname.toStringNoDot()<<endl);
   
   if(domain.empty())
     d_handle.qname=qname;
-  else if(strcasecmp(qname.c_str(),domain.c_str()))
-    d_handle.qname=qname.substr(0,qname.size()-domain.length()-1); // strip domain name
+  else if(qname.isPartOf(domain))
+    d_handle.qname=qname.makeRelative(domain); // strip domain name
 
   d_handle.qtype=qtype;
-  d_handle.domain=qname.substr(qname.size()-domain.length());
+  d_handle.domain=domain;
 
   if(!bbd.d_loaded) {
     d_handle.reset();
-    throw DBException("Zone for '"+bbd.d_name+"' in '"+bbd.d_filename+"' temporarily not available (file missing, or master dead)"); // fsck
+    throw DBException("Zone for '"+bbd.d_name.toStringNoDot()+"' in '"+bbd.d_filename+"' temporarily not available (file missing, or master dead)"); // fsck
   }
     
   if(!bbd.current()) {
-    L<<Logger::Warning<<"Zone '"<<bbd.d_name<<"' ("<<bbd.d_filename<<") needs reloading"<<endl;
+    L<<Logger::Warning<<"Zone '"<<bbd.d_name.toStringNoDot()<<"' ("<<bbd.d_filename<<") needs reloading"<<endl;
     queueReloadAndStore(bbd.d_id);
     if (!safeGetBBDomainInfo(domain, &bbd))
-      throw DBException("Zone '"+bbd.d_name+"' ("+bbd.d_filename+") gone after reload"); // if we don't throw here, we crash for some reason
+      throw DBException("Zone '"+bbd.d_name.toStringNoDot()+"' ("+bbd.d_filename+") gone after reload"); // if we don't throw here, we crash for some reason
   }
 
   d_handle.d_records = bbd.d_records.get();
@@ -1082,10 +1086,7 @@ void Bind2Backend::lookup(const QType &qtype, const DNSName &qname, DNSPacket *p
 
   pair<recordstorage_t::const_iterator, recordstorage_t::const_iterator> range;
 
-  string lname=labelReverse(toLower(d_handle.qname));
-  //cout<<"starting equal range for: '"<<d_handle.qname<<"', search is for: '"<<lname<<"'"<<endl;
-  range = d_handle.d_records->equal_range(lname);
+  range = d_handle.d_records->equal_range(d_handle.qname.labelReverse());
   //cout<<"End equal range"<<endl;
   d_handle.mustlog = mustlog;
   
@@ -1149,14 +1150,14 @@ void Bind2Backend::handle::reset()
 bool Bind2Backend::handle::get_normal(DNSResourceRecord &r)
 {
   DLOG(L << "Bind2Backend get() was called for "<<qtype.getName() << " record for '"<<
-       qname<<"' - "<<d_records->size()<<" available in total!"<<endl);
+       qname.toStringNoDot()<<"' - "<<d_records->size()<<" available in total!"<<endl);
   
   if(d_iter==d_end_iter) {
     return false;
   }
 
   while(d_iter!=d_end_iter && !(qtype.getCode()==QType::ANY || (d_iter)->qtype==qtype.getCode())) {
-    DLOG(L<<Logger::Warning<<"Skipped "<<qname<<"/"<<QType(d_iter->qtype).getName()<<": '"<<d_iter->content<<"'"<<endl);
+    DLOG(L<<Logger::Warning<<"Skipped "<<qname.toStringNoDot()<<"/"<<QType(d_iter->qtype).getName()<<": '"<<d_iter->content<<"'"<<endl);
     d_iter++;
   }
   if(d_iter==d_end_iter) {
@@ -1164,7 +1165,7 @@ bool Bind2Backend::handle::get_normal(DNSResourceRecord &r)
   }
   DLOG(L << "Bind2Backend get() returning a rr with a "<<QType(d_iter->qtype).getCode()<<endl);
 
-  r.qname=qname.empty() ? domain : (qname+"."+domain);
+  r.qname=qname.empty() ? domain : (qname+domain);
   r.domain_id=id;
   r.content=(d_iter)->content;
   //  r.domain_id=(d_iter)->domain_id;
@@ -1172,7 +1173,7 @@ bool Bind2Backend::handle::get_normal(DNSResourceRecord &r)
   r.ttl=(d_iter)->ttl;
 
   //if(!d_iter->auth && r.qtype.getCode() != QType::A && r.qtype.getCode()!=QType::AAAA && r.qtype.getCode() != QType::NS)
-  //  cerr<<"Warning! Unauth response for qtype "<< r.qtype.getName() << " for '"<<r.qname<<"'"<<endl;
+  //  cerr<<"Warning! Unauth response for qtype "<< r.qtype.getName() << " for '"<<r.qname.toStringNoDot()<<"'"<<endl;
   r.auth = d_iter->auth;
 
   d_iter++;
@@ -1180,7 +1181,7 @@ bool Bind2Backend::handle::get_normal(DNSResourceRecord &r)
   return true;
 }
 
-bool Bind2Backend::list(const string &target, int id, bool include_disabled)
+bool Bind2Backend::list(const DNSName& target, int id, bool include_disabled)
 {
   BB2DomainInfo bbd;
   
@@ -1202,7 +1203,7 @@ bool Bind2Backend::list(const string &target, int id, bool include_disabled)
 bool Bind2Backend::handle::get_list(DNSResourceRecord &r)
 {
   if(d_qname_iter!=d_qname_end) {
-    r.qname=d_qname_iter->qname.empty() ? domain : (labelReverse(d_qname_iter->qname)+"."+domain);
+    r.qname=d_qname_iter->qname.empty() ? domain : (d_qname_iter->qname.labelReverse()+domain);
     r.domain_id=id;
     r.content=(d_qname_iter)->content;
     r.qtype=(d_qname_iter)->qtype;
@@ -1214,7 +1215,7 @@ bool Bind2Backend::handle::get_list(DNSResourceRecord &r)
   return false;
 }
 
-bool Bind2Backend::isMaster(const string &name, const string &ip)
+bool Bind2Backend::isMaster(const DNSName& name, const string &ip)
 {
   BB2DomainInfo bbd;
   if(!safeGetBBDomainInfo(name, &bbd))
@@ -1227,7 +1228,7 @@ bool Bind2Backend::isMaster(const string &name, const string &ip)
   return false;
 }
 
-bool Bind2Backend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
+bool Bind2Backend::superMasterBackend(const string &ip, const DNSName& domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
 {
   // Check whether we have a configfile available.
   if (getArg("supermaster-config").empty())
@@ -1263,7 +1264,7 @@ bool Bind2Backend::superMasterBackend(const string &ip, const string &domain, co
   return true;
 }
 
-BB2DomainInfo Bind2Backend::createDomainEntry(const string &domain, const string &filename)
+BB2DomainInfo Bind2Backend::createDomainEntry(const DNSName& domain, const string &filename)
 {
   int newid=1;
   {   // Find a free zone id nr.  
@@ -1282,12 +1283,12 @@ BB2DomainInfo Bind2Backend::createDomainEntry(const string &domain, const string
   return bbd;
 }
 
-bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account)
+bool Bind2Backend::createSlaveDomain(const string &ip, const DNSName& domain, const string &nameserver, const string &account)
 {
-  string filename = getArg("supermaster-destdir")+'/'+domain;
+  string filename = getArg("supermaster-destdir")+'/'+domain.toStringNoDot();
   
   L << Logger::Warning << d_logprefix
-    << " Writing bind config zone statement for superslave zone '" << domain
+    << " Writing bind config zone statement for superslave zone '" << domain.toStringNoDot()
     << "' from supermaster " << ip << endl;
 
   {
@@ -1300,8 +1301,8 @@ bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, con
     }
     
     c_of << endl;
-    c_of << "# Superslave zone " << domain << " (added: " << nowTime() << ") (account: " << account << ')' << endl;
-    c_of << "zone \"" << domain << "\" {" << endl;
+    c_of << "# Superslave zone " << domain.toStringNoDot() << " (added: " << nowTime() << ") (account: " << account << ')' << endl;
+    c_of << "zone \"" << domain.toStringNoDot() << "\" {" << endl;
     c_of << "\ttype slave;" << endl;
     c_of << "\tfile \"" << filename << "\";" << endl;
     c_of << "\tmasters { " << ip << "; };" << endl;
@@ -1309,7 +1310,7 @@ bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, con
     c_of.close();
   }
 
-  BB2DomainInfo bbd = createDomainEntry(toLowerCanonic(domain), filename);
+  BB2DomainInfo bbd = createDomainEntry(domain, filename);
   bbd.d_masters.push_back(ip);
   safePutBBDomainInfo(bbd);
   return true;
index 7b1db1f5f4bdf0581e5c08e70655aa64de5527cb..98765b1e7855691eb292fed30354a8d082012a6b 100644 (file)
@@ -52,7 +52,7 @@ using namespace ::boost::multi_index;
 */
 struct Bind2DNSRecord
 {
-  string qname;
+  DNSName qname;
   string content;
   string nsec3hash;
   uint32_t ttl;
@@ -62,7 +62,7 @@ struct Bind2DNSRecord
   {
     if(qname < rhs.qname)
       return true;
-    if(qname > rhs.qname)
+    if(rhs.qname < qname)
       return false;
     if(qtype==QType::SOA && rhs.qtype!=QType::SOA)
       return true;
@@ -74,15 +74,13 @@ struct Bind2DNSCompare : std::less<Bind2DNSRecord>
 { 
     using std::less<Bind2DNSRecord>::operator(); 
     // use operator< 
-    bool operator() (const std::string& a, const Bind2DNSRecord& b) const 
-    {return a < b.qname;} 
-    bool operator() (const Bind2DNSRecord& a, const std::string& b) const 
-    {return a.qname < b;} 
+    bool operator() (const DNSName& a, const Bind2DNSRecord& b) const
+    {return a < b.qname;}
+    bool operator() (const Bind2DNSRecord& a, const DNSName& b) const
+    {return a.qname < b;}
     bool operator() (const Bind2DNSRecord& a, const Bind2DNSRecord& b) const
-    {
-      return a < b;
-    }
-}; 
+    {return a.qname < b.qname;}
+};
 
 struct HashedTag{};
 
@@ -157,7 +155,7 @@ public:
   string d_status; //!< message describing status of a domain, for human consumption
   mutable bool d_checknow; //!< if this domain has been flagged for a check
   time_t d_ctime;  //!< last known ctime of the file on disk
-  string d_name;   //!< actual name of the domain
+  DNSName d_name;   //!< actual name of the domain
   string d_filename; //!< full absolute filename of the zone on disk
   unsigned int d_id;  //!< internal id of the domain
   time_t d_lastcheck; //!< last time domain was checked for freshness
@@ -188,7 +186,7 @@ public:
   bool getDomainInfo(const DNSName &domain, DomainInfo &di);
   time_t getCtime(const string &fname);
    // DNSSEC
-  virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after);
+  virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const string& qname, DNSName& unhashed, string& before, string& after);
   void lookup(const QType &, const DNSName &qdomain, DNSPacket *p=0, int zoneId=-1);
   bool list(const DNSName &target, int id, bool include_disabled=false);
   bool get(DNSResourceRecord &);
@@ -214,7 +212,7 @@ public:
   virtual int addDomainKey(const DNSName& name, const KeyData& key);
   virtual bool activateDomainKey(const DNSName& name, unsigned int id);
   virtual bool deactivateDomainKey(const DNSName& name, unsigned int id);
-  virtual bool getTSIGKey(const DNSName& name, string* algorithm, string* content);
+  virtual bool getTSIGKey(const DNSName& name, DNSName* algorithm, string* content);
   virtual bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content);
   virtual bool deleteTSIGKey(const DNSName& name);
   virtual bool getTSIGKeys(std::vector< struct TSIGKey > &keys);
@@ -223,13 +221,13 @@ public:
 
   typedef multi_index_container < BB2DomainInfo , 
                                  indexed_by < ordered_unique<member<BB2DomainInfo, unsigned int, &BB2DomainInfo::d_id> >,
-                                              ordered_unique<tag<NameTag>, member<BB2DomainInfo, std::string, &BB2DomainInfo::d_name>, CIStringCompare >
+                                              ordered_unique<tag<NameTag>, member<BB2DomainInfo, DNSName, &BB2DomainInfo::d_name> >
                                               > > state_t;
   static state_t s_state;
   static pthread_rwlock_t s_state_lock;
 
   void parseZoneFile(BB2DomainInfo *bbd);
-  void insertRecord(BB2DomainInfo& bbd, const string &qname, const QType &qtype, const string &content, int ttl, const std::string& hashed=string(), bool *auth=0);
+  void insertRecord(BB2DomainInfo& bbd, const DNSName& qname, const QType &qtype, const string &content, int ttl, const std::string& hashed=string(), bool *auth=0);
   void rediscover(string *status=0);
 
   bool isMaster(const DNSName &name, const string &ip);
@@ -246,12 +244,12 @@ private:
   void release(SSqlStatement**);
   static bool safeGetBBDomainInfo(int id, BB2DomainInfo* bbd);
   static void safePutBBDomainInfo(const BB2DomainInfo& bbd);
-  static bool safeGetBBDomainInfo(const std::string& name, BB2DomainInfo* bbd);
-  static bool safeRemoveBBDomainInfo(const std::string& name);
+  static bool safeGetBBDomainInfo(const DNSName& name, BB2DomainInfo* bbd);
+  static bool safeRemoveBBDomainInfo(const DNSName& name);
   bool GetBBDomainInfo(int id, BB2DomainInfo** bbd);
   shared_ptr<SSQLite3> d_dnssecdb;
   bool d_hybrid;
-  bool getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p);
+  bool getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p);
   class handle
   {
   public:
@@ -268,8 +266,8 @@ private:
     bool d_list;
     int id;
 
-    string qname;
-    string domain;
+    DNSName qname;
+    DNSName domain;
     QType qtype;
     bool mustlog;
 
@@ -289,7 +287,7 @@ private:
 
   set<string> alsoNotify; //!< this is used to store the also-notify list of interested peers.
 
-  BB2DomainInfo createDomainEntry(const string &domain, const string &filename); //!< does not insert in s_state
+  BB2DomainInfo createDomainEntry(const DNSName& domain, const string &filename); //!< does not insert in s_state
 
   int d_transaction_id;
   string d_transaction_tmpname;
@@ -298,7 +296,7 @@ private:
   handle d_handle;
 
   void queueReloadAndStore(unsigned int id);
-  bool findBeforeAndAfterUnhashed(BB2DomainInfo& bbd, const std::string& qname, std::string& unhashed, std::string& before, std::string& after);
+  bool findBeforeAndAfterUnhashed(BB2DomainInfo& bbd, const DNSName& qname, DNSName& unhashed, string& before, string& after);
   void reload();
   static string DLDomStatusHandler(const vector<string>&parts, Utility::pid_t ppid);
   static string DLListRejectsHandler(const vector<string>&parts, Utility::pid_t ppid);
index a4f717250812f7e515bf8fcaf0d81ab9b1dcb8bd..6cd60476d3c88e5866d7fd900350f3550e7e3ddb 100644 (file)
@@ -38,37 +38,37 @@ void Bind2Backend::setupDNSSEC()
 bool Bind2Backend::doesDNSSEC()
 { return d_hybrid; }
 
-bool Bind2Backend::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p)
+bool Bind2Backend::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p)
 { return false; }
 
-bool Bind2Backend::getAllDomainMetadata(const string& name, std::map<std::string, std::vector<std::string> >& meta)
+bool Bind2Backend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta)
 { return false; }
 
-bool Bind2Backend::getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta)
+bool Bind2Backend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta)
 { return false; }
 
-bool Bind2Backend::setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta)
+bool Bind2Backend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta)
 { return false; }
 
-bool Bind2Backend::getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys)
+bool Bind2Backend::getDomainKeys(const DNSName& name, unsigned int kind, std::vector<KeyData>& keys)
 { return false; }
 
-bool Bind2Backend::removeDomainKey(const string& name, unsigned int id)
+bool Bind2Backend::removeDomainKey(const DNSName& name, unsigned int id)
 { return false; }
 
-int Bind2Backend::addDomainKey(const string& name, const KeyData& key)
+int Bind2Backend::addDomainKey(const DNSName& name, const KeyData& key)
 { return -1; }
 
-bool Bind2Backend::activateDomainKey(const string& name, unsigned int id)
+bool Bind2Backend::activateDomainKey(const DNSName& name, unsigned int id)
 { return false; }
 
-bool Bind2Backend::deactivateDomainKey(const string& name, unsigned int id)
+bool Bind2Backend::deactivateDomainKey(const DNSName& name, unsigned int id)
 { return false; }
 
-bool Bind2Backend::getTSIGKey(const string& name, string* algorithm, string* content)
+bool Bind2Backend::getTSIGKey(const DNSName& name, DNSName* algorithm, string* content)
 { return false; }
 
-bool Bind2Backend::setTSIGKey(const string& name, const string& algorithm, const string& content)
+bool Bind2Backend::setTSIGKey(const DNSName& name, const string& algorithm, const string& content)
 { return false; }
 
 bool Bind2Backend::deleteTSIGKey(const string& name)
@@ -144,7 +144,7 @@ bool Bind2Backend::doesDNSSEC()
   return d_dnssecdb || d_hybrid;
 }
 
-bool Bind2Backend::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p)
+bool Bind2Backend::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p)
 {
   if(!d_dnssecdb || d_hybrid)
     return false;
@@ -167,7 +167,7 @@ bool Bind2Backend::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordConte
   return true;
 }
 
-bool Bind2Backend::getAllDomainMetadata(const string& name, std::map<std::string, std::vector<std::string> >& meta)
+bool Bind2Backend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta)
 {
   if(!d_dnssecdb || d_hybrid)
     return false;
@@ -193,7 +193,7 @@ bool Bind2Backend::getAllDomainMetadata(const string& name, std::map<std::string
   return true;
 }
 
-bool Bind2Backend::getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta)
+bool Bind2Backend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta)
 {
   if(!d_dnssecdb || d_hybrid)
     return false;
@@ -220,7 +220,7 @@ bool Bind2Backend::getDomainMetadata(const string& name, const std::string& kind
   return true;
 }
 
-bool Bind2Backend::setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta)
+bool Bind2Backend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta)
 {
   if(!d_dnssecdb || d_hybrid)
     return false;
@@ -249,7 +249,7 @@ bool Bind2Backend::setDomainMetadata(const string& name, const std::string& kind
 
 }
 
-bool Bind2Backend::getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys)
+bool Bind2Backend::getDomainKeys(const DNSName& name, unsigned int kind, std::vector<KeyData>& keys)
 {
   // cerr<<"Asked to get keys for zone '"<<name<<"'\n";
   if(!d_dnssecdb || d_hybrid)
@@ -277,7 +277,7 @@ bool Bind2Backend::getDomainKeys(const string& name, unsigned int kind, std::vec
   return true;
 }
 
-bool Bind2Backend::removeDomainKey(const string& name, unsigned int id)
+bool Bind2Backend::removeDomainKey(const DNSName& name, unsigned int id)
 {
   if(!d_dnssecdb || d_hybrid)
     return false;
@@ -298,7 +298,7 @@ bool Bind2Backend::removeDomainKey(const string& name, unsigned int id)
   return true;
 }
 
-int Bind2Backend::addDomainKey(const string& name, const KeyData& key)
+int Bind2Backend::addDomainKey(const DNSName& name, const KeyData& key)
 {
   if(!d_dnssecdb || d_hybrid)
     return -1;
@@ -321,7 +321,7 @@ int Bind2Backend::addDomainKey(const string& name, const KeyData& key)
   return true;
 }
 
-bool Bind2Backend::activateDomainKey(const string& name, unsigned int id)
+bool Bind2Backend::activateDomainKey(const DNSName& name, unsigned int id)
 {
   // cerr<<"Asked to activate key "<<id<<" inzone '"<<name<<"'\n";
   if(!d_dnssecdb || d_hybrid)
@@ -341,7 +341,7 @@ bool Bind2Backend::activateDomainKey(const string& name, unsigned int id)
   return true;
 }
 
-bool Bind2Backend::deactivateDomainKey(const string& name, unsigned int id)
+bool Bind2Backend::deactivateDomainKey(const DNSName& name, unsigned int id)
 {
   // cerr<<"Asked to deactivate key "<<id<<" inzone '"<<name<<"'\n";
   if(!d_dnssecdb || d_hybrid)
@@ -361,7 +361,7 @@ bool Bind2Backend::deactivateDomainKey(const string& name, unsigned int id)
   return true;
 }
 
-bool Bind2Backend::getTSIGKey(const string& name, string* algorithm, string* content)
+bool Bind2Backend::getTSIGKey(const DNSName& name, DNSName* algorithm, string* content)
 {
   if(!d_dnssecdb || d_hybrid)
     return false;
@@ -374,7 +374,7 @@ bool Bind2Backend::getTSIGKey(const string& name, string* algorithm, string* con
     content->clear();
     while(d_getTSIGKeyQuery_stmt->hasNextRow()) {
       d_getTSIGKeyQuery_stmt->nextRow(row);
-      if(row.size() >= 2 && (algorithm->empty() || pdns_iequals(*algorithm, row[0]))) {
+      if(row.size() >= 2 && (algorithm->empty() || *algorithm == DNSName(row[0]))) {
         *algorithm = row[0];
         *content = row[1];
       }
@@ -388,7 +388,7 @@ bool Bind2Backend::getTSIGKey(const string& name, string* algorithm, string* con
   return !content->empty();
 }
 
-bool Bind2Backend::setTSIGKey(const string& name, const string& algorithm, const string& content)
+bool Bind2Backend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content)
 {
   if(!d_dnssecdb || d_hybrid)
     return false;
@@ -408,7 +408,7 @@ bool Bind2Backend::setTSIGKey(const string& name, const string& algorithm, const
   return true;
 }
 
-bool Bind2Backend::deleteTSIGKey(const string& name) 
+bool Bind2Backend::deleteTSIGKey(const DNSName& name)
 {
   if(!d_dnssecdb || d_hybrid)
     return false;