return ret;
}
-bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord> &ret)
+bool SyncRes::qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord> &ret, unsigned int depth)
{
if (!d_wantsRPZ) {
return false;
}
+ if (s_maxdepth && depth > s_maxdepth) {
+ string prefix = d_prefix;
+ prefix.append(depth, ' ');
+ string msg = "More than " + std::to_string(s_maxdepth) + " (max-recursion-depth) levels of recursion needed while resolving " + target.toLogString();
+ LOG(prefix << target << ": " << msg << endl);
+ throw ImmediateServFailException(msg);
+ }
bool match = dfe.getQueryPolicy(target, d_discardedPolicies, d_appliedPolicy, true);
if (!match) {
return true;
}
auto spoofed = d_appliedPolicy.getCustomRecords(target, qtype.getCode());
+
+ // Add the record to the result vector being built, chase if we hit a CNAME
for (const auto& dr : spoofed) {
if (dr.d_place != DNSResourceRecord::ANSWER) {
continue;
auto content = getRR<CNAMERecordContent>(dr);
if (content) {
target = content->getTarget();
- return qnameRPZHit(dfe, target, qtype, ret);
+ // This call wil return true if we hit a policy that needs an throw PolicyHitException
+ // For CNAME chasing, we don't want that since resolving should continue with the new target
+ return qnameRPZHit(dfe, target, qtype, ret, depth + 1);
}
}
auto luaconfsLocal = g_luaconfs.getLocal();
// Can change qname
- bool hit = qnameRPZHit(luaconfsLocal->dfe, qname, qtype, ret);
+ bool hit = qnameRPZHit(luaconfsLocal->dfe, qname, qtype, ret, depth + 1);
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, vector<DNSRecord>& ret);
+ bool qnameRPZHit(const DNSFilterEngine& dfe, DNSName& target, const QType& qtype, vector<DNSRecord>& ret, unsigned int depth);
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);