]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Initial version, showing some working functionality
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 7 Feb 2022 11:38:33 +0000 (12:38 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 14 Feb 2022 19:09:49 +0000 (20:09 +0100)
pdns/pdns_recursor.cc
pdns/syncres.cc
pdns/syncres.hh

index 9aad7e01eeddbe8c0fe2cbf671064c2f25c86be8..66802f84cff6b8b53dfe3e64d3dd8c79654f2e99 100644 (file)
@@ -1268,7 +1268,7 @@ void startDoResolve(void* p)
 
       bool needCommit = false;
       for (auto i = ret.cbegin(); i != ret.cend(); ++i) {
-        if (!DNSSECOK && (i->d_type == QType::NSEC3 || ((i->d_type == QType::RRSIG || i->d_type == QType::NSEC) && ((dc->d_mdp.d_qtype != i->d_type && dc->d_mdp.d_qtype != QType::ANY) || i->d_place != DNSResourceRecord::ANSWER)))) {
+        if (!DNSSECOK && (i->d_type == QType::NSEC3 || ((i->d_type == QType::RRSIG || i->d_type == QType::NSEC) && ((dc->d_mdp.d_qtype != i->d_type && dc->d_mdp.d_qtype != QType::ANY) || (i->d_place != DNSResourceRecord::ANSWER && i->d_place != DNSResourceRecord::ADDITIONAL))))) {
           continue;
         }
 
index b61f1830294ac8cd8e110045b9e63dd7ff02327c..af82a278cd51017dcdbb3ad8d6803cf07dda78d6 100644 (file)
@@ -140,6 +140,35 @@ SyncRes::SyncRes(const struct timeval& now) :  d_authzonequeries(0), d_outquerie
 {
 }
 
+static bool allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals, const DNSRecord& rec);
+
+void SyncRes::getAdditionals(const DNSName& qname, QType qtype, bool requireAuth, std::set<DNSRecord>& additionals, unsigned int depth)
+{
+  vector<DNSRecord> addRecords;
+
+  vState state = vState::Indeterminate;
+  if (requireAuth) {
+    set<GetBestNSAnswer> lbeenthere;
+    int res = doResolve(qname, qtype, addRecords, depth, lbeenthere, state);
+    if (res != 0) {
+      return;
+    }
+  } else {
+    // Peek into cache for non-auth data
+    if (g_recCache->get(d_now.tv_sec, qname, qtype,  false, &addRecords, d_cacheRemote, false, d_routingTag, nullptr, nullptr, nullptr, &state) <= 0) {
+      return;
+    }
+  }
+  if (vStateIsBogus(state)) {
+    return;
+  }
+  for (const auto& rec : addRecords) {
+    if (rec.d_place == DNSResourceRecord::ANSWER) {
+      additionals.insert(rec);
+    }
+  }
+}
+
 /** everything begins here - this is the entry point just after receiving a packet */
 int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass, vector<DNSRecord>&ret, unsigned int depth)
 {
@@ -189,6 +218,40 @@ int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass
     }
   }
 
+  const std::map<QType, std::pair<std::set<QType>, bool>> additionalTypes = {
+    {QType::MX, {{QType::A, QType::AAAA}, false}},
+    //{QType::NS, {{QType::A, QType::AAAA}, false}},
+    {QType::SRV, {{QType::A, QType::AAAA}, false}},
+    {QType::SVCB, {{}, false}},
+    {QType::HTTPS, {{}, false}},
+    {QType::NAPTR, {{}, false}}
+  };
+
+  const auto it = additionalTypes.find(qtype);
+  if (it != additionalTypes.end()) {
+    std::unordered_set<DNSName> addnames;
+    for (const auto& rec : ret) {
+      if (rec.d_place == DNSResourceRecord::ANSWER) {
+        allowAdditionalEntry(addnames, rec);
+      }
+    }
+    std::set<DNSRecord> additionals;
+    bool requireAuth = it->second.second;
+    for (const auto& targettype : it->second.first) {
+      for (const auto& addname : addnames) {
+        vector<DNSRecord> addRecords;
+        if ((targettype == QType::A && !s_doIPv4) || (targettype == QType::AAAA && !s_doIPv6)) {
+          continue;
+        }
+        getAdditionals(addname, targettype, requireAuth, additionals, depth);
+      }
+    }
+    for (auto rec : additionals) {
+      rec.d_place =  DNSResourceRecord::ADDITIONAL;
+      rec.d_ttl -= d_now.tv_sec;
+      ret.push_back(rec);
+    }
+  }
   d_eventTrace.add(RecEventTrace::SyncRes, res, false);
   return res;
 }
@@ -3068,6 +3131,10 @@ static bool allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals
     }
     return true;
   }
+  // Record ttypes below are candidates for this
+  case QType::SVCB:
+  case QType::HTTPS:
+  case QType::NAPTR:
   default:
     return false;
   }
index 3537bd0e7006ceca346e2c52c0ad1923cf92f27f..93d8a5b6d2b32b8c2bc9792f87c433ae2269081f 100644 (file)
@@ -598,6 +598,7 @@ public:
 
   explicit SyncRes(const struct timeval& now);
 
+  void getAdditionals(const DNSName& qname, QType qtype, bool requireAuth, std::set<DNSRecord>& additionals, unsigned int depth);
   int beginResolve(const DNSName &qname, QType qtype, QClass qclass, vector<DNSRecord>&ret, unsigned int depth = 0);
 
   void setId(int id)