Skip to content

Commit

Permalink
Merge pull request #6237 from aerique:bugfix/rec-rpz-zone-load-fail
Browse files Browse the repository at this point in the history
Retry loading RPZ zones from server.
  • Loading branch information
aerique committed Feb 13, 2018
1 parent 6b0f00e commit 209955c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 32 deletions.
8 changes: 8 additions & 0 deletions pdns/filterpo.hh
Expand Up @@ -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);
Expand Down
54 changes: 31 additions & 23 deletions pdns/rec-lua-conf.cc
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
39 changes: 31 additions & 8 deletions pdns/reczones.cc
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion pdns/rpzloader.hh
Expand Up @@ -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);

0 comments on commit 209955c

Please sign in to comment.