From: Remi Gacogne Date: Tue, 4 May 2021 10:29:32 +0000 (+0200) Subject: rec: Apply dns64 on RPZ hits generated after a gettag_ffi hit X-Git-Tag: rec-4.4.4~3^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=291cab063ae85c6387da05d5895a405e8f0978aa;p=thirdparty%2Fpdns.git rec: Apply dns64 on RPZ hits generated after a gettag_ffi hit We do special case the qname RPZ processing after a gettag_ffi hit, leading to dns64 to not be applied in that case. This commit adds dns64 handling to the special case. (cherry picked from commit 92f829c42ef82b6d5d0804886519536137925f23) --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 4a2e9e5610..ab13f9949c 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1281,6 +1281,24 @@ int getFakePTRRecords(const DNSName& qname, vector& ret) return rcode; } +static bool answerIsNOData(uint16_t requestedType, int rcode, const std::vector& records) +{ + if (rcode != RCode::NoError) { + return false; + } + for (const auto& rec : records) { + if (rec.d_place != DNSResourceRecord::ANSWER) { + /* no records in the answer section */ + return true; + } + if (rec.d_type == requestedType) { + /* we have a record, of the right type, in the right section */ + return false; + } + } + return true; +} + static void startDoResolve(void *p) { auto dc=std::unique_ptr(reinterpret_cast(p)); @@ -1533,6 +1551,10 @@ static void startDoResolve(void *p) else { auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw); if (policyResult == PolicyResult::HaveAnswer) { + if (dq.qtype == QType::AAAA && answerIsNOData(dc->d_mdp.d_qtype, res, ret) && g_dns64Prefix) { + res = getFakeAAAARecords(dq.qname, *g_dns64Prefix, ret); + shouldNotValidate = true; + } goto haveAnswer; } else if (policyResult == PolicyResult::Drop) { @@ -1594,15 +1616,7 @@ static void startDoResolve(void *p) if (t_pdl || (g_dns64Prefix && dq.qtype == QType::AAAA && !vStateIsBogus(dq.validationState))) { if (res == RCode::NoError) { - auto i = ret.cbegin(); - for(; i!= ret.cend(); ++i) { - if (i->d_type == dc->d_mdp.d_qtype && i->d_place == DNSResourceRecord::ANSWER) { - break; - } - } - - if (i == ret.cend()) { - /* no record in the answer section, NODATA */ + if (answerIsNOData(dc->d_mdp.d_qtype, res, ret)) { if (t_pdl && t_pdl->nodata(dq, res)) { shouldNotValidate = true; } @@ -1611,9 +1625,8 @@ static void startDoResolve(void *p) shouldNotValidate = true; } } - } - else if(res == RCode::NXDomain && t_pdl && t_pdl->nxdomain(dq, res)) { + else if (res == RCode::NXDomain && t_pdl && t_pdl->nxdomain(dq, res)) { shouldNotValidate = true; }