return rcode;
}
-static bool answerIsNOData(uint16_t requestedType, int rcode, const std::vector<DNSRecord>& 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;
-}
-
// RFC 6147 section 5.1 all rcodes except NXDomain should be candidate for dns64
// for NoError, check if it is NoData
static bool dns64Candidate(uint16_t requestedType, int rcode, const std::vector<DNSRecord>& records)
{
if (rcode == RCode::NoError) {
- return answerIsNOData(requestedType, rcode, records);
+ return SyncRes::answerIsNOData(requestedType, rcode, records);
}
return rcode != RCode::NXDomain;
}
bool luaHookHandled = false;
if (dc->d_luaContext) {
PolicyResult policyResult = PolicyResult::NoAction;
- if (answerIsNOData(dc->d_mdp.d_qtype, res, ret)) {
+ if (SyncRes::answerIsNOData(dc->d_mdp.d_qtype, res, ret)) {
if (dc->d_luaContext->nodata(dq, res, sr.d_eventTrace)) {
luaHookHandled = true;
shouldNotValidate = true;
}
return res;
}
+
+bool SyncRes::answerIsNOData(uint16_t requestedType, int rcode, const std::vector<DNSRecord>& records)
+{
+ if (rcode != RCode::NoError) {
+ return false;
+ }
+
+ // NOLINTNEXTLINE(readability-use-anyofallof)
+ for (const auto& rec : records) {
+ if (rec.d_place == DNSResourceRecord::ANSWER && rec.d_type == requestedType) {
+ /* we have a record, of the right type, in the right section */
+ return false;
+ }
+ }
+ return true;
+#if 0
+ // This code should be equivalent to the code above, clang-tidy prefers any_of()
+ // I have doubts if that is easier to read
+ return !std::any_of(records.begin(), records.end(), [=](const DNSRecord& rec) {
+ return rec.d_place == DNSResourceRecord::ANSWER && rec.d_type == requestedType;
+ });
+#endif
+}
BOOST_CHECK_GT(secondTTL, 0);
}
+BOOST_AUTO_TEST_CASE(test_nodata_ok)
+{
+ vector<DNSRecord> vec;
+ vec.emplace_back("nz.compass.com", nullptr, QType::CNAME, QClass::IN, 60, 0, DNSResourceRecord::ANSWER);
+ vec.emplace_back("nz.compass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::ANSWER);
+ vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::NSEC3, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY);
+ vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY);
+
+ BOOST_CHECK(SyncRes::answerIsNOData(QType::A, RCode::NoError, vec));
+}
+
+BOOST_AUTO_TEST_CASE(test_nodata_not)
+{
+ vector<DNSRecord> vec;
+ vec.emplace_back("kc-pro.westeurope.cloudapp.azure.com", nullptr, QType::A, QClass::IN, 60, 0, DNSResourceRecord::ANSWER);
+ vec.emplace_back("nz.compass.com", nullptr, QType::CNAME, QClass::IN, 60, 0, DNSResourceRecord::ANSWER);
+ vec.emplace_back("nz.compass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::ANSWER);
+ vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::NSEC3, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY);
+ vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY);
+
+ BOOST_CHECK(!SyncRes::answerIsNOData(QType::A, RCode::NoError, vec));
+}
+
+BOOST_AUTO_TEST_CASE(test_nodata_out_of_order)
+{
+ vector<DNSRecord> vec;
+ vec.emplace_back("nz.compass.com", nullptr, QType::CNAME, QClass::IN, 60, 0, DNSResourceRecord::ANSWER);
+ vec.emplace_back("nz.compass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::ANSWER);
+ vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::NSEC3, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY);
+ vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY);
+ vec.emplace_back("kc-pro.westeurope.cloudapp.azure.com", nullptr, QType::A, QClass::IN, 60, 0, DNSResourceRecord::ANSWER);
+
+ BOOST_CHECK(!SyncRes::answerIsNOData(QType::A, RCode::NoError, vec));
+}
+
BOOST_AUTO_TEST_SUITE_END()