]> granicus.if.org Git - pdns/commitdiff
implement reload-zones
authorBert Hubert <bert.hubert@netherlabs.nl>
Sat, 6 May 2006 19:50:46 +0000 (19:50 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sat, 6 May 2006 19:50:46 +0000 (19:50 +0000)
make loading zones do a 'round trip' of records to see if they make it alive
add 'unregistering' of record types (unused for now)
make zone loading a lot more helpful in reporting errors

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

pdns/dnsparser.hh
pdns/dnsrecords.cc
pdns/dnsrecords.hh
pdns/docs/pdns.sgml
pdns/docs/rec_control.1.txt
pdns/pdns_recursor.cc
pdns/rec_channel_rec.cc
pdns/recursor_cache.hh
pdns/syncres.hh

index 889347da37352da10bcb3c7edcc394f4dba0f8f6..42697fb0fb77238d979d090b663e8cce8d58a690 100644 (file)
@@ -180,6 +180,13 @@ public:
     getNamemap()[make_pair(cl,ty)]=name;
   }
 
+  static void unregist(uint16_t cl, uint16_t ty) 
+  {
+    pair<uint16_t, uint16_t> key=make_pair(cl, ty);
+    getTypemap().erase(key);
+    getZmakermap().erase(key);
+  }
+
   static uint16_t TypeToNumber(const string& name)
   {
     for(namemap_t::const_iterator i=getNamemap().begin(); i!=getNamemap().end();++i)
index 9076dbc78c55f371c9b725365f50ae3588e80450..92ca107ed9e781c7780550f61b79b38c291ad81f 100644 (file)
@@ -287,6 +287,7 @@ void reportBasicTypes()
   SRVRecordContent::report();
   PTRRecordContent::report();
   DNSRecordContent::regist(3, ns_t_txt, &TXTRecordContent::make, &TXTRecordContent::make, "TXT");
+  TXTRecordContent::report();
   DNSRecordContent::regist(1, 255, 0, 0, "ANY");
 }
 
@@ -302,7 +303,6 @@ void reportOtherTypes()
    CERTRecordContent::report();
    NSECRecordContent::report();
    OPTRecordContent::report();
-   TXTRecordContent::report();
 }
 
 void reportAllTypes()
index b6532f7fca485d1e34d730aec66f165029198aa8..466950ce284cfa28133254366b9bfb0e8d1d6675 100644 (file)
@@ -31,6 +31,7 @@ using namespace boost;
 #define includeboilerplate(RNAME)   RNAME##RecordContent(const DNSRecord& dr, PacketReader& pr); \
   RNAME##RecordContent(const string& zoneData);                                                  \
   static void report(void);                                                                      \
+  static void unreport(void);                                                                    \
   static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);                          \
   static DNSRecordContent* make(const string& zonedata);                                         \
   string getZoneRepresentation() const;                                                          \
@@ -289,6 +290,10 @@ void RNAME##RecordContent::toPacket(DNSPacketWriter& pw)
 void RNAME##RecordContent::report(void)                                                            \
 {                                                                                                  \
   regist(1, RTYPE, &RNAME##RecordContent::make, &RNAME##RecordContent::make, #RNAME);              \
+}                                                                                                  \
+void RNAME##RecordContent::unreport(void)                                                          \
+{                                                                                                  \
+  unregist(1, RTYPE);                                                                              \
 }                                                                                                  \
                                                                                                    \
 RNAME##RecordContent::RNAME##RecordContent(const string& zoneData) : DNSRecordContent(RTYPE)       \
index c7a9f24a34a2b58d603f25b0e4f73f9d9284f63b..5ad52d0ae548a0e5c4dfa30f3d644da36f4f830d 100644 (file)
@@ -6379,6 +6379,16 @@ local0.err                        /var/log/pdns.err
                </para>
              </listitem>
            </varlistentry>       
+           <varlistentry>
+             <term>reload-zones</term>
+             <listitem>
+               <para>
+               Reload data about all authoritative and forward zones. The configuration file is also scanned 
+               to see if the <command>auth-domain</command>, <command>forward-domain</command> and <command>export-etc-hosts</command>
+               statements have changed, and if so, these changes are incorporated.
+               </para>
+             </listitem>
+           </varlistentry>       
            <varlistentry>
              <term>top-remotes</term>
              <listitem>
@@ -6402,9 +6412,8 @@ local0.err                        /var/log/pdns.err
                <para>
                  <warning>
                    <para>
-                     Ubunty Breezy ships a version of Boost that has problems with this command! Either refrain from
-                     using wipe-cache or download a more recent Boost into the PowerDNS source directory, as explained in the
-                     <filename>README</filename>
+                   In PowerDNS versions 3.0.0 and 3.0.1 this command is slightly buggy and might cause your nameserver to crash if the first
+                   query after wiping the cache is for the domain you just wiped.
                    </para>
                  </warning>
                  <warning>
index 496b041bf77e57d38df4ca86e3527c4fbd6715d3..8cc1b4ba59b8b48e2c06219de897bf6c88593a8f 100644 (file)
-REC_CONTROL(1)\r
-==============\r
-bert hubert <bert.hubert@netherlabs.nl>\r
-v3.0, 19 April 2006\r
-\r
-NAME\r
-----\r
-rec_control - control pdns_recursor\r
-\r
-SYNOPSIS\r
---------\r
-'rec_control' [--help] [--socket-dir] [--socket-pid] command ..\r
-\r
-DESCRIPTION\r
------------\r
-rec_control(1) allows the operator to control a running instance\r
-of the pdns_recursor.\r
-\r
-The commands that can be passed to the recursor are described on\r
-http://doc.powerdns.com/rec-control.html\r
-
-EXAMPLES\r
---------\r
-\r
+REC_CONTROL(1)
+==============
+bert hubert <bert.hubert@netherlabs.nl>
+v3.0, 19 April 2006
+
+NAME
+----
+rec_control - control pdns_recursor
+
+SYNOPSIS
+--------
+'rec_control' [--help] [--socket-dir] [--socket-pid] command ..
+
+DESCRIPTION
+-----------
+rec_control(1) allows the operator to control a running instance
+of the pdns_recursor.
+
+The commands that can be passed to the recursor are described on
+http://doc.powerdns.com/rec-control.html
+
+EXAMPLES
+--------
+
 To stop the recursor by hand, run:
 
        # rec_control quit
 
-To dump the cache to disk, execute:\r
-\r
-       # rec_control dump-cache /tmp/the-cache\r
-\r
-OPTIONS\r
--------\r
-\r
+To dump the cache to disk, execute:
+
+       # rec_control dump-cache /tmp/the-cache
+
+OPTIONS
+-------
+
 --help::
        provide this helpful message
 
 --socket-dir::
        Where the controlsocket will live
-\r
+
 --socket-pid::
        When running in SMP mode, pid of pdns_recursor to control
-\r
-COMMANDS\r
---------\r
-dump-cache filename::\r
-       Dumps the entire cache to the filename mentioned. This file should\r
-       not exist already, PowerDNS will refuse to overwrite it. While\r
-       dumping, the recursor will not answer questions.\r
-\r
-get statistic::\r
-       Retrieve a statistic. For items that can be queried, see\r
-       http://doc.powerdns.com/recursor-stats.html\r
-\r
-ping::\r
-       Check if server is alive.\r
-\r
-quit::\r
-       Request shutdown of the recursor\r
-\r
-top-remotes::\r
-       Shows the top-20 most active remote hosts. Statistics are over the\r
-       last 'remotes-ringbuffer-entries' queries, which defaults to 0.\r
-\r
-wipe-cache domain0 [domain1]::\r
-       Wipe entries from the cache. This is useful if, for example, an\r
-       important server has a new IP address, but the TTL has not yet\r
-       expired. Multiple domain names can be passed. Note that you must\r
-       terminate a domain with a .!  So to wipe powerdns.org, issue\r
-       'rec_control wipe-cache powerdns.org.'.\r
+
+COMMANDS
+--------
+dump-cache filename::
+       Dumps the entire cache to the filename mentioned. This file should
+       not exist already, PowerDNS will refuse to overwrite it. While
+       dumping, the recursor will not answer questions.
+
+get statistic::
+       Retrieve a statistic. For items that can be queried, see
+       http://doc.powerdns.com/recursor-stats.html
+
+ping::
+       Check if server is alive.
+
+quit::
+       Request shutdown of the recursor
+
+reload-zones::
+       Reload authoritative and forward zones. Retains current configuration
+       in case of errors.
+
+top-remotes::
+       Shows the top-20 most active remote hosts. Statistics are over the
+       last 'remotes-ringbuffer-entries' queries, which defaults to 0.
+
+wipe-cache domain0 [domain1]::
+       Wipe entries from the cache. This is useful if, for example, an
+       important server has a new IP address, but the TTL has not yet
+       expired. Multiple domain names can be passed. Note that you must
+       terminate a domain with a .!  So to wipe powerdns.org, issue
+       'rec_control wipe-cache powerdns.org.'.
        Versions beyond 3.1 don't need the trailing dot. Consider not only
        wiping 'www.domain.com.' but also 'domain.com.', as the cached nameservers
        or target of CNAME may continue to be undesired.
 
-BUGS\r
-----\r
-None known. File new ones at http://wiki.powerdns.com.\r
-\r
-AUTHOR\r
-------\r
-Written by PowerDNS.COM BV, bert hubert, <bert.hubert@netherlabs.nl>\r
-\r
-RESOURCES\r
----------\r
-Website: http://wiki.powerdns.com, http://www.powerdns.com\r
-\r
-SEE ALSO\r
---------\r
-pdns_recursor(1)\r
-\r
-COPYING\r
--------\r
-Copyright (C) 2006 PowerDNS.COM BV. Free use of this software\r
-is granted under the terms of the GNU General Public License (GPL) version\r
-2.\r
-\r
+BUGS
+----
+None known. File new ones at http://wiki.powerdns.com.
+
+AUTHOR
+------
+Written by PowerDNS.COM BV, bert hubert, <bert.hubert@netherlabs.nl>
+
+RESOURCES
+---------
+Website: http://wiki.powerdns.com, http://www.powerdns.com
+
+SEE ALSO
+--------
+pdns_recursor(1)
+
+COPYING
+-------
+Copyright (C) 2006 PowerDNS.COM BV. Free use of this software
+is granted under the terms of the GNU General Public License (GPL) version
+2.
+
index e715a7ef5ed27d24cf30d976e451987b44957a98..e058a3309ff0e75b1fcf0cf38f47990a8fdc713a 100644 (file)
@@ -1204,10 +1204,62 @@ static void makeIPToNamesZone(const vector<string>& parts)
   }
 }
 
+
+void parseAuthAndForwards();
+
+string reloadAuthAndForwards()
+{
+  SyncRes::domainmap_t original=SyncRes::s_domainmap;
+  
+  try {
+    L<<Logger::Warning<<"Reloading zones, purging data from cache"<<endl;
+  
+    for(SyncRes::domainmap_t::const_iterator i = SyncRes::s_domainmap.begin(); i != SyncRes::s_domainmap.end(); ++i) {
+      for(SyncRes::AuthDomain::records_t::const_iterator j = i->second.d_records.begin(); j != i->second.d_records.end(); ++j) 
+       RC.doWipeCache(j->qname);
+    }
+
+    string configname=::arg()["config-dir"]+"/recursor.conf";
+    cleanSlashes(configname);
+    
+    if(!::arg().preParseFile(configname.c_str(), "forward-zones")) 
+      L<<Logger::Warning<<"Unable to re-parse configuration file '"<<configname<<"'"<<endl;
+    
+    ::arg().preParseFile(configname.c_str(), "auth-zones");
+    ::arg().preParseFile(configname.c_str(), "export-etc-hosts");
+    ::arg().preParseFile(configname.c_str(), "serve-rfc1918");
+    
+    parseAuthAndForwards();
+    
+    // purge again - new zones need to blank out the cache
+    for(SyncRes::domainmap_t::const_iterator i = SyncRes::s_domainmap.begin(); i != SyncRes::s_domainmap.end(); ++i) {
+      for(SyncRes::AuthDomain::records_t::const_iterator j = i->second.d_records.begin(); j != i->second.d_records.end(); ++j) 
+       RC.doWipeCache(j->qname);
+    }
+
+    // this is pretty blunt
+    SyncRes::s_negcache.clear(); 
+    return "ok\n";
+  }
+  catch(exception& e) {
+    L<<Logger::Error<<"Had error reloading zones, keeping original data: "<<e.what()<<endl;
+  }
+  catch(AhuException& ae) {
+    L<<Logger::Error<<"Encountered error reloading zones, keeping original data: "<<ae.reason<<endl;
+  }
+  catch(...) {
+    L<<Logger::Error<<"Encountered unknown error reloading zones, keeping original data"<<endl;
+  }
+  SyncRes::s_domainmap.swap(original);
+  return "reloading failed, see log\n";
+}
+
 void parseAuthAndForwards()
 {
   SyncRes::s_domainmap.clear(); // this makes us idempotent
 
+  TXTRecordContent::report();
+
   typedef vector<string> parts_t;
   parts_t parts;  
   for(int n=0; n < 2 ; ++n ) {
@@ -1224,7 +1276,19 @@ void parseAuthAndForwards()
        ZoneParserTNG zpt(headers.second, headers.first);
        DNSResourceRecord rr;
        while(zpt.get(rr)) {
+         try {
+           string tmp=DNSRR2String(rr);
+           rr=String2DNSRR(rr.qname, rr.qtype, tmp, 3600);
+         }
+         catch(exception &e) {
+           throw AhuException("Error parsing record '"+rr.qname+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"': "+e.what());
+         }
+         catch(...) {
+           throw AhuException("Error parsing record '"+rr.qname+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"'");
+         }
+
          ad.d_records.insert(rr);
+
        }
       }
       else {
index 54892fef60a0515bfaa7e5fc95291bd9a870f55b..fa489aad79c9b72dfcb2ee14d688bfddf4105445 100644 (file)
@@ -255,7 +255,10 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP
 
   if(cmd=="ping")
     return "pong\n";
-  
-  return "Unknown command '"+cmd+"'\n";
 
+  if(cmd=="reload-zones") {
+    return reloadAuthAndForwards();
+  }
+
+  return "Unknown command '"+cmd+"'\n";
 }
index 23845e1ce91ed1fe6bdebcd9347732462bd0078d..1a5bbd83c30dbb19d6b330b83b400465524faf3a 100644 (file)
@@ -117,6 +117,7 @@ private:
   string d_cachedqname;
   bool d_cachecachevalid;
 };
-
+string DNSRR2String(const DNSResourceRecord& rr);
+DNSResourceRecord String2DNSRR(const string& qname, const QType& qt, const string& serial, uint32_t ttd);
 
 #endif
index 7ddce01e8a24a9897436c940f11a7534871a5a97..0b3412b56e0992b3ede5452e681c2dfe2ab4142c 100644 (file)
@@ -477,4 +477,6 @@ replacing_insert(Index& i,const typename Index::value_type& x)
   return res;
 }
 
+
+std::string reloadAuthAndForwards();
 #endif