]> granicus.if.org Git - pdns/commitdiff
Merge pull request #6237 from aerique:bugfix/rec-rpz-zone-load-fail
authoraerique <aerique@xs4all.nl>
Tue, 13 Feb 2018 15:44:34 +0000 (16:44 +0100)
committerGitHub <noreply@github.com>
Tue, 13 Feb 2018 15:44:34 +0000 (16:44 +0100)
Retry loading RPZ zones from server.

pdns/filterpo.hh
pdns/rec-lua-conf.cc
pdns/reczones.cc
pdns/rpzloader.hh

index 69e1fc56be3b670fb0e3ab223efc939aefb50abe..c57fe9974fa54cf6dc6e5cf391e1cfb3fbf0ff94 100644 (file)
@@ -122,6 +122,14 @@ public:
     {
       return d_name;
     }
+    DNSName getDomain()
+    {
+      return d_domain;
+    }
+    uint32_t getRefresh()
+    {
+      return d_refresh;
+    }
     void dump(FILE * fp) const;
 
     void addClientTrigger(const Netmask& nm, Policy pol);
index 3353df34da1bb1305fbf02b4b22978af16912421..882ae4efe6a3b427db1447c41b94017fe5faf3ac 100644 (file)
@@ -135,15 +135,19 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly)
     });
 
   Lua.writeFunction("rpzMaster", [&lci, checkOnly](const string& master_, const string& zoneName, const boost::optional<std::unordered_map<string,boost::variant<uint32_t, string>>>& options) {
+
+      boost::optional<DNSFilterEngine::Policy> defpol;
+      std::shared_ptr<DNSFilterEngine::Zone> zone = std::make_shared<DNSFilterEngine::Zone>();
+      TSIGTriplet tt;
+      uint32_t refresh=0;
+      size_t maxReceivedXFRMBytes = 0;
+      uint32_t maxTTL = std::numeric_limits<uint32_t>::max();
+      ComboAddress localAddress;
+      ComboAddress master(master_, 53);
+      size_t zoneIdx;
+
       try {
-        boost::optional<DNSFilterEngine::Policy> defpol;
-        std::shared_ptr<DNSFilterEngine::Zone> zone = std::make_shared<DNSFilterEngine::Zone>();
-        TSIGTriplet tt;
-        uint32_t refresh=0;
         std::string polName(zoneName);
-        size_t maxReceivedXFRMBytes = 0;
-        uint32_t maxTTL = std::numeric_limits<uint32_t>::max();
-        ComboAddress localAddress;
         if(options) {
           auto& have = *options;
           size_t zoneSizeHint = 0;
@@ -167,35 +171,39 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly)
             localAddress = ComboAddress(boost::get<string>(constGet(have,"localAddress")));
           }
         }
-        ComboAddress master(master_, 53);
         if (localAddress != ComboAddress() && localAddress.sin4.sin_family != master.sin4.sin_family) {
           // We were passed a localAddress, check if its AF matches the master's
           throw PDNSException("Master address("+master.toString()+") is not of the same Address Family as the local address ("+localAddress.toString()+").");
         }
 
-        DNSName domain(zoneName);
-        zone->setDomain(domain);
+        zone->setDomain(DNSName(zoneName));
         zone->setName(polName);
         zone->setRefresh(refresh);
-        size_t zoneIdx = lci.dfe.addZone(zone);
-
-        if (!checkOnly) {
-          auto sr=loadRPZFromServer(master, domain, zone, defpol, maxTTL, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress);
-          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);
-          t.detach();
-        }
+        zoneIdx = lci.dfe.addZone(zone);
       }
       catch(const std::exception& e) {
-        theL()<<Logger::Error<<"Unable to load RPZ zone '"<<zoneName<<"' from '"<<master_<<"': "<<e.what()<<endl;
+        theL()<<Logger::Error<<"Problem configuring 'rpzMaster': "<<e.what()<<endl;
+        exit(1);  // FIXME proper exit code?
       }
       catch(const PDNSException& e) {
-        theL()<<Logger::Error<<"Unable to load RPZ zone '"<<zoneName<<"' from '"<<master_<<"': "<<e.reason<<endl;
+        theL()<<Logger::Error<<"Problem configuring 'rpzMaster': "<<e.reason<<endl;
+        exit(1);  // FIXME proper exit code?
       }
 
+      try {
+          if (!checkOnly) {
+            std::thread t(RPZIXFRTracker, master, defpol, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress, zone);
+            t.detach();
+          }
+      }
+      catch(const std::exception& e) {
+        theL()<<Logger::Error<<"Problem starting RPZIXFRTracker thread: "<<e.what()<<endl;
+        exit(1);  // FIXME proper exit code?
+      }
+      catch(const PDNSException& e) {
+        theL()<<Logger::Error<<"Problem starting RPZIXFRTracker thread: "<<e.reason<<endl;
+        exit(1);  // FIXME proper exit code?
+      }
     });
 
   typedef vector<pair<int,boost::variant<string, vector<pair<int, string> > > > > argvec_t;
index eb945e2fcd8abd1428e9dcfb67ff845b13c6424e..b4c84a95fe2cf4c23fff1abdd43286979099062c 100644 (file)
@@ -318,15 +318,38 @@ 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, 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)
 {
-  uint32_t refresh = oursr->d_st.refresh;
+  uint32_t refresh = zone->getRefresh();
+  DNSName zoneName = zone->getDomain();
+  shared_ptr<SOARecordContent> sr;
+
+  while (!sr) {
+    try {
+      sr=loadRPZFromServer(master, zoneName, zone, defpol, maxTTL, tt, maxReceivedBytes, localAddress);
+      if(refresh) {
+        sr->d_st.refresh=refresh;
+      }
+      zone->setSerial(sr->d_st.serial);
+    }
+    catch(const std::exception& e) {
+      theL()<<Logger::Warning<<"Unable to load RPZ zone '"<<zoneName<<"' from '"<<master<<"': '"<<e.what()<<"'. (Will try again in "<<refresh<<" seconds...)"<<endl;
+    }
+    catch(const PDNSException& e) {
+      theL()<<Logger::Warning<<"Unable to load RPZ zone '"<<zoneName<<"' from '"<<master<<"': '"<<e.reason<<"'. (Will try again in "<<refresh<<" seconds...)"<<endl;
+    }
+
+    if (!sr) {
+      sleep(refresh);
+    }
+  }
+
   for(;;) {
     DNSRecord dr;
-    dr.d_content=oursr;
+    dr.d_content=sr;
 
     sleep(refresh);
-    
+
     L<<Logger::Info<<"Getting IXFR deltas for "<<zoneName<<" from "<<master.toStringWithPort()<<", our serial: "<<getRR<SOARecordContent>(dr)->d_st.serial<<endl;
     vector<pair<vector<DNSRecord>, vector<DNSRecord> > > deltas;
 
@@ -362,7 +385,7 @@ void RPZIXFRTracker(const ComboAddress& master, const DNSName& zoneName, boost::
           continue;
        if(rr.d_type == QType::SOA) {
          auto oldsr = getRR<SOARecordContent>(rr);
-         if(oldsr && oldsr->d_st.serial == oursr->d_st.serial) {
+         if(oldsr && oldsr->d_st.serial == sr->d_st.serial) {
            //      cout<<"Got good removal of SOA serial "<<oldsr->d_st.serial<<endl;
          }
          else
@@ -382,7 +405,7 @@ void RPZIXFRTracker(const ComboAddress& master, const DNSName& zoneName, boost::
          auto newsr = getRR<SOARecordContent>(rr);
          //      L<<Logger::Info<<"New SOA serial for "<<zoneName<<": "<<newsr->d_st.serial<<endl;
          if (newsr) {
-           oursr = newsr;
+           sr = newsr;
          }
        }
        else {
@@ -392,8 +415,8 @@ void RPZIXFRTracker(const ComboAddress& master, const DNSName& zoneName, boost::
        }
       }
     }
-    L<<Logger::Info<<"Had "<<totremove<<" RPZ removal"<<addS(totremove)<<", "<<totadd<<" addition"<<addS(totadd)<<" for "<<zoneName<<" New serial: "<<oursr->d_st.serial<<endl;
-    newZone->setSerial(oursr->d_st.serial);
+    L<<Logger::Info<<"Had "<<totremove<<" RPZ removal"<<addS(totremove)<<", "<<totadd<<" addition"<<addS(totadd)<<" for "<<zoneName<<" New serial: "<<sr->d_st.serial<<endl;
+    newZone->setSerial(sr->d_st.serial);
 
     /* we need to replace the existing zone with the new one,
        but we don't want to touch anything else, especially other zones,
index 37b79c5f5996747d8ea7688405a0f71f6477524d..ac5751e608d23dd90d4af3dc5d888315fb473e27 100644 (file)
@@ -29,4 +29,4 @@ 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);
 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, 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);