]> granicus.if.org Git - pdns/commitdiff
partial commit for backup purposes: bind2backend is getting coooool!
authorBert Hubert <bert.hubert@netherlabs.nl>
Mon, 14 Feb 2005 13:40:31 +0000 (13:40 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Mon, 14 Feb 2005 13:40:31 +0000 (13:40 +0000)
non-functional now though

git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@320 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/backends/bind/bindbackend2.cc
pdns/backends/bind/bindbackend2.hh
pdns/qtype.cc
pdns/qtype.hh

index 9e883ca49c3949a36a5fc20a3acf25dca5c35820..0d248808aa4571f990162524d250572766e2a0f6 100644 (file)
@@ -292,18 +292,31 @@ static string canonic(string ret)
   return ret;
 }
 
+
+set<shared_ptr<string> > contents;
 map<unsigned int, BB2DomainInfo*> nbbds;
 /** This function adds a record to a domain with a certain id. */
 void Bind2Backend::insert(int id, const string &qnameu, const string &qtype, const string &content, int ttl=300, int prio=25)
 {
-  DNSResourceRecord rr;
-  rr.domain_id=id;
-  rr.qname=canonic(qnameu);
-  rr.qtype=qtype;
-  rr.content=canonic(content); // I think this is wrong, the zoneparser should not come up with . terminated stuff XXX FIXME
-  rr.ttl=ttl;
-  rr.priority=prio;
-  nbbds[id]->d_records->push_back(rr);
+  Bind2DNSRecord bdr;
+
+  //  rr.domain_id=id;
+  bdr.qname=canonic(qnameu);
+
+  if(bdr.qname==nbbds[id]->d_name)
+    bdr.qname.clear();
+  else if(bdr.qname.length() > nbbds[id]->d_name.length())
+    bdr.qname.resize(bdr.qname.length() - (nbbds[id]->d_name.length() + 1));
+  else
+    throw AhuException("Trying to insert non-zone data, name='"+bdr.qname+"', zone='"+nbbds[id]->d_name+"'");
+
+  bdr.qname.swap(bdr.qname);
+  bdr.qtype=QType(qtype.c_str()).getCode();
+  //  rr.content=canonic(content); // I think this is wrong, the zoneparser should not come up with . terminated stuff XXX FIXME
+  bdr.ttl=ttl;
+
+  //  cout<<"Adding rr.qname: '"<<rr.qname<<"'"<<endl;
+  nbbds[id]->d_records->push_back(bdr);
 }
 
 
@@ -487,7 +500,7 @@ void Bind2Backend::loadConfig(string* status)
          }
        if(j==s_id_zone_map.end()) { // entirely new
          bbd=new BB2DomainInfo;
-         bbd->d_records=new vector<DNSResourceRecord>;
+         bbd->d_records=new vector<Bind2DNSRecord>;
          
          bbd->d_id=domain_id++;
          s_name_id_map[i->name]=bbd->d_id;
@@ -506,10 +519,12 @@ void Bind2Backend::loadConfig(string* status)
          
          try {
            ZP.parse(i->filename,i->name,bbd->d_id); // calls callback for us
+           L<<Logger::Info<<d_logprefix<<" sorting '"<<i->name<<endl;
+           sort(nbbds[bbd->d_id]->d_records->begin(), nbbds[bbd->d_id]->d_records->end());
            nbbds[bbd->d_id]->setCtime();
            nbbds[bbd->d_id]->d_loaded=true;          // does this perform locking for us?
            nbbds[bbd->d_id]->d_status="parsed into memory at "+nowTime();
-           
+
          }
          catch(AhuException &ae) {
            ostringstream msg;
@@ -620,6 +635,17 @@ void Bind2Backend::queueReload(BB2DomainInfo *bbd)
   }
 }
 
+bool operator<(const Bind2DNSRecord &a, const string &b)
+{
+  return a.qname < b;
+}
+
+bool operator<(const string &a, const Bind2DNSRecord &b)
+{
+  return a < b.qname;
+}
+
+
 void Bind2Backend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_p, int zoneId )
 {
   d_handle=new Bind2Backend::handle;
@@ -644,7 +670,9 @@ void Bind2Backend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt
   DLOG(L<<"Bind2Backend constructing handle for search for "<<qtype.getName()<<" for "<<
        qname<<endl);
 
-  d_handle->qname=qname;
+  
+  d_handle->qname=qname.substr(0,qname.size()-domain.length()-1); // strip domain name
+  //  cout<<"Reduced to '"<<d_handle->qname<<"'"<<endl;
   d_handle->parent=this;
   d_handle->qtype=qtype;
 
@@ -672,7 +700,7 @@ void Bind2Backend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt
   else {
     DLOG(L<<"Query with no results"<<endl);
   }
-  d_handle->d_iter=d_handle->d_records->begin();
+  d_handle->d_iter=equal_range(d_handle->d_records->begin(), d_handle->d_records->end(), d_handle->qname).first;
   d_handle->d_list=false;
 }
 
@@ -716,7 +744,8 @@ bool Bind2Backend::handle::get_normal(DNSResourceRecord &r)
        qname<<"- "<<d_records->size()<<" available!"<<endl);
   
   // this is a linear walk!!! XXX FIXME
-  while(d_iter!=d_records->end() && (strcasecmp(d_iter->qname.c_str(),qname.c_str()) || !(qtype=="ANY" || (d_iter)->qtype==qtype))) {
+
+  while(d_iter!=d_records->end() && (strcasecmp(d_iter->qname.c_str(),qname.c_str()) || !(qtype.getCode()==QType::ANY || (d_iter)->qtype==qtype))) {
     DLOG(L<<Logger::Warning<<"Skipped "<<qname<<"/"<<QType(d_iter->qtype).getName()<<": '"<<d_iter->content<<"'"<<endl);
     d_iter++;
   }
@@ -731,11 +760,11 @@ bool Bind2Backend::handle::get_normal(DNSResourceRecord &r)
 
   r.qname=qname;
   
-  r.content=(d_iter)->content;
-  r.domain_id=(d_iter)->domain_id;
+  //r.content=(d_iter)->content;
+  //  r.domain_id=(d_iter)->domain_id;
   r.qtype=(d_iter)->qtype;
   r.ttl=(d_iter)->ttl;
-  r.priority=(d_iter)->priority;
+  //  r.priority=(d_iter)->priority;
   d_iter++;
 
   return true;
@@ -763,7 +792,7 @@ bool Bind2Backend::list(const string &target, int id)
 bool Bind2Backend::handle::get_list(DNSResourceRecord &r)
 {
   if(d_qname_iter!=d_qname_end) {
-    r=*d_qname_iter;
+    //    r=*d_qname_iter;   // XXX FIXME WRONG WRONG WRONG
     d_qname_iter++;
     return true;
   }
@@ -843,7 +872,7 @@ bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, con
   
   BB2DomainInfo *bbd = new BB2DomainInfo;
 
-  bbd->d_records = new vector<DNSResourceRecord>;
+  bbd->d_records = new vector<Bind2DNSRecord>;
   bbd->d_name = domain;
   bbd->setCheckInterval(getArgAsNum("check-interval"));
   bbd->d_master = ip;
index 086305d2e487f0435ae38751a108845df288db52..24ee9666c8f0c69a24be6d67ccf1a891832a7b18 100644 (file)
 #include <pthread.h>
 #include <time.h>
 #include <fstream>
-
+#include <boost/shared_ptr.hpp>
 #include "huffman.hh"
+using namespace boost;
+using namespace std;
 
-#if __GNUC__ >= 3
-# include <ext/hash_map>
-using namespace __gnu_cxx;
-#else
-# include <hash_map>
-#endif
-
+struct Bind2DNSRecord
+{
+  string qname;
+  QType qtype;
+  uint32_t ttl;
+  shared_ptr<string> content;
 
-using namespace std;
+  bool operator<(const Bind2DNSRecord& rhs) const
+  {
+    return qname < rhs.qname;
+  }
+};
 
 class BB2DomainInfo
 {
@@ -76,97 +81,14 @@ public:
   }
 
   void setCheckInterval(time_t seconds);
-  vector <DNSResourceRecord>* d_records;
+  vector <Bind2DNSRecord>* d_records;
 private:
   time_t getCtime();
   time_t d_checkinterval;
   time_t d_lastcheck;
   pthread_rwlock_t *d_rwlock;
 };
-      
-
-
-class BBResourceRecord
-{
-public:
-  bool operator==(const BBResourceRecord &o) const
-  {
-    return (o.domain_id==domain_id && o.qtype==qtype && o.content==content && 
-           o.ttl==ttl && o.priority==priority);
-  }
-  
-  const string *qnameptr; // 4
-  unsigned int domain_id;  // 4
-  unsigned short int qtype;             // 2
-  unsigned short int priority;  // 2
-  const string *content;   // 4 
-  unsigned int ttl;        // 4
-
-};
-
-struct compare_string
-{
-  bool operator()(const string& s1, const string& s2) const
-  {
-    return s1 == s2;
-  }
-};
 
-struct hash_string
-{
-  size_t operator()(const string& s) const
-  {
-    return __stl_hash_string(s.c_str());
-  }
-};
-
-typedef hash_map<string,vector<BBResourceRecord>, hash_string, compare_string> cmap_t; 
-
-
-
-/** The Bind2Backend is a DNSBackend that can answer DNS related questions. It looks up data
-    in a Bind-style zone file 
-
-    How this all works is quite complex and prone to change. There are a number of containers involved which,
-    together, contain everything we need to know about a domain or a record.
-
-    A domain consists of records. So, 'example.com' has 'www.example.com' as a record.
-
-    All record names are stored in the hash_map d_qnames, with their name as index. Attached to that index
-    is a vector of BBResourceRecords ('Bind2Backend') belonging to that qname. Each record contains a d_domainid,
-    which is the ID of the domain it belongs to.
-
-    Then there is the map called d_bbds which has as its key the Domain ID, and attached a BB2DomainInfo object, which
-    tells us domain metadata (place on disk, if it is a master or a slave etc).
-
-    To allow for AXFRs, there is yet another container, the d_zone_id_map, which contains per domain_id a vector
-    of pointers to vectors of BBResourceRecords. When read in sequence, these deliver all records of a domain_id.
-
-    As there is huge repitition in the right hand side of records, many records point to the same thing (IP address, nameserver),
-    a list of these is kept in s_contents, and each BBResourceRecord only contains a pointer to a record in s_contents.
-
-    So, summarizing:
-    
-    class BBResourceRecord:
-    Everything you need to know about a record. In this context we call the name of a BBResourceRecord 'qname'
-
-    class BB2DomainInfo:
-    Domain metadata, like location on disk, last time zone was checked
-
-    d_qnames<qname,vector<BBResourceRecord> >:
-    If you know the qname of a record, this gives you all records under that name. 
-
-    set<string>s_contents:
-    Set of all 'contents' of records, the right hand sides. 
-
-    map<int,vector<vector<BBResourceRecord>* > > d_zone_id_map:
-    If you know the zone_id, this has a vector of pointers to vectors in d_qnames, for AXFR
-
-    map<unsigned int, BB2DomainInfo>d_bbds:
-    Map of all domains we know about and metadata about them.
-
-    
-*/
 class Bind2Backend : public DNSBackend
 {
 public:
@@ -213,13 +135,13 @@ private:
 
     Bind2Backend *parent;
 
-    vector<DNSResourceRecord>* d_records;
-    vector<DNSResourceRecord>::const_iterator d_iter;
+    vector<Bind2DNSRecord>* d_records;
+    vector<Bind2DNSRecord>::const_iterator d_iter;
     
-    vector<DNSResourceRecord>::const_iterator d_rend;
+    vector<Bind2DNSRecord>::const_iterator d_rend;
 
-    vector<DNSResourceRecord>::const_iterator d_qname_iter;
-    vector<DNSResourceRecord>::const_iterator d_qname_end;
+    vector<Bind2DNSRecord>::const_iterator d_qname_iter;
+    vector<Bind2DNSRecord>::const_iterator d_qname_end;
 
     bool d_list;
     int id;
@@ -247,7 +169,7 @@ private:
   ofstream *d_of;
   handle *d_handle;
   void queueReload(BB2DomainInfo *bbd);
-  BBResourceRecord resourceMaker(int id, const string &qtype, const string &content, int ttl, int prio);
+
   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 795d3b62f87a732eba310216c03154642fdd20bd..f2c9121bf21446e6b425438eeae8996ecdaa4dcb 100644 (file)
@@ -120,7 +120,7 @@ QType::QType(int n)
   code=n;
 }
 
-QType::QType(char *p)
+QType::QType(const char *p)
 {
   QType();
   code=chartocode(p);
index 0833a8c7247ae52212c4be0a23f1b2c663b41e64..dd81ae3f2675a930138701100bdab902c1fcaede 100644 (file)
@@ -47,7 +47,7 @@ class QType
 public:
   QType(); //!< Naked constructor
   explicit QType(int); //!< convert from an integer to a QType
-  QType(char *p);  //!< convert from a char* to a QType
+  QType(const char *p);  //!< convert from a char* to a QType
 
   QType &operator=(int);  //!< Assigns integers to us
   QType &operator=(const char *); //!< Assings strings to us