]> granicus.if.org Git - pdns/commitdiff
ixfrdist: Allow setting the inbound AXFR timeout
authorPieter Lexis <pieter.lexis@powerdns.com>
Wed, 14 Feb 2018 12:58:15 +0000 (13:58 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Wed, 14 Feb 2018 12:58:15 +0000 (13:58 +0100)
pdns/ixfrdist.cc
pdns/resolver.cc
pdns/resolver.hh

index a0465633e7dc634bf4deaca13fa91b6cbac85ee3..98b84f5f7bbb7f2b734dc765a161049d44748c2a 100644 (file)
@@ -74,6 +74,9 @@ bool g_exiting = false;
 #define KEEP_DEFAULT 20
 uint16_t g_keep = KEEP_DEFAULT;
 
+#define AXFRTIMEOUT_DEFAULT 20
+uint16_t g_axfrTimeout = AXFRTIMEOUT_DEFAULT;
+
 NetmaskGroup g_acl;
 
 void handleSignal(int signum) {
@@ -237,7 +240,7 @@ void updateThread() {
         Resolver::res_t nop;
         vector<DNSRecord> chunk;
         records_t records;
-        while(axfr.getChunk(nop, &chunk)) {
+        while(axfr.getChunk(nop, &chunk, g_axfrTimeout)) {
           for(auto& dr : chunk) {
             if(dr.d_type == QType::TSIG)
               continue;
@@ -707,6 +710,7 @@ int main(int argc, char** argv) {
       ("server-address", po::value<string>()->default_value("127.0.0.1:5300"), "server address")
       ("work-dir", po::value<string>()->default_value("."), "Directory for storing AXFR and IXFR data")
       ("keep", po::value<uint16_t>()->default_value(KEEP_DEFAULT), "Number of old zone versions to retain")
+      ("axfr-timeout", po::value<uint16_t>()->default_value(AXFRTIMEOUT_DEFAULT), "Timeout in seconds for an AXFR to complete")
       ;
     po::options_description alloptions;
     po::options_description hidden("hidden options");
@@ -748,6 +752,10 @@ int main(int argc, char** argv) {
     g_keep = g_vm["keep"].as<uint16_t>();
   }
 
+  if (g_vm.count("axfr-timeout") > 0) {
+    g_axfrTimeout = g_vm["axfr-timeout"].as<uint16_t>();
+  }
+
   vector<ComboAddress> listen_addresses = {ComboAddress("127.0.0.1:53")};
 
   if (g_vm.count("listen-address") > 0) {
index 81eabdfea634537da3459596293707812f230221..d2ecd76f812df92bd2268303e3b007e5a574c522 100644 (file)
@@ -429,7 +429,7 @@ AXFRRetriever::~AXFRRetriever()
 
 
 
-int AXFRRetriever::getChunk(Resolver::res_t &res, vector<DNSRecord>* records) // Implementation is making sure RFC2845 4.4 is followed.
+int AXFRRetriever::getChunk(Resolver::res_t &res, vector<DNSRecord>* records, uint16_t timeout) // Implementation is making sure RFC2845 4.4 is followed.
 {
   if(d_soacount > 1)
     return false;
@@ -442,7 +442,7 @@ int AXFRRetriever::getChunk(Resolver::res_t &res, vector<DNSRecord>* records) //
   if (d_maxReceivedBytes > 0 && (d_maxReceivedBytes - d_receivedBytes) < (size_t) len)
     throw ResolverException("Reached the maximum number of received bytes during AXFR");
 
-  timeoutReadn(len);
+  timeoutReadn(len, timeout);
 
   d_receivedBytes += (uint16_t) len;
 
@@ -475,13 +475,13 @@ int AXFRRetriever::getChunk(Resolver::res_t &res, vector<DNSRecord>* records) //
   return true;
 }
 
-void AXFRRetriever::timeoutReadn(uint16_t bytes)
+void AXFRRetriever::timeoutReadn(uint16_t bytes, uint16_t timeoutsec)
 {
-  time_t start=time(0);
+  time_t start=time(nullptr);
   int n=0;
   int numread;
   while(n<bytes) {
-    int res=waitForData(d_sock, 10-(time(0)-start));
+    int res=waitForData(d_sock, timeoutsec-(time(nullptr)-start));
     if(res<0)
       throw ResolverException("Reading data from remote nameserver over TCP: "+stringerror());
     if(!res)
index c9946ccf810ca7319aa3f9c17f820a8ce95d489b..9246994cb68b779f8f189e7b799039f3b3e404ff 100644 (file)
@@ -87,12 +87,12 @@ class AXFRRetriever : public boost::noncopyable
                   const ComboAddress* laddr = NULL,
                   size_t maxReceivedBytes=0);
     ~AXFRRetriever();
-    int getChunk(Resolver::res_t &res, vector<DNSRecord>* records=0);  
+    int getChunk(Resolver::res_t &res, vector<DNSRecord>* records=0, uint16_t timeout=10);
   
   private:
     void connect();
     int getLength();
-    void timeoutReadn(uint16_t bytes);  
+    void timeoutReadn(uint16_t bytes, uint16_t timeoutsec=10);
 
     shared_array<char> d_buf;
     string d_domain;