]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Check usefullness of root hints.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 10 Jun 2020 07:54:20 +0000 (09:54 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 3 Jul 2020 08:25:08 +0000 (10:25 +0200)
e.g. if we are running IPv6 only, and only have IPv4 hints
things will not work. Base he decision on presence of A/AAAA
records mentioned as NS.

pdns/reczones.cc

index 28716ac31768c4ebf0d1bdcf6db2861f5ce213f1..16d28b7101ac5b61a2a25a32d54fb9bd0aae635f 100644 (file)
@@ -84,24 +84,57 @@ void primeHints(void)
     ZoneParserTNG zpt(::arg()["hint-file"]);
     zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps"));
     DNSResourceRecord rr;
+    set<DNSName> seenNS;
+    set<DNSName> seenA;
+    set<DNSName> seenAAAA;
 
     while(zpt.get(rr)) {
       rr.ttl+=time(0);
       if(rr.qtype.getCode()==QType::A) {
+        seenA.insert(rr.qname);
         vector<DNSRecord> aset;
         aset.push_back(DNSRecord(rr));
         s_RC->replace(time(0), rr.qname, QType(QType::A), aset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true, boost::none, boost::none, validationState); // auth, etc see above
       } else if(rr.qtype.getCode()==QType::AAAA) {
+        seenAAAA.insert(rr.qname);
         vector<DNSRecord> aaaaset;
         aaaaset.push_back(DNSRecord(rr));
         s_RC->replace(time(0), rr.qname, QType(QType::AAAA), aaaaset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true, boost::none, boost::none, validationState);
       } else if(rr.qtype.getCode()==QType::NS) {
+        seenNS.insert(DNSName(rr.content));
         rr.content=toLower(rr.content);
         nsset.push_back(DNSRecord(rr));
       }
       insertIntoRootNSZones(rr.qname.getLastLabel());
     }
+
+    // Check reachability of A and AAAA records
+    bool reachableA = false, reachableAAAA = false;
+    for (auto const& r: seenA) {
+      if (seenNS.count(r)) {
+        reachableA = true;
+      }
+    }
+    for (auto const& r: seenAAAA) {
+      if (seenNS.count(r)) {
+        reachableAAAA = true;
+      }
+    }
+    if (SyncRes::s_doIPv4 && !SyncRes::s_doIPv6 && !reachableA) {
+      g_log<<Logger::Critical<<"Running IPv4 only but no IPv4 root hints, stopping"<<endl;
+      // XXX exit() trips an exception in ~ThreadInfo, to be investigated
+      _exit(99);
+    }
+    if (!SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableAAAA) {
+      g_log<<Logger::Critical<<"Running IPv6 only but no IPv6 root hints, stopping"<<endl;
+      _exit(99);
+    }
+    if (SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableA && !reachableAAAA) {
+      g_log<<Logger::Critical<<"No valid root hints, stopping"<<endl;
+      _exit(99);
+    }
   }
+
   s_RC->doWipeCache(g_rootdnsname, false, QType::NS);
   s_RC->replace(time(0), g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, boost::none, boost::none, validationState); // and stuff in the cache
 }