ComboAddress localAddress;
ComboAddress master(master_, 53);
size_t zoneIdx;
+ std::shared_ptr<SOARecordContent> sr = nullptr;
try {
+ std::string seedFile;
std::string polName(zoneName);
- if(options) {
+
+ if (options) {
auto& have = *options;
size_t zoneSizeHint = 0;
parseRPZParameters(have, polName, defpol, maxTTL, zoneSizeHint);
if (zoneSizeHint > 0) {
zone->reserve(zoneSizeHint);
}
+
if(have.count("tsigname")) {
tt.name=DNSName(toLower(boost::get<string>(constGet(have, "tsigname"))));
tt.algo=DNSName(toLower(boost::get<string>(constGet(have, "tsigalgo"))));
if(B64Decode(boost::get<string>(constGet(have, "tsigsecret")), tt.secret))
throw std::runtime_error("TSIG secret is not valid Base-64 encoded");
}
+
if(have.count("refresh")) {
refresh = boost::get<uint32_t>(constGet(have,"refresh"));
}
+
if(have.count("maxReceivedMBytes")) {
maxReceivedXFRMBytes = static_cast<size_t>(boost::get<uint32_t>(constGet(have,"maxReceivedMBytes")));
}
+
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(have.count("seedFile")) {
+ seedFile = boost::get<std::string>(constGet(have, "seedFile"));
+ }
}
+
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()+").");
}
- zone->setDomain(DNSName(zoneName));
+ DNSName domain(zoneName);
+ zone->setDomain(domain);
zone->setName(polName);
zone->setRefresh(refresh);
zoneIdx = lci.dfe.addZone(zone);
+
+ if (!seedFile.empty()) {
+ sr = loadRPZFromFile(seedFile, zone, defpol, maxTTL);
+ if (zone->getDomain() != domain) {
+ throw PDNSException("The RPZ zone " + zoneName + " loaded from the seed file (" + zone->getDomain().toString() + ") does not match the one passed in parameter (" + domain.toString() + ")");
+ }
+
+ if (sr == nullptr) {
+ throw PDNSException("The RPZ zone " + zoneName + " loaded from the seed file (" + zone->getDomain().toString() + ") has no SOA record");
+ }
+ }
}
catch(const std::exception& e) {
g_log<<Logger::Error<<"Problem configuring 'rpzMaster': "<<e.what()<<endl;
try {
if (!checkOnly) {
- std::thread t(RPZIXFRTracker, master, defpol, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress, zone, axfrTimeout, lci.generation);
+ std::thread t(RPZIXFRTracker, master, defpol, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress, zone, axfrTimeout, sr, lci.generation);
t.detach();
}
}
}
// this function is silent - you do the logging
-void loadRPZFromFile(const std::string& fname, std::shared_ptr<DNSFilterEngine::Zone> zone, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL)
+std::shared_ptr<SOARecordContent> loadRPZFromFile(const std::string& fname, std::shared_ptr<DNSFilterEngine::Zone> zone, boost::optional<DNSFilterEngine::Policy> defpol, uint32_t maxTTL)
{
+ shared_ptr<SOARecordContent> sr = nullptr;
ZoneParserTNG zpt(fname);
DNSResourceRecord drr;
DNSName domain;
drr.content=".";
DNSRecord dr(drr);
if(dr.d_type == QType::SOA) {
+ sr = getRR<SOARecordContent>(dr);
domain = dr.d_name;
zone->setDomain(domain);
}
throw PDNSException("Issue parsing '"+drr.qname.toLogString()+"' '"+drr.content+"' at "+zpt.getLineOfFile()+": "+pe.reason);
}
}
+
+ return sr;
}
static std::unordered_map<std::string, shared_ptr<rpzStats> > s_rpzStats;
stats->d_numberOfRecords = numberOfRecords;
}
-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, uint64_t configGeneration)
+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, std::shared_ptr<SOARecordContent> sr, uint64_t configGeneration)
{
+ bool isPreloaded = sr != nullptr;
uint32_t refresh = zone->getRefresh();
DNSName zoneName = zone->getDomain();
std::string polName = zone->getName() ? *(zone->getName()) : zoneName.toString();
- shared_ptr<SOARecordContent> sr;
while (!sr) {
+ /* if we received an empty sr, the zone was not really preloaded */
+
try {
sr=loadRPZFromServer(master, zoneName, zone, defpol, maxTTL, tt, maxReceivedBytes, localAddress, axfrTimeout);
if(refresh == 0) {
}
auto luaconfsLocal = g_luaconfs.getLocal();
+ bool skipRefreshDelay = isPreloaded;
for(;;) {
DNSRecord dr;
dr.d_content=sr;
- sleep(refresh);
+ if (skipRefreshDelay) {
+ skipRefreshDelay = false;
+ }
+ else {
+ sleep(refresh);
+ }
if (luaconfsLocal->generation != configGeneration) {
/* the configuration has been reloaded, meaning that a new thread
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> 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, 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, uint16_t axfrTimeout, uint64_t configGeneration);
+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, shared_ptr<SOARecordContent> sr, uint64_t configGeneration);
struct rpzStats
{