Retry loading RPZ zones from server.
{
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);
});
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;
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;
}
-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;
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
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 {
}
}
}
- 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,
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);