]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Basic NAPTR handling plys different modes: Ignore, CacheOnly, CacheOnlyRequireAuth...
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 7 Feb 2022 13:53:26 +0000 (14:53 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 14 Feb 2022 19:09:49 +0000 (20:09 +0100)
pdns/dnsrecords.hh
pdns/syncres.cc
pdns/syncres.hh

index 7d5b2272bd0f60851c98f7417f2bdb8bd9da3e27..3d1e348011db65c000f0ebe5e12e1b05eb971c8c 100644 (file)
@@ -51,6 +51,14 @@ public:
 
   includeboilerplate(NAPTR)
   template<class Convertor> void xfrRecordContent(Convertor& conv);
+  string getFlags() const
+  {
+    return d_flags;
+  }
+  DNSName getReplacement() const
+  {
+    return d_replacement;
+  }
 private:
   uint16_t d_order, d_preference;
   string d_flags, d_services, d_regexp;
index 1f0b3ae5fcb60c66bf9f19238f030e2f21d57ad7..0ea779c416ae201ab7f434c0b5d8c7de6e35d6d8 100644 (file)
@@ -140,32 +140,62 @@ SyncRes::SyncRes(const struct timeval& now) :  d_authzonequeries(0), d_outquerie
 {
 }
 
-static bool allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals, const DNSRecord& rec);
+static void allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals, const DNSRecord& rec);
+
+static const std::map<QType, std::pair<std::set<QType>, SyncRes::AddtionalMode>> additionalTypes = {
+  {QType::MX, {{QType::A, QType::AAAA}, SyncRes::AddtionalMode::CacheOnlyRequireAuth}},
+  {QType::SRV, {{QType::A, QType::AAAA}, SyncRes::AddtionalMode::ResolveImmediately}},
+  {QType::SVCB, {{QType::A, QType::AAAA}, SyncRes::AddtionalMode::CacheOnly}},
+  {QType::HTTPS, {{QType::A, QType::AAAA}, SyncRes::AddtionalMode::CacheOnly}},
+  {QType::NAPTR, {{QType::A, QType::AAAA, QType::SRV}, SyncRes::AddtionalMode::ResolveImmediately}}
+};
 
-void SyncRes::getAdditionals(const DNSName& qname, QType qtype, bool requireAuth, std::set<DNSRecord>& additionals, unsigned int depth)
+void SyncRes::getAdditionals(const DNSName& qname, QType qtype, AddtionalMode mode, std::set<DNSRecord>& additionals, unsigned int depth)
 {
   vector<DNSRecord> addRecords;
 
   vState state = vState::Indeterminate;
-  if (requireAuth) {
+  switch (mode) {
+  case AddtionalMode::ResolveImmediately: {
     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) {
+    if (vStateIsBogus(state)) {
       return;
     }
+    for (auto rec : addRecords) {
+      if (rec.d_place == DNSResourceRecord::ANSWER) {
+        rec.d_place = DNSResourceRecord::ADDITIONAL;
+        additionals.insert(rec);
+      }
+    }
+    break;
   }
-  if (vStateIsBogus(state)) {
-    return;
-  }
-  for (const auto& rec : addRecords) {
-    if (rec.d_place == DNSResourceRecord::ANSWER) {
-      additionals.insert(rec);
+  case AddtionalMode::CacheOnly:
+  case AddtionalMode::CacheOnlyRequireAuth: {
+    // Peek into cache
+    if (g_recCache->get(d_now.tv_sec, qname, qtype, mode == AddtionalMode::CacheOnlyRequireAuth, &addRecords, d_cacheRemote, false, d_routingTag, nullptr, nullptr, nullptr, &state) <= 0) {
+      return;
     }
+    if (vStateIsBogus(state)) {
+      return;
+    }
+    for (auto rec : addRecords) {
+      if (rec.d_place == DNSResourceRecord::ANSWER) {
+        rec.d_place = DNSResourceRecord::ADDITIONAL;
+        rec.d_ttl -= d_now.tv_sec ;
+        additionals.insert(rec);
+      }
+    }
+    break;
+  }
+  case AddtionalMode::ResolveDeferred:
+    // Not yet implemented
+    break;
+  case AddtionalMode::Ignore:
+    break;
   }
 }
 
@@ -218,15 +248,6 @@ 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, {{QType::A, QType::AAAA}, false}},
-    {QType::HTTPS, {{QType::A, QType::AAAA}, false}},
-    {QType::NAPTR, {{}, false}}
-  };
-
   const auto it = additionalTypes.find(qtype);
   if (it != additionalTypes.end()) {
     std::unordered_set<DNSName> addnames;
@@ -236,19 +257,17 @@ int SyncRes::beginResolve(const DNSName &qname, const QType qtype, QClass qclass
       }
     }
     std::set<DNSRecord> additionals;
-    bool requireAuth = it->second.second;
+    auto mode = 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);
+        getAdditionals(addname, targettype, mode, additionals, depth);
       }
     }
-    for (auto rec : additionals) {
-      rec.d_place =  DNSResourceRecord::ADDITIONAL;
-      rec.d_ttl -= d_now.tv_sec;
+    for (const auto& rec : additionals) {
       ret.push_back(rec);
     }
   }
@@ -3107,30 +3126,24 @@ void SyncRes::fixupAnswer(const std::string& prefix, LWResult& lwr, const DNSNam
   }
 }
 
-static bool allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals, const DNSRecord& rec)
+static void allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals, const DNSRecord& rec)
 {
   switch(rec.d_type) {
   case QType::MX:
-  {
     if (auto mxContent = getRR<MXRecordContent>(rec)) {
       allowedAdditionals.insert(mxContent->d_mxname);
     }
-    return true;
-  }
+    break;
   case QType::NS:
-  {
     if (auto nsContent = getRR<NSRecordContent>(rec)) {
       allowedAdditionals.insert(nsContent->getNS());
     }
-    return true;
-  }
+    break;
   case QType::SRV:
-  {
     if (auto srvContent = getRR<SRVRecordContent>(rec)) {
       allowedAdditionals.insert(srvContent->d_target);
     }
-    return true;
-  }
+    break;
   case QType::SVCB: /* fall-through */
   case QType::HTTPS:
     if (auto svcbContent = getRR<SVCBBaseRecordContent>(rec)) {
@@ -3140,18 +3153,23 @@ static bool allowAdditionalEntry(std::unordered_set<DNSName>& allowedAdditionals
           target = rec.d_name;
         }
         allowedAdditionals.insert(target);
-        return true;
       }
       else {
         // Alias mode not implemented yet
-        return false;
       }
     }
     break;
   case QType::NAPTR:
-    // To be done
+    if (auto naptrContent = getRR<NAPTRRecordContent>(rec)) {
+      auto flags = naptrContent->getFlags();
+      toLowerInPlace(flags);
+      if (flags.find('a') || flags.find('s')) {
+        allowedAdditionals.insert(naptrContent->getReplacement());
+      }
+    }
+    break;
   default:
-    return false;
+    break;
   }
 }
 
index 93d8a5b6d2b32b8c2bc9792f87c433ae2269081f..1cb0b9d5f87a26be68275999cd44a06f0f263e62 100644 (file)
@@ -598,7 +598,15 @@ public:
 
   explicit SyncRes(const struct timeval& now);
 
-  void getAdditionals(const DNSName& qname, QType qtype, bool requireAuth, std::set<DNSRecord>& additionals, unsigned int depth);
+  enum class AddtionalMode : uint8_t {
+    Ignore,
+    CacheOnly,
+    CacheOnlyRequireAuth,
+    ResolveImmediately,
+    ResolveDeferred
+  };
+
+  void getAdditionals(const DNSName& qname, QType qtype, AddtionalMode, 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)