]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Do not chase CNAME during qname minization step 4 9790/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 1 Dec 2020 09:52:37 +0000 (10:52 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 1 Dec 2020 09:52:37 +0000 (10:52 +0100)
pdns/syncres.cc
pdns/syncres.hh

index 92f674e4de412ba7f3ec07c3f526409e17f9e9f5..2a0c357db9cd59af8ed48e809bc71ae091d273ec 100644 (file)
@@ -771,9 +771,12 @@ int SyncRes::doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecor
 
       // Step 4
       QLOG("Step4 Resolve A for child");
+      bool oldFollowCNAME = d_followCNAME;
+      d_followCNAME = false;
       retq.resize(0);
       StopAtDelegation stopAtDelegation = Stop;
       res = doResolveNoQNameMinimization(child, QType::A, retq, depth, beenthere, state, NULL, &stopAtDelegation);
+      d_followCNAME = oldFollowCNAME;
       QLOG("Step4 Resolve A result is " << RCode::to_s(res) << "/" << retq.size() << "/" << stopAtDelegation);
       if (stopAtDelegation == Stopped) {
         QLOG("Delegation seen, continue at step 1");
@@ -1019,9 +1022,11 @@ vector<ComboAddress> SyncRes::getAddrs(const DNSName &qname, unsigned int depth,
   bool oldCacheOnly = setCacheOnly(cacheOnly);
   bool oldRequireAuthData = d_requireAuthData;
   bool oldValidationRequested = d_DNSSECValidationRequested;
+  bool oldFollowCNAME = d_followCNAME;
   const unsigned int startqueries = d_outqueries;
   d_requireAuthData = false;
   d_DNSSECValidationRequested = false;
+  d_followCNAME = true;
 
   try {
     vState newState = vState::Indeterminate;
@@ -1077,6 +1082,7 @@ vector<ComboAddress> SyncRes::getAddrs(const DNSName &qname, unsigned int depth,
   d_requireAuthData = oldRequireAuthData;
   d_DNSSECValidationRequested = oldValidationRequested;
   setCacheOnly(oldCacheOnly);
+  d_followCNAME = oldFollowCNAME;
 
   /* we need to remove from the nsSpeeds collection the existing IPs
      for this nameserver that are no longer in the set, even if there
@@ -1444,7 +1450,7 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector
       DNSName newTarget;
       if (foundQT == QType::DNAME) {
         if (qtype == QType::DNAME && qname == foundName) { // client wanted the DNAME, no need to synthesize a CNAME
-          res = 0;
+          res = RCode::NoError;
           return true;
         }
         // Synthesize a CNAME
@@ -1473,12 +1479,12 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector
       }
 
       if(qtype == QType::CNAME) { // perhaps they really wanted a CNAME!
-        res = 0;
+        res = RCode::NoError;
         return true;
       }
 
       if (qtype == QType::DS || qtype == QType::DNSKEY) {
-        res = 0;
+        res = RCode::NoError;
         return true;
       }
 
@@ -1505,6 +1511,11 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector
         setQNameMinimization(false);
       }
 
+      if (!d_followCNAME) {
+        res = RCode::NoError;
+        return true;
+      }
+
       // Check to see if we already have seen the new target as a previous target
       if (scanForCNAMELoop(newTarget, ret)) {
         string msg = "got a CNAME referral (from cache) that causes a loop";
@@ -3722,6 +3733,11 @@ void SyncRes::handleNewTarget(const std::string& prefix, const DNSName& qname, c
     return;
   }
 
+  if (!d_followCNAME) {
+    rcode = RCode::NoError;
+    return;
+  }
+
   // Check to see if we already have seen the new target as a previous target
   if (scanForCNAMELoop(newtarget, ret)) {
     LOG(prefix<<qname<<": status=got a CNAME referral that causes a loop, returning SERVFAIL"<<endl);
index bd32049994f629cfb35b369e16fce08ace7c3a85..fbc17f3a1d28e4ec04c55c111cb1b052824f9e81 100644 (file)
@@ -897,6 +897,7 @@ private:
   bool d_wasVariable{false};
   bool d_qNameMinimization{false};
   bool d_queryReceivedOverTCP{false};
+  bool d_followCNAME{true};
 
   LogMode d_lm;
 };