Add localAddress to rpzMaster options to allow override.
Fixes #4343
* refresh = an integer describing the interval between checks for updates. By default, the RPZ zone's default is used
* maxReceivedMBytes = the maximum size in megabytes of an AXFR/IXFR update, to prevent resource exhaustion.
The default value of 0 means no restriction.
+* localAddress = The source IP address to use when transferring the RPZ. When unset, [`query-local-address(6)`](#query-local-address) is used.
If no settings are included, the RPZ is taken literally with no overrides applied.
int refresh=0;
std::string polName;
size_t maxReceivedXFRMBytes = 0;
+ ComboAddress localAddress;
if(options) {
auto& have = *options;
if(have.count("policyName")) {
if(have.count("maxReceivedMBytes")) {
maxReceivedXFRMBytes = static_cast<size_t>(boost::get<int>(constGet(have,"maxReceivedMBytes")));
}
+ if(have.count("localAddress")) {
+ 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 zone(zone_);
- auto sr=loadRPZFromServer(master, zone, lci.dfe, polName, defpol, 0, tt, maxReceivedXFRMBytes * 1024 * 1024);
+ auto sr=loadRPZFromServer(master, zone, lci.dfe, polName, defpol, 0, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress);
if(refresh)
sr->d_st.refresh=refresh;
std::thread t(RPZIXFRTracker, master, zone, polName, tt, sr, maxReceivedXFRMBytes * 1024 * 1024);
}
}
-shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& polName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt, size_t maxReceivedBytes)
+shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& polName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress)
{
L<<Logger::Warning<<"Loading RPZ zone '"<<zone<<"' from "<<master.toStringWithPort()<<endl;
if(!tt.name.empty())
L<<Logger::Warning<<"With TSIG key '"<<tt.name<<"' of algorithm '"<<tt.algo<<"'"<<endl;
- ComboAddress local= master.sin4.sin_family == AF_INET ? ComboAddress("0.0.0.0") : ComboAddress("::"); // should be configurable
+ ComboAddress local(localAddress);
+ if (local == ComboAddress())
+ local = getQueryLocalAddress(master.sin4.sin_family, 0);
+
AXFRRetriever axfr(master, zone, tt, &local, maxReceivedBytes);
unsigned int nrecords=0;
Resolver::res_t nop;
#include "dnsrecords.hh"
int loadRPZFromFile(const std::string& fname, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place);
-std::shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt, size_t maxReceivedBytes);
+std::shared_ptr<SOARecordContent> loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, const std::string& policyName, boost::optional<DNSFilterEngine::Policy> defpol, int place, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress);
void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, const std::string& policyName, bool addOrRemove, boost::optional<DNSFilterEngine::Policy> defpol, int place);
void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, const std::string& policyName, const TSIGTriplet &tt, shared_ptr<SOARecordContent> oursr, size_t maxReceivedBytes);