]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Use seperate function to test for loop; empty result vector on loop
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 5 Jun 2020 08:19:08 +0000 (10:19 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 5 Jun 2020 08:19:08 +0000 (10:19 +0200)
detection (like other resolvers I tested  do).

pdns/recursordist/test-syncres_cc1.cc
pdns/syncres.cc

index 3bb11de1002fe9a46220292a6bf97ffb45fe5277..1e048cd32d3fd719cbf335a66d5d00e78b1b5120 100644 (file)
@@ -1125,7 +1125,7 @@ BOOST_AUTO_TEST_CASE(test_cname_loop)
   vector<DNSRecord> ret;
   int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, RCode::ServFail);
-  BOOST_CHECK_GT(ret.size(), 0U);
+  BOOST_CHECK_EQUAL(ret.size(), 0U);
   BOOST_CHECK_EQUAL(count, 2U);
 }
 
index b6a3bf9d85b55b1d8a6368e2603135e70388f7c0..c01851dfe0cb2ad76e064fb50e036a4030569eef 100644 (file)
@@ -1172,6 +1172,18 @@ void SyncRes::updateValidationStatusInCache(const DNSName &qname, const QType& q
   }
 }
 
+static bool scanForCNAMELoop(const DNSName& name, const vector<DNSRecord>& records)
+{
+  for (const auto record: records) {
+    if (record.d_type == QType::CNAME && record.d_place == DNSResourceRecord::ANSWER) {
+      if (name == record.d_name) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector<DNSRecord>& ret, unsigned int depth, int &res, vState& state, bool wasAuthZone, bool wasForwardRecurse)
 {
   string prefix;
@@ -1337,14 +1349,10 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector
       }
 
       // Check to see if we already have seen the new target as a previous target
-      for (const auto &rec: ret) {
-        if (rec.d_type == QType::CNAME && rec.d_place == DNSResourceRecord::ANSWER) {
-          if (newTarget == rec.d_name) {
-            string msg = "got a CNAME referral (from cache) that causes a loop";
-            LOG(prefix<<qname<<": status="<<msg<<endl);
-            throw ImmediateServFailException(msg);
-          }
-        }
+      if (scanForCNAMELoop(newTarget, ret)) {
+        string msg = "got a CNAME referral (from cache) that causes a loop";
+        LOG(prefix<<qname<<": status="<<msg<<endl);
+        throw ImmediateServFailException(msg);
       }
 
       set<GetBestNSAnswer>beenthere;
@@ -3380,6 +3388,7 @@ bool SyncRes::processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qn
   if(!newtarget.empty()) {
     if(newtarget == qname) {
       LOG(prefix<<qname<<": status=got a CNAME referral to self, returning SERVFAIL"<<endl);
+      ret.clear();
       *rcode = RCode::ServFail;
       return true;
     }
@@ -3391,14 +3400,11 @@ bool SyncRes::processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qn
     }
 
     // Check to see if we already have seen the new target as a previous target
-    for (const auto &record: ret) {
-      if (record.d_type == QType::CNAME && record.d_place == DNSResourceRecord::ANSWER) {
-        if (newtarget == record.d_name) {
-          LOG(prefix<<qname<<": status=got a CNAME referral that causes a loop, returning SERVFAIL"<<endl);
-          *rcode = RCode::ServFail;
-          return true;
-        }
-      }
+    if (scanForCNAMELoop(newtarget, ret)) {
+      LOG(prefix<<qname<<": status=got a CNAME referral that causes a loop, returning SERVFAIL"<<endl);
+      ret.clear();
+      *rcode = RCode::ServFail;
+      return true;
     }
 
     if (qtype == QType::DS) {