The policy action are:
-* Policy.Custom will return a NoError, CNAME answer with the value specified with `defcontent`
+* Policy.Custom will return a NoError, CNAME answer with the value specified with `defcontent`, when looking up the result of this CNAME, RPZ is not taken into account
* Policy.Drop will simply cause the query to be dropped
* Policy.NoAction will continue normal processing of the query
* Policy.NODATA will return a NoError response with no value in the answer section
}
#endif
+/**
+ * Chases the CNAME provided by the PolicyCustom RPZ policy.
+ *
+ * @param spoofed: The DNSRecord that was created by the policy, should already be added to ret
+ * @param qtype: The QType of the original query
+ * @param sr: A SyncRes
+ * @param res: An integer that will contain the RCODE of the lookup we do
+ * @param ret: A vector of DNSRecords where the result of the CNAME chase should be appended to
+ */
+void handleRPZCustom(const DNSRecord& spoofed, const QType& qtype, SyncRes& sr, int& res, vector<DNSRecord>& ret)
+{
+ if (spoofed.d_type == QType::CNAME) {
+ bool oldWantsRPZ = sr.d_wantsRPZ;
+ sr.d_wantsRPZ = false;
+ vector<DNSRecord> ans;
+ res = sr.beginResolve(DNSName(spoofed.d_content->getZoneRepresentation()), qtype, 1, ans);
+ for (const auto& rec : ans) {
+ if(rec.d_place == DNSResourceRecord::ANSWER) {
+ ret.push_back(rec);
+ }
+ }
+ // Reset the RPZ state of the SyncRes
+ sr.d_wantsRPZ = oldWantsRPZ;
+ }
+}
+
void startDoResolve(void *p)
{
DNSComboWriter* dc=(DNSComboWriter *)p;
spoofed.d_content = appliedPolicy.d_custom;
spoofed.d_place = DNSResourceRecord::ANSWER;
ret.push_back(spoofed);
+ handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret);
goto haveAnswer;
case DNSFilterEngine::PolicyKind::Truncate:
if(!dc->d_tcp) {
spoofed.d_content = appliedPolicy.d_custom;
spoofed.d_place = DNSResourceRecord::ANSWER;
ret.push_back(spoofed);
+ handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret);
goto haveAnswer;
}
}
spoofed.d_content = appliedPolicy.d_custom;
spoofed.d_place = DNSResourceRecord::ANSWER;
ret.push_back(spoofed);
+ handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret);
goto haveAnswer;
}
}
Reply to question for qname='www3.example.net.', qtype=A
Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0
0 www3.example.net. IN CNAME 0 www2.example.net.
+0 www2.example.net. IN A 10 192.0.2.2
Reply to question for qname='android.marvin.example.net.', qtype=A
Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0
0 android.marvin.example.net. IN A 15 192.0.2.5
Reply to question for qname='www.example.net.', qtype=A
Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0
0 www.example.net. IN CNAME 0 www2.example.net.
+0 www2.example.net. IN A 15 192.0.2.2
==> www4.example.net RPZ IP trigger action, dropped
==> trillian.example.net NXDOMAIN
Reply to question for qname='trillian.example.net.', qtype=A