]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
More sophisticated cname loop detection.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 3 Jun 2020 14:31:57 +0000 (16:31 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 5 Jun 2020 07:35:12 +0000 (09:35 +0200)
pdns/syncres.cc

index 333c0d8c21708bceeb95af32f33dcdd13e66388f..b6a3bf9d85b55b1d8a6368e2603135e70388f7c0 100644 (file)
@@ -1331,9 +1331,20 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector
       }
 
       if (qname == newTarget) {
-        LOG(prefix<<qname<<": Got a CNAME referral (from cache) to self, returning SERVFAIL"<<endl);
-        res = RCode::ServFail;
-        return true;
+        string msg = "got a CNAME referral (from cache) to self";
+        LOG(prefix<<qname<<": "<<msg<<endl);
+        throw ImmediateServFailException(msg);
+      }
+
+      // 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);
+          }
+        }
       }
 
       set<GetBestNSAnswer>beenthere;
@@ -3379,6 +3390,17 @@ bool SyncRes::processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qn
       return true;
     }
 
+    // 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 (qtype == QType::DS) {
       LOG(prefix<<qname<<": status=got a CNAME referral, but we are looking for a DS"<<endl);