return findNamedPolicy(d_qpolName, qname, pol);
}
+bool DNSFilterEngine::Zone::findExactQNamePolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const
+{
+ return findExactNamedPolicy(d_qpolName, qname, pol);
+}
+
bool DNSFilterEngine::Zone::findNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const
{
return findNamedPolicy(d_propolName, qname, pol);
}
+bool DNSFilterEngine::Zone::findExactNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const
+{
+ return findExactNamedPolicy(d_propolName, qname, pol);
+}
+
bool DNSFilterEngine::Zone::findNSIPPolicy(const ComboAddress& addr, DNSFilterEngine::Policy& pol) const
{
if (const auto fnd = d_propolNSAddr.lookup(addr)) {
return false;
}
-bool DNSFilterEngine::Zone::findNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol) const
+bool DNSFilterEngine::Zone::findNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol)
{
+ if (polmap.empty()) {
+ return false;
+ }
+
/* for www.powerdns.com, we need to check:
www.powerdns.com.
*.powerdns.com.
return false;
}
+bool DNSFilterEngine::Zone::findExactNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol)
+{
+ if (polmap.empty()) {
+ return false;
+ }
+
+ const auto& it = polmap.find(qname);
+ if (it != polmap.end()) {
+ pol = it->second;
+ return true;
+ }
+
+ return false;
+}
+
DNSFilterEngine::Policy DNSFilterEngine::getProcessingPolicy(const DNSName& qname, const std::unordered_map<std::string,bool>& discardedPolicies) const
{
- // cout<<"Got question for nameserver name "<<qname<<endl;
- Policy pol;
- for(const auto& z : d_zones) {
+ // cout<<"Got question for nameserver name "<<qname<<endl;
+ std::vector<bool> zoneEnabled(d_zones.size());
+ size_t count = 0;
+ bool allEmpty = true;
+ for (const auto& z : d_zones) {
+ bool enabled = true;
const auto zoneName = z->getName();
- if(zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) {
- continue;
+ if (zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) {
+ enabled = false;
+ }
+ else {
+ if (z->hasNSPolicies()) {
+ allEmpty = false;
+ }
+ else {
+ enabled = false;
+ }
}
- if(z->findNSPolicy(qname, pol)) {
- // cerr<<"Had a hit on the nameserver ("<<qname<<") used to process the query"<<endl;
- return pol;
+ zoneEnabled[count] = enabled;
+ ++count;
+ }
+
+ Policy pol;
+ if (!allEmpty) {
+ count = 0;
+ for(const auto& z : d_zones) {
+ if (zoneEnabled[count] && z->findNSPolicy(qname, pol)) {
+ // cerr<<"Had a hit on the nameserver ("<<qname<<") used to process the query"<<endl;
+ return pol;
+ }
+ ++count;
+ }
+
+ DNSName s(qname);
+ while(s.chopOff()){
+ count = 0;
+ for(const auto& z : d_zones) {
+ if (zoneEnabled[count] && z->findNSPolicy(g_wildcarddnsname+s, pol)) {
+ // cerr<<"Had a hit on the nameserver ("<<qname<<") used to process the query"<<endl;
+ return pol;
+ }
+ ++count;
+ }
}
}
+
return pol;
}
DNSFilterEngine::Policy DNSFilterEngine::getQueryPolicy(const DNSName& qname, const ComboAddress& ca, const std::unordered_map<std::string,bool>& discardedPolicies) const
{
// cout<<"Got question for "<<qname<<" from "<<ca.toString()<<endl;
- Policy pol;
- for(const auto& z : d_zones) {
+ std::vector<bool> zoneEnabled(d_zones.size());
+ size_t count = 0;
+ bool allEmpty = true;
+ for (const auto& z : d_zones) {
+ bool enabled = true;
const auto zoneName = z->getName();
- if(zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) {
- continue;
+ if (zoneName && discardedPolicies.find(*zoneName) != discardedPolicies.end()) {
+ enabled = false;
+ }
+ else {
+ if (z->hasQNamePolicies()) {
+ allEmpty = false;
+ }
+ else {
+ enabled = false;
+ }
}
- if(z->findQNamePolicy(qname, pol)) {
- // cerr<<"Had a hit on the name of the query"<<endl;
- return pol;
+ zoneEnabled[count] = enabled;
+ ++count;
+ }
+
+ Policy pol;
+ if (!allEmpty) {
+ count = 0;
+ for(const auto& z : d_zones) {
+ if (zoneEnabled[count] && z->findExactQNamePolicy(qname, pol)) {
+ // cerr<<"Had a hit on the name of the query"<<endl;
+ return pol;
+ }
+ ++count;
}
- if(z->findClientPolicy(ca, pol)) {
+ DNSName s(qname);
+ while(s.chopOff()){
+ count = 0;
+ for(const auto& z : d_zones) {
+ if (zoneEnabled[count] && z->findExactQNamePolicy(g_wildcarddnsname+s, pol)) {
+ // cerr<<"Had a hit on the name of the query"<<endl;
+ return pol;
+ }
+ ++count;
+ }
+ }
+ }
+
+ count = 0;
+ for(const auto& z : d_zones) {
+ if (zoneEnabled[count] && z->findClientPolicy(ca, pol)) {
// cerr<<"Had a hit on the IP address ("<<ca.toString()<<") of the client"<<endl;
return pol;
}
return result;
}
-void DNSFilterEngine::Zone::dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol) const
+void DNSFilterEngine::Zone::dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol)
{
auto records = pol.getRecords(name);
for (const auto& dr : records) {
}
-void DNSFilterEngine::Zone::dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol) const
+void DNSFilterEngine::Zone::dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol)
{
DNSName full = maskToRPZ(nm);
full += name;
size_t size() const
{
return d_qpolAddr.size() + d_postpolAddr.size() + d_propolName.size() + d_propolNSAddr.size() + d_qpolName.size();
-
}
void dump(FILE * fp) const;
bool rmResponseTrigger(const Netmask& nm, const Policy& pol);
bool findQNamePolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const;
+ bool findExactQNamePolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const;
bool findNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const;
+ bool findExactNSPolicy(const DNSName& qname, DNSFilterEngine::Policy& pol) const;
bool findNSIPPolicy(const ComboAddress& addr, DNSFilterEngine::Policy& pol) const;
bool findResponsePolicy(const ComboAddress& addr, DNSFilterEngine::Policy& pol) const;
bool findClientPolicy(const ComboAddress& addr, DNSFilterEngine::Policy& pol) const;
+ bool hasClientPolicies() const
+ {
+ return !d_qpolAddr.empty();
+ }
+ bool hasQNamePolicies() const
+ {
+ return !d_qpolName.empty();
+ }
+ bool hasNSPolicies() const
+ {
+ return !d_propolName.empty();
+ }
+ bool hasNSIPPolicies() const
+ {
+ return !d_propolNSAddr.empty();
+ }
+ bool hasResponsePolicies() const
+ {
+ return !d_postpolAddr.empty();
+ }
+
private:
static DNSName maskToRPZ(const Netmask& nm);
- bool findNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol) const;
- void dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol) const;
- void dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol) const;
+ static bool findExactNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol);
+ static bool findNamedPolicy(const std::unordered_map<DNSName, DNSFilterEngine::Policy>& polmap, const DNSName& qname, DNSFilterEngine::Policy& pol);
+ static void dumpNamedPolicy(FILE* fp, const DNSName& name, const Policy& pol);
+ static void dumpAddrPolicy(FILE* fp, const Netmask& nm, const DNSName& name, const Policy& pol);
std::unordered_map<DNSName, Policy> d_qpolName; // QNAME trigger (RPZ)
NetmaskTree<Policy> d_qpolAddr; // Source address
z->clear();
}
}
+ void clearZones()
+ {
+ d_zones.clear();
+ }
const std::shared_ptr<Zone> getZone(size_t zoneIdx) const
{
std::shared_ptr<Zone> result{nullptr};