]> granicus.if.org Git - pdns/commitdiff
rec: Implement settable AXFR timeout for RPZ
authorPieter Lexis <pieter.lexis@powerdns.com>
Wed, 21 Feb 2018 11:52:54 +0000 (12:52 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Wed, 21 Feb 2018 11:55:27 +0000 (12:55 +0100)
pdns/rec-lua-conf.cc
pdns/recursordist/docs/lua-config/rpz.rst
pdns/reczones.cc
pdns/rpzloader.cc
pdns/rpzloader.hh

index 882ae4efe6a3b427db1447c41b94017fe5faf3ac..e42ce1f4b5eccdcba75a4520bfec57335232d0f8 100644 (file)
@@ -141,6 +141,7 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly)
       TSIGTriplet tt;
       uint32_t refresh=0;
       size_t maxReceivedXFRMBytes = 0;
+      uint16_t axfrTimeout = 20;
       uint32_t maxTTL = std::numeric_limits<uint32_t>::max();
       ComboAddress localAddress;
       ComboAddress master(master_, 53);
@@ -170,6 +171,9 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly)
           if(have.count("localAddress")) {
             localAddress = ComboAddress(boost::get<string>(constGet(have,"localAddress")));
           }
+          if(have.count("axfrTimeout")) {
+            axfrTimeout = static_cast<uint16_t>(boost::get<uint32_t>(constGet(have, "axfrTimeout")));
+          }
         }
         if (localAddress != ComboAddress() && localAddress.sin4.sin_family != master.sin4.sin_family) {
           // We were passed a localAddress, check if its AF matches the master's
@@ -192,7 +196,7 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly)
 
       try {
           if (!checkOnly) {
-            std::thread t(RPZIXFRTracker, master, defpol, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress, zone);
+            std::thread t(RPZIXFRTracker, master, defpol, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress, zone, axfrTimeout);
             t.detach();
           }
       }
index b41c2d49192503b09a97b2974b31018fc0e4319c..630730c54dce2ff92717b05fba2d6941d7bc22da 100644 (file)
@@ -104,6 +104,14 @@ localAddress
 The source IP address to use when transferring the RPZ.
 When unset, :ref:`setting-query-local-address` and :ref:`setting-query-local-address6` are used.
 
+axfrTimeout
+^^^^^^^^^^^
+.. versionadded:: 4.1.2
+  Before 4.1.2, the timeout was fixed on 10 seconds.
+
+The timeout in seconds of the total initial AXFR transaction.
+20 by default.
+
 Policy Actions
 --------------
 
index b4c84a95fe2cf4c23fff1abdd43286979099062c..50e489efc1e76f50d9ff37931c626e9bc0bff722 100644 (file)
@@ -318,7 +318,7 @@ string reloadAuthAndForwards()
 }
 
 
-void RPZIXFRTracker(const ComboAddress& master, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, size_t zoneIdx, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress, std::shared_ptr<DNSFilterEngine::Zone> zone)
+void RPZIXFRTracker(const ComboAddress& master, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, size_t zoneIdx, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress, std::shared_ptr<DNSFilterEngine::Zone> zone, const uint16_t axfrTimeout)
 {
   uint32_t refresh = zone->getRefresh();
   DNSName zoneName = zone->getDomain();
@@ -326,7 +326,7 @@ void RPZIXFRTracker(const ComboAddress& master, boost::optional<DNSFilterEngine:
 
   while (!sr) {
     try {
-      sr=loadRPZFromServer(master, zoneName, zone, defpol, maxTTL, tt, maxReceivedBytes, localAddress);
+      sr = loadRPZFromServer(master, zoneName, zone, defpol, maxTTL, tt, maxReceivedBytes, localAddress, axfrTimeout);
       if(refresh) {
         sr->d_st.refresh=refresh;
       }
index 4ed461273de2564cbb1cfac9160b558e7f37eb78..b717b753499d715b50c69bf16c5f722590c499a2 100644 (file)
@@ -174,7 +174,7 @@ void RPZRecordToPolicy(const DNSRecord& dr, std::shared_ptr<DNSFilterEngine::Zon
   }
 }
 
-shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zoneName, std::shared_ptr<DNSFilterEngine::Zone> zone, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress)
+shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zoneName, std::shared_ptr<DNSFilterEngine::Zone> zone, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress, uint16_t axfrTimeout)
 {
   L<<Logger::Warning<<"Loading RPZ zone '"<<zoneName<<"' from "<<master.toStringWithPort()<<endl;
   if(!tt.name.empty())
@@ -189,8 +189,10 @@ shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const
   Resolver::res_t nop;
   vector<DNSRecord> chunk;
   time_t last=0;
+  time_t axfrStart = time(0);
+  time_t axfrNow = time(0);
   shared_ptr<SOARecordContent> sr;
-  while(axfr.getChunk(nop, &chunk)) {
+  while(axfr.getChunk(nop, &chunk, (axfrStart + axfrTimeout - axfrNow))) {
     for(auto& dr : chunk) {
       if(dr.d_type==QType::NS || dr.d_type==QType::TSIG) {
        continue;
@@ -205,6 +207,10 @@ shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const
       RPZRecordToPolicy(dr, zone, true, defpol, maxTTL);
       nrecords++;
     } 
+    axfrNow = time(nullptr);
+    if (axfrNow - axfrStart > axfrTimeout) {
+      throw PDNSException("Total AXFR time exceeded!");
+    }
     if(last != time(0)) {
       L<<Logger::Info<<"Loaded & indexed "<<nrecords<<" policy records so far"<<endl;
       last=time(0);
index ac5751e608d23dd90d4af3dc5d888315fb473e27..aec9fd23aaa206035a6cab007a46af0fb44da615 100644 (file)
@@ -27,6 +27,6 @@
 extern bool g_logRPZChanges;
 
 void loadRPZFromFile(const std::string& fname, std::shared_ptr<DNSFilterEngine::Zone> zone, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL);
-std::shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zoneName, std::shared_ptr<DNSFilterEngine::Zone> zone, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress);
+std::shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zoneName, std::shared_ptr<DNSFilterEngine::Zone> zone, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress, const uint16_t axfrTimeout);
 void RPZRecordToPolicy(const DNSRecord& dr, std::shared_ptr<DNSFilterEngine::Zone> zone, bool addOrRemove, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL);
-void RPZIXFRTracker(const ComboAddress& master, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, size_t polZone, const TSIGTriplet &tt, size_t maxReceivedBytes, const ComboAddress& localAddress, std::shared_ptr<DNSFilterEngine::Zone> zone);
+void RPZIXFRTracker(const ComboAddress& master, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, size_t polZone, const TSIGTriplet &tt, size_t maxReceivedBytes, const ComboAddress& localAddress, std::shared_ptr<DNSFilterEngine::Zone> zone, uint16_t axfrTimeout);