]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Provide NAPTR replacement information as additional answers whenever possible.
authorMiod Vallat <miod.vallat@open-xchange.com>
Fri, 24 Jan 2025 08:38:32 +0000 (09:38 +0100)
committerMiod Vallat <miod.vallat@open-xchange.com>
Mon, 3 Feb 2025 15:19:37 +0000 (16:19 +0100)
pdns/packethandler.cc

index 8483814d1954ded32b400d6e0eeade41493717d3..00b8ad5d2e09a328ce4a1e04fa25ebe30a03e691 100644 (file)
@@ -514,9 +514,11 @@ DNSName PacketHandler::doAdditionalServiceProcessing(const DNSName &firstTarget,
 }
 
 
+// NOLINTNEXTLINE(readability-function-cognitive-complexity)
 void PacketHandler::doAdditionalProcessing(DNSPacket& p, std::unique_ptr<DNSPacket>& r)
 {
   DNSName content;
+  DNSZoneRecord dzr;
   std::unordered_set<DNSName> lookup;
   vector<DNSZoneRecord> extraRecords;
   const auto& rrs = r->getRRS();
@@ -524,6 +526,7 @@ void PacketHandler::doAdditionalProcessing(DNSPacket& p, std::unique_ptr<DNSPack
   lookup.reserve(rrs.size());
   for(auto& rr : rrs) {
     if(rr.dr.d_place != DNSResourceRecord::ADDITIONAL) {
+      content.clear();
       switch(rr.dr.d_type) {
         case QType::NS:
           content=getRR<NSRecordContent>(rr.dr)->getNS();
@@ -546,10 +549,34 @@ void PacketHandler::doAdditionalProcessing(DNSPacket& p, std::unique_ptr<DNSPack
           }
           break;
         }
+        case QType::NAPTR: {
+          auto naptrContent = getRR<NAPTRRecordContent>(rr.dr);
+          auto flags = naptrContent->getFlags();
+          toLowerInPlace(flags);
+          if (flags.find('a') != string::npos) {
+            content = naptrContent->getReplacement();
+            DLOG(g_log<<Logger::Debug<<"adding NAPTR replacement 'a'="<<content<<endl);
+          }
+          else if (flags.find('s') != string::npos) {
+            content = naptrContent->getReplacement();
+            DLOG(g_log<<Logger::Debug<<"adding NAPTR replacement 's'="<<content<<endl);
+            B.lookup(QType(QType::SRV), content, d_sd.domain_id, &p);
+            while(B.get(dzr)) {
+              content=getRR<SRVRecordContent>(dzr.dr)->d_target;
+              if(content.isPartOf(d_sd.qname)) {
+                lookup.emplace(content);
+              }
+              dzr.dr.d_place=DNSResourceRecord::ADDITIONAL;
+              r->addRecord(std::move(dzr));
+            }
+            content.clear();
+          }
+          break;
+        }
         default:
           continue;
       }
-      if(content.isPartOf(d_sd.qname)) {
+      if(!content.empty() && content.isPartOf(d_sd.qname)) {
         lookup.emplace(content);
       }
     }
@@ -603,7 +630,6 @@ void PacketHandler::doAdditionalProcessing(DNSPacket& p, std::unique_ptr<DNSPack
     }
   }
 
-  DNSZoneRecord dzr;
   for(const auto& name : lookup) {
     B.lookup(QType(QType::ANY), name, d_sd.domain_id, &p);
     while(B.get(dzr)) {