Though regression test is not happy yet this should be an improvement.
Also refactor qnameRPZHit a bit.
bool DNSFilterEngine::getClientPolicy(const ComboAddress& ca, const std::unordered_map<std::string,bool>& discardedPolicies, Policy& pol) const
{
+ // cout<<"Got question for "<<qname<<" from "<<ca.toString()<<endl;
std::vector<bool> zoneEnabled(d_zones.size());
size_t count = 0;
bool allEmpty = true;
}
if (allEmpty) {
- //cerr << " allempty" << endl;
return false;
}
}
if (allEmpty) {
- //cerr << " allempty" << endl;
return false;
}
return true;
}
}
- //cerr << "no hit on " << qname << endl;
+
++count;
}
}
#endif
-#if 0
/**
* Chases the CNAME provided by the PolicyCustom RPZ policy.
*
sr.setWantsRPZ(oldWantsRPZ);
}
}
-#endif
static bool addRecordToPacket(DNSPacketWriter& pw, const DNSRecord& rec, uint32_t& minTTL, uint32_t ttlCap, const uint16_t maxAnswerSize)
{
enum class PolicyResult : uint8_t { NoAction, HaveAnswer, Drop };
-static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy, const std::unique_ptr<DNSComboWriter>& dc, SyncRes& sr, int& res, vector<DNSRecord>& ret, DNSPacketWriter& pw)
+static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy, const std::unique_ptr<DNSComboWriter>& dc, SyncRes& sr, int& res, vector<DNSRecord>& ret, DNSPacketWriter& pw, bool post)
{
/* don't account truncate actions for TCP queries, since they are not applied */
if (appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::Truncate || !dc->d_tcp) {
return PolicyResult::HaveAnswer;
}
return PolicyResult::NoAction;
+
case DNSFilterEngine::PolicyKind::Custom:
- return PolicyResult::NoAction; // Now handled in syncres
-#if 0
- ret.clear();
res = RCode::NoError;
- {
+ if (post && ret.size() == 0) { // can happen with NS matches, those do not fill the result
auto spoofed = appliedPolicy.getCustomRecords(dc->d_mdp.d_qname, dc->d_mdp.d_qtype);
for (auto& dr : spoofed) {
ret.push_back(dr);
}
}
}
- return PolicyResult::HaveAnswer;
-#endif
+ return post ? PolicyResult::HaveAnswer : PolicyResult::NoAction;
}
return PolicyResult::NoAction;
sr.setWantsRPZ(wantsRPZ);
if (wantsRPZ && appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) {
- auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw);
+ auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, false);
if (policyResult == PolicyResult::HaveAnswer) {
goto haveAnswer;
}
if (appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction) {
throw PDNSException("NoAction policy returned while a NSDNAME or NSIP trigger was hit");
}
- auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw);
+ auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, true);
if (policyResult == PolicyResult::HaveAnswer) {
goto haveAnswer;
}
if (wantsRPZ) { //XXX This block is repeated, see above
- auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw);
+ auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, true);
if (policyResult == PolicyResult::HaveAnswer) {
goto haveAnswer;
}
return ret;
}
-bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype)
+bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord> &ret)
{
- //cerr << "wants: " << target << '/' << qtype.getName() << ' ' << d_wantsRPZ << ' ' << int(d_appliedPolicy.d_type) << ' ' << int(d_appliedPolicy.d_kind) << endl;
- if (d_wantsRPZ) {
- //cerr << "check" << endl;
- bool match = dfe.getQueryPolicy(target, d_discardedPolicies, d_appliedPolicy, true);
- if (match) {
- mergePolicyTags(d_policyTags, d_appliedPolicy.getTags());
- if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) {
- LOG(" (CNAME hit by RPZ policy '" + d_appliedPolicy.getName() + "')");
- if (d_appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::Custom) {
- auto spoofed = d_appliedPolicy.getCustomRecords(target, qtype.getCode());
- for (auto& dr : spoofed) {
- auto content = getRR<CNAMERecordContent>(dr);
- if (content) {
- target = content->getTarget();
- //cerr << "NEW TARGET " << target << endl;
- return false;
- }
- }
- }
- //cerr << "OTHER POLICY HIT" << endl;
- return true;
- }
+ if (!d_wantsRPZ) {
+ return false;
+ }
+
+ bool match = dfe.getQueryPolicy(target, d_discardedPolicies, d_appliedPolicy, true);
+ if (!match) {
+ return false;
+ }
+
+ mergePolicyTags(d_policyTags, d_appliedPolicy.getTags());
+ if (d_appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction) {
+ return false;
+ }
+ LOG(": (hit by RPZ policy '" + d_appliedPolicy.getName() + "')" << endl);
+ if (d_appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::Truncate) {
+ // XXX We don't know if we're doing TCP here....
+ return false;
+ }
+ if (d_appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::Custom) {
+ return true;
+ }
+ auto spoofed = d_appliedPolicy.getCustomRecords(target, qtype.getCode());
+ for (const auto& dr : spoofed) {
+ if (dr.d_place != DNSResourceRecord::ANSWER) {
+ continue;
+ }
+ ret.push_back(dr);
+ auto content = getRR<CNAMERecordContent>(dr);
+ if (content) {
+ target = content->getTarget();
+ return qnameRPZHit(dfe, target, qtype, ret);
}
}
- //cerr << "NOMATCH" << endl;
- return false;
+
+ return true;
}
#define QLOG(x) LOG(prefix << " child=" << child << ": " << x << endl)
int SyncRes::doResolve(const DNSName &qnameArg, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state) {
+ DNSName qname(qnameArg);
auto luaconfsLocal = g_luaconfs.getLocal();
- DNSName qname(qnameArg);
- bool hit = qnameRPZHit(luaconfsLocal->dfe, qname, qtype);
+ // Can change qname
+ bool hit = qnameRPZHit(luaconfsLocal->dfe, qname, qtype, ret);
if (hit) {
throw PolicyHitException();
}
bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType& qtype, LWResult& lwr, boost::optional<Netmask>& ednsmask, const DNSName& auth, bool const sendRDQuery, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool* truncated);
bool processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType& qtype, DNSName& auth, bool wasForwarded, const boost::optional<Netmask> ednsmask, bool sendRDQuery, NsSet &nameservers, std::vector<DNSRecord>& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state);
- bool qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype);
+ bool qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord>& ret);
int doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state);
int doResolveNoQNameMinimization(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state, bool* fromCache = NULL, StopAtDelegation* stopAtDelegation = NULL, bool considerforwards = true);
bool doOOBResolve(const AuthDomain& domain, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, int& res);