]> granicus.if.org Git - pdns/commitdiff
bind bind bind!
authorBert Hubert <bert.hubert@netherlabs.nl>
Wed, 18 Dec 2002 09:30:13 +0000 (09:30 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Wed, 18 Dec 2002 09:30:13 +0000 (09:30 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@85 d19b8d6e-7fed-0310-83ef-9ca221ded41b

12 files changed:
ChangeLog
TODO
pdns/arguments.cc
pdns/backends/bind/bindbackend.cc
pdns/backends/bind/bindbackend.hh
pdns/backends/bind/bindparser.cc
pdns/backends/bind/bindparser.yy
pdns/common_startup.cc
pdns/communicator.cc
pdns/communicator.hh
pdns/dnspacket.hh
pdns/dynhandler.cc

index 6e62de8d739954a2d88de18a5fa4652b4cc2e12c..b18b7189d4e716388566aff49950a33638aa4874 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,9 @@ Changes since 2.9.2:
        - can now understand incoming RP records in AXFR
        - fixed potential crasher bug in shortened packet parsing
        - now groks LOC records incoming/outgoing
+       - configparser now strips leading spaces in arguments
+       - improved chroot error reporting
+       - lots of bind backend work
        
 Changes since 2.9.1:
        - removed debugging output from the webserver (found by Paul Wouters)
diff --git a/TODO b/TODO
index 2e6f81165df5356cb38b2506e414c884f87e98a8..54096cf227b4776d2d512ec08ded1b539adb271b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,3 +1,5 @@
+reset yacc/lex in bindparser
+
 bugs:
        pdns.conf-dist contains old descriptions
 
index 196f50a05c9cebc4510f5bcc3fa6e7895b724395..31a34e5c5b5d027594106c2b016ed4098160d479 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-#include "utility.hh"\r
+#include "utility.hh"
 #include <fstream>
 #include <iostream>
 #include "logger.hh"
@@ -42,7 +42,7 @@ string & ArgvMap::set(const string &var)
 }
 
 bool ArgvMap::mustDo(const string &var)
-{\r
+{
   return ((*this)[var]!="no") && ((*this)[var]!="off");
 }
 
@@ -232,6 +232,11 @@ void ArgvMap::parseOne(const string &arg, const string &parseOnly, bool lax)
   }
 
   if(var!="" && (parseOnly.empty() || var==parseOnly)) {
+
+    pos=val.find_first_not_of(" \t");  // strip leading whitespace
+    if(pos && pos!=string::npos) 
+      val=val.substr(pos);
+
     if(parmIsset(var))
       params[var]=val;
     else
index 4805ac63396e148ae6bcd925f36df130b0dd4f6a..e00318ee21548e7a5b66baa96c502a85b353c96b 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-// $Id: bindbackend.cc,v 1.3 2002/12/17 16:50:31 ahu Exp $ 
+// $Id: bindbackend.cc,v 1.4 2002/12/18 09:30:13 ahu Exp $ 
 #include <errno.h>
 #include <string>
 #include <map>
@@ -39,7 +39,7 @@ using namespace std;
 #include "huffman.hh"
 #include "qtype.hh"
 #include "misc.hh"
-
+#include "dynlistener.hh"
 using namespace std;
 
 
@@ -58,6 +58,7 @@ BBDomainInfo::BBDomainInfo()
   d_last_check=0;
   d_checknow=false;
   d_rwlock=new pthread_rwlock_t;
+  d_confcount=0;
   //cout<<"Generated a new bbdomaininfo: "<<(void*)d_rwlock<<"/"<<getpid()<<endl;
   pthread_rwlock_init(d_rwlock,0);
 }
@@ -158,12 +159,15 @@ void BindBackend::getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains)
     sd.last_check=i->second.d_last_check;
     sd.backend=this;
     sd.kind=DomainInfo::Slave;
-
     SOAData soadata;
     soadata.serial=0;
     soadata.refresh=0;
-    getSOA(i->second.d_name,soadata);
-    sd.serial=soadata.serial;
+    soadata.serial=0;
+    try {
+      getSOA(i->second.d_name,soadata); // we might not *have* a SOA yet
+      sd.serial=soadata.serial;
+    }
+    catch(...){}
 
     if(sd.last_check+soadata.refresh<(unsigned int)time(0))
       unfreshDomains->push_back(sd);    
@@ -191,10 +195,12 @@ bool BindBackend::getDomainInfo(const string &domain, DomainInfo &di)
 static string canonic(string ret)
 {
   string::iterator i;
+
   for(i=ret.begin();
       i!=ret.end();
       ++i)
-    *i=tolower(*i);
+    *i=*i; //tolower(*i);
+
 
   if(*(i-1)=='.')
     ret.resize(i-ret.begin()-1);
@@ -271,6 +277,13 @@ BBResourceRecord BindBackend::resourceMaker(int id, const string &qtype, const s
 
 static BindBackend *us;
 static int domain_id;
+BindBackend *self;
+string BindBackend::DLReloadHandler(const vector<string>&parts, Utility::pid_t ppid)
+{
+  for(map<u_int32_t,BBDomainInfo>::iterator i=self->d_bbds.begin();i!=self->d_bbds.end();++i) 
+    i->second.d_checknow=true;
+  return "queued";
+}
 
 static void callback(const string &domain, const string &qtype, const string &content, int ttl, int prio)
 {
@@ -281,12 +294,11 @@ static void callback(const string &domain, const string &qtype, const string &co
 
 BindBackend::BindBackend(const string &suffix)
 {
+  d_logprefix="[bind"+suffix+"backend]";
+  setArgPrefix("bind"+suffix);
   if(!s_first)
     return;
    
-  d_logprefix="[bind"+suffix+"backend]";
-  setArgPrefix("bind"+suffix);
-
   s_first=0;
   if(!mustDo("enable-huffman"))
     s_hc.passthrough(true);
@@ -315,10 +327,33 @@ BindBackend::BindBackend(const string &suffix)
     d_bbds[0].d_loaded=true;
   }
   
+  loadConfig();
+  
+
+  extern DynListener *dl;
+  self=this;
+  dl->registerFunc("BIND-RELOAD", &DLReloadHandler);
+}
+
+
+void BindBackend::rediscover()
+{
+  loadConfig();
+}
+
+void BindBackend::loadConfig()
+{
+  static int s_confcount;
 
   if(!getArg("config").empty()) {
     BindParser BP;
-    BP.parse(getArg("config"));
+    try {
+      BP.parse(getArg("config"));
+    }
+    catch(AhuException &ae) {
+      L<<Logger::Error<<"Error parsing bind configuration: "<<ae.reason<<endl;
+      throw;
+    }
     
     ZoneParser ZP;
       
@@ -331,6 +366,11 @@ BindBackend::BindBackend(const string &suffix)
     L<<Logger::Warning<<d_logprefix<<" Parsing "<<domains.size()<<" domain(s), will report when done"<<endl;
     
     int rejected=0;
+    int newdomains=0;
+    s_confcount++;
+
+    map<unsigned int, BBDomainInfo> nbbds;
+
     for(vector<BindDomainInfo>::const_iterator i=domains.begin();
        i!=domains.end();
        ++i)
@@ -339,35 +379,48 @@ BindBackend::BindBackend(const string &suffix)
        bbd.d_name=i->name;
        bbd.d_filename=i->filename;
        bbd.d_master=i->master;
-       bbd.d_id=domain_id;
+
        bbd.setCtime();
        bbd.setCheckInterval(getArgAsNum("check-interval"));
+
+       map<unsigned int, BBDomainInfo>::const_iterator j=d_bbds.begin();
+       for(;j!=d_bbds.end();++j)
+         if(j->second.d_name==bbd.d_name) {
+           bbd.d_id=j->second.d_id;
+           break;
+         }
+       if(j==d_bbds.end())
+         bbd.d_id=domain_id++;
        
-       d_bbds[domain_id]=bbd; 
+       nbbds[bbd.d_id]=bbd; 
        L<<Logger::Info<<d_logprefix<<" parsing '"<<i->name<<"' from file '"<<i->filename<<"'"<<endl;
-       d_bbds[domain_id].d_loaded=false;
+       nbbds[bbd.d_id].d_loaded=false;
        try {
          ZP.parse(i->filename,i->name); // calls callback for us
-         d_bbds[domain_id].d_loaded=true;
+         nbbds[bbd.d_id].d_loaded=true;
        }
        catch(AhuException &ae) {
          L<<Logger::Warning<<d_logprefix<<" error parsing '"<<i->name<<"' from file '"<<i->filename<<"': "<<ae.reason<<endl;
          rejected++;
        }
        
-       vector<vector<BBResourceRecord> *>&tmp=d_zone_id_map[domain_id];  // shrink trick
+       vector<vector<BBResourceRecord> *>&tmp=d_zone_id_map[bbd.d_id];  // shrink trick
        vector<vector<BBResourceRecord> *>(tmp).swap(tmp);
-
-       domain_id++;
       }
-    L<<Logger::Error<<d_logprefix<<" Done parsing domains, "<<rejected<<" were rejected"<<endl; // XXX add how many were rejected
-    L<<Logger::Info<<d_logprefix<<" Number of hash buckets: "<<d_qnames.bucket_count()<<", number of entries: "<<d_qnames.size()<< endl;
-  }
-}
 
-void BindBackend::rediscover()
-{
 
+    int remdomains=0;
+    vector<string> oldnames, newnames;
+    for(map<unsigned int, BBDomainInfo>::const_iterator j=d_bbds.begin();j!=d_bbds.end();++j)
+      oldnames.push_back(j->second.d_name);
+    for(map<unsigned int, BBDomainInfo>::const_iterator j=nbbds.begin();j!=nbbds.end();++j)
+      newnames.push_back(j->second.d_name);
+
+    d_bbds.swap(nbbds); // commit
+
+    L<<Logger::Error<<d_logprefix<<" Done parsing domains, "<<rejected<<" rejected, "<<newdomains<<" new, "<<remdomains<<" removed"<<endl; // XXX add how many were rejected
+    L<<Logger::Info<<d_logprefix<<" Number of hash buckets: "<<d_qnames.bucket_count()<<", number of entries: "<<d_qnames.size()<< endl;
+  }
 }
 
 void BindBackend::queueReload(BBDomainInfo *bbd)
@@ -427,7 +480,7 @@ void BindBackend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_
       
     if(!bbd.d_loaded) {
       delete d_handle;
-      throw AhuException("Temporarily unavailable due to a zone lock"); // fuck
+      throw AhuException("Zone temporarily not available (file missing, or master dead)"); // fuck
     }
 
     if(!bbd.current()) {
index 2eec079c90d772ffddd597966a2a25f26e9d4560..2b3a12e0b7621f083df1fab27ed53bb41d4d4ab6 100644 (file)
@@ -67,6 +67,7 @@ public:
   unsigned int d_id;
   time_t d_last_check;
   string d_master;
+  int d_confcount;
 
   bool tryRLock()
   {
@@ -211,4 +212,6 @@ private:
   handle *d_handle;
   void queueReload(BBDomainInfo *bbd);
   BBResourceRecord resourceMaker(int id, const string &qtype, const string &content, int ttl, int prio);
+  static string DLReloadHandler(const vector<string>&parts, Utility::pid_t ppid);
+  void loadConfig();
 };
index c34973c86b7619ddffb83d6402852a25d0e1fc61..b6aab10a3f6f7899497716888a8164dd1eb301a7 100644 (file)
@@ -1,22 +1,4 @@
-/*
-    PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002  PowerDNS.COM BV
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-/* A Bison parser, made from /home/ahu/programming/ahudns/backends/bind/bindparser.yy
+/* A Bison parser, made from /home/ahu/programming/pdns/pdns/backends/bind/bindparser.yy
    by GNU bison 1.35.  */
 
 #define YYBISON 1  /* Identify Bison output.  */
@@ -68,6 +50,7 @@ extern "C"
        {
                return 1;
        }
+       void yyrestart(FILE *);
 
 }
 
@@ -88,7 +71,7 @@ void BindParser::parse(const string &fname)
 {      
        yydebug=0;
        yyin=fopen(fname.c_str(),"r");
-
+       yyrestart(yyin);
        if(!yyin)
                throw AhuException("Unable to open '"+fname+"': "+strerror(errno));
 
@@ -218,11 +201,11 @@ static const short yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
 static const short yyrline[] =
 {
-       0,   107,   108,   112,   112,   112,   112,   115,   116,   120,
-     124,   131,   141,   143,   147,   148,   151,   154,   155,   159,
-     163,   164,   168,   168,   171,   178,   179,   183,   183,   183,
-     185,   189,   193,   194,   198,   198,   198,   198,   201,   204,
-     205,   209,   215,   223,   232,   239
+       0,   108,   109,   113,   113,   113,   113,   116,   117,   121,
+     125,   132,   142,   144,   148,   149,   152,   155,   156,   160,
+     164,   165,   169,   169,   172,   179,   180,   184,   184,   184,
+     186,   190,   194,   195,   199,   199,   199,   199,   202,   205,
+     206,   210,   216,   224,   233,   240
 };
 #endif
 
@@ -1038,7 +1021,7 @@ yyreduce:
   switch (yyn) {
 
 case 10:
-#line 126 "bindparser.yy"
+#line 127 "bindparser.yy"
 {
                s_di.name=yyvsp[-1];
                parent->commit(s_di);
@@ -1046,7 +1029,7 @@ case 10:
        }
     break;
 case 11:
-#line 133 "bindparser.yy"
+#line 134 "bindparser.yy"
 {
                s_di.name=yyvsp[-2];
                parent->commit(s_di);
@@ -1054,33 +1037,33 @@ case 11:
        }
     break;
 case 24:
-#line 172 "bindparser.yy"
+#line 173 "bindparser.yy"
 {
                parent->setDirectory(yyvsp[0]);
        }
     break;
 case 41:
-#line 210 "bindparser.yy"
+#line 211 "bindparser.yy"
 {
                s_di.master=yyvsp[0];
        }
     break;
 case 42:
-#line 217 "bindparser.yy"
+#line 218 "bindparser.yy"
 {
          //            printf("Found a filename: '%s'\n",$2);
                s_di.filename=yyvsp[0];
        }
     break;
 case 43:
-#line 225 "bindparser.yy"
+#line 226 "bindparser.yy"
 {
          //            printf("Found a filename: '%s'\n",$2);
          //            ztype=$2;
        }
     break;
 case 44:
-#line 234 "bindparser.yy"
+#line 235 "bindparser.yy"
 {
                yyval=yyvsp[0];
        }
@@ -1318,4 +1301,4 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 240 "bindparser.yy"
+#line 241 "bindparser.yy"
index 345f9bdc5a3121aaf8060c4c178df2f69faa0a13..68b623a44a8947ecc519423aa87e7e786ee353c1 100644 (file)
@@ -29,6 +29,7 @@ extern "C"
        {
                return 1;
        }
+       void yyrestart(FILE *);
 
 }
 
@@ -49,7 +50,7 @@ void BindParser::parse(const string &fname)
 {      
        yydebug=0;
        yyin=fopen(fname.c_str(),"r");
-
+       yyrestart(yyin);
        if(!yyin)
                throw AhuException("Unable to open '"+fname+"': "+strerror(errno));
 
index 62ae03dd82a72251c883a875921935751bfe6955..8a5fe2475d13643ace33d42e3f1fab538608e636 100644 (file)
@@ -236,7 +236,7 @@ void mainthread()
 #ifndef WIN32
    if(!arg()["chroot"].empty()) {  
      if(chroot(arg()["chroot"].c_str())<0) {
-       L<<Logger::Error<<"Unable to chroot: "<<strerror(errno)<<", exiting"<<endl; 
+       L<<Logger::Error<<"Unable to chroot to '"+arg()["chroot"]+"': "<<strerror(errno)<<", exiting"<<endl; 
        exit(1);
      }   
      else
index fc751c9e2b2e20b4000a2ce02e5a6d3018ef4228..8b6e71db83d7ee165582e5293327b36791080e4b 100644 (file)
@@ -178,12 +178,17 @@ void CommunicatorClass::masterUpdateCheck(PacketHandler *P)
   vector<DomainInfo> cmdomains;
   B->getUpdatedMasters(&cmdomains);
   
-  if(cmdomains.empty())
-    L<<Logger::Error<<"No master domains need notifications"<<endl;
-  else
+  if(cmdomains.empty()) {
+    if(d_masterschanged)
+      L<<Logger::Error<<"No master domains need notifications"<<endl;
+    d_masterschanged=false;
+  }
+  else {
+    d_masterschanged=true;
     L<<Logger::Error<<cmdomains.size()<<" domain"<<(cmdomains.size()>1 ? "s" : "")<<" for which we are master need"<<
       (cmdomains.size()>1 ? "" : "s")<<
       " notifications"<<endl;
+  }
 
   // figure out A records of everybody needing notification
   // do this via the FindNS class, d_fns
@@ -209,15 +214,18 @@ void CommunicatorClass::slaveRefresh(PacketHandler *P)
   
   if(sdomains.empty())
   {
-    L<<Logger::Error<<"All slave domains are fresh"<<endl;
+    if(d_slaveschanged)
+      L<<Logger::Error<<"All slave domains are fresh"<<endl;
+    d_slaveschanged=false;
     return;
   }
-  else
+  else 
     L<<Logger::Error<<sdomains.size()<<" slave domain"<<(sdomains.size()>1 ? "s" : "")<<" need"<<
       (sdomains.size()>1 ? "" : "s")<<
       " checking"<<endl;
   
   for(vector<DomainInfo>::const_iterator i=sdomains.begin();i!=sdomains.end();++i) {
+    d_slaveschanged=true;
     u_int32_t theirserial=0;
     try {
       Resolver resolver;
index d902832caecaa321e1f779d3d0efcfd707b845ee..81894c533a2319b263f407179e0bdad91ecdc9ed 100644 (file)
@@ -128,6 +128,7 @@ public:
 //    sem_init(&d_suck_sem,0,0);
 //    sem_init(&d_any_sem,0,0);
     d_tickinterval=60;
+    d_masterschanged=d_slaveschanged=true;
   }
   int doNotifications();    
   void go()
@@ -162,6 +163,7 @@ private:
   Semaphore d_any_sem;
   int d_tickinterval;
   NotificationQueue d_nq;
+  bool d_masterschanged, d_slaveschanged;
 };
 
 #endif
index adc4aad4eb2e57d1710422162449bfb74f3448f3..e30686cf222672c215feedb0b4c2382758963a8c 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-// $Id: dnspacket.hh,v 1.6 2002/12/17 16:50:30 ahu Exp $
+// $Id: dnspacket.hh,v 1.7 2002/12/18 09:30:13 ahu Exp $
 #ifndef DNSPACKET_HH
 #define DNSPACKET_HH
 
@@ -299,7 +299,7 @@ int DNSPacket::parse(const char *mesg, int length)
     d_qlen=offset+4; // this points to the start of any answers
   }
 
-  if(15+offset>=stringbuffer.length()) {
+  if((unsigned int)(15+offset)>=stringbuffer.length()) {
     L << Logger::Warning << "Ignoring packet: question too short from "
       << getRemote() << endl;
     return -1;
index 039c99d107ff4c0d4a4a1c9ef218935fda3cc6fb..72978b14e2b09daeea2431e05badddb6bbc21ab5 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-#include "utility.hh"\r
+#include "utility.hh"
 #include "dynhandler.hh"
 #include "statbag.hh"
 #include "logger.hh"
 #include "dns.hh"
 #include "arguments.hh"
 #include <signal.h>
-#include "misc.hh"\r
+#include "misc.hh"
 #include "communicator.hh"
 
 static bool s_pleasequit;
@@ -207,9 +207,15 @@ string DLNotifyHandler(const vector<string>&parts, Utility::pid_t ppid)
 string DLRediscoverHandler(const vector<string>&parts, Utility::pid_t ppid)
 {
   PacketHandler P;
-  P.getBackend()->rediscover();
-  L<<Logger::Error<<"Rediscovery was requested"<<endl;
-  return "Ok";
+  try {
+    L<<Logger::Error<<"Rediscovery was requested"<<endl;
+    P.getBackend()->rediscover();
+    return "Ok";
+  }
+  catch(AhuException &ae) {
+    return ae.reason;
+  }
+
 }
 
 string DLReloadHandler(const vector<string>&parts, Utility::pid_t ppid)