]> git.ipfire.org Git - thirdparty/pdns.git/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>
Thu, 22 Feb 2018 11:17:50 +0000 (12:17 +0100)
(cherry picked from commit ea448a77fd2c664893e961b21d26408879e20360)

pdns/rec-lua-conf.cc
pdns/recursordist/docs/lua-config/rpz.rst
pdns/reczones.cc
pdns/rpzloader.cc
pdns/rpzloader.hh

index 3353df34da1bb1305fbf02b4b22978af16912421..b73a3849340572956897e876f2c6e20cca6d5dae 100644 (file)
@@ -142,6 +142,7 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly)
         uint32_t refresh=0;
         std::string polName(zoneName);
         size_t maxReceivedXFRMBytes = 0;
+        uint16_t axfrTimeout = 20;
         uint32_t maxTTL = std::numeric_limits<uint32_t>::max();
         ComboAddress localAddress;
         if(options) {
@@ -166,6 +167,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")));
+          }
         }
         ComboAddress master(master_, 53);
         if (localAddress != ComboAddress() && localAddress.sin4.sin_family != master.sin4.sin_family) {
@@ -180,12 +184,12 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly)
         size_t zoneIdx = lci.dfe.addZone(zone);
 
         if (!checkOnly) {
-          auto sr=loadRPZFromServer(master, domain, zone, defpol, maxTTL, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress);
+          auto sr=loadRPZFromServer(master, domain, zone, defpol, maxTTL, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress, axfrTimeout);
           if(refresh)
             sr->d_st.refresh=refresh;
           zone->setSerial(sr->d_st.serial);
 
-          std::thread t(RPZIXFRTracker, master, DNSName(zoneName), defpol, maxTTL, zoneIdx, tt, sr, maxReceivedXFRMBytes * 1024 * 1024, localAddress);
+          std::thread t(RPZIXFRTracker, master, DNSName(zoneName), defpol, maxTTL, zoneIdx, tt, sr, maxReceivedXFRMBytes * 1024 * 1024, localAddress, axfrTimeout);
           t.detach();
         }
       }
index 8bb211a5343ae12262ec8b2223694fdfa41e5d52..71725bef91b3d2f49c467c68aa97b0a85ea5a384 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 afaf3575e9eb36f830d7b0ec3e6e8c2d944844cc..6f76419c88be681ab4dc3f1bd5c00953435ce5ac 100644 (file)
@@ -318,7 +318,7 @@ string reloadAuthAndForwards()
 }
 
 
-void RPZIXFRTracker(const ComboAddress& master, const DNSName& zoneName, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, size_t zoneIdx, const TSIGTriplet& tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes, const ComboAddress& localAddress)
+void RPZIXFRTracker(const ComboAddress& master, const DNSName& zoneName, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, size_t zoneIdx, const TSIGTriplet& tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes, const ComboAddress& localAddress, const uint16_t axfrTimeout)
 {
   uint32_t refresh = oursr->d_st.refresh;
   for(;;) {
index b5977d9d0467d0976c420844b25fb002ba1ae43f..7bc08cf4649b33823c6a6fc7d317af17808e180f 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 37b79c5f5996747d8ea7688405a0f71f6477524d..e343f597d2a6462d975ddb61aad03e14f1d7d5f3 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, const DNSName& zoneName, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, size_t polZone, const TSIGTriplet &tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes, const ComboAddress& localAddress);
+void RPZIXFRTracker(const ComboAddress& master, const DNSName& zoneName, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL, size_t polZone, const TSIGTriplet &tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes, const ComboAddress& localAddress, const uint16_t axfrTimeout);