]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add additional processing for SVCB and HTTPS
authorPieter Lexis <pieter.lexis@powerdns.com>
Tue, 22 Sep 2020 14:11:46 +0000 (16:11 +0200)
committerPieter Lexis <pieter.lexis@powerdns.com>
Fri, 25 Sep 2020 10:26:12 +0000 (12:26 +0200)
pdns/dnsrecords.hh
pdns/packethandler.cc
pdns/packethandler.hh

index 4daa894c87e56d1f585fea84098131a9c18e9f18..bb016dedca7d01b4347112f56de19ab2c0f8b87e 100644 (file)
@@ -501,6 +501,8 @@ class SVCBRecordContent : public DNSRecordContent
 {
 public:
   includeboilerplate(SVCB)
+  const DNSName& getTarget() const {return d_target;}
+  uint16_t getPriority() const {return d_priority;}
 
 private:
   uint16_t d_priority;
@@ -512,6 +514,8 @@ class HTTPSRecordContent : public DNSRecordContent
 {
 public:
   includeboilerplate(HTTPS)
+  const DNSName& getTarget() const {return d_target;}
+  uint16_t getPriority() const {return d_priority;}
 
 private:
   uint16_t d_priority;
index a535ac6fecbe7b99fff8e1072a892230d3e3b534..9347adb87b3022d02b74a2151e1098de5153cc56 100644 (file)
@@ -438,13 +438,51 @@ bool PacketHandler::getBestWildcard(DNSPacket& p, const SOAData& sd, const DNSNa
   return haveSomething;
 }
 
+DNSName PacketHandler::doAdditionalServiceProcessing(const DNSName &firstTarget, const uint16_t &qtype, const int domain_id, std::unique_ptr<DNSPacket>& r) {
+  DNSName ret = firstTarget;
+  size_t ctr = 5; // Max 5 SVCB Aliasforms per query
+  bool done = false;
+  while (!done && ctr > 0) {
+    DNSZoneRecord rr;
+    done = true;
+    B.lookup(QType(qtype), ret, domain_id);
+    while (B.get(rr)) {
+      rr.dr.d_place = DNSResourceRecord::ADDITIONAL;
+      switch (qtype) {
+        case QType::SVCB: {
+          auto rrc = getRR<SVCBRecordContent>(rr.dr);
+          r->addRecord(std::move(rr));
+          ret = rrc->getTarget().isRoot() ? ret : rrc->getTarget();
+          if (rrc->getPriority() == 0) {
+            done = false;
+          }
+          break;
+        }
+        case QType::HTTPS: {
+          auto rrc = getRR<HTTPSRecordContent>(rr.dr);
+          r->addRecord(std::move(rr));
+          ret = rrc->getTarget().isRoot() ? ret : rrc->getTarget();
+          if (rrc->getPriority() == 0) {
+            done = false;
+          }
+          break;
+        }
+        default:
+          throw PDNSException("Unknown type (" + QType(qtype).getName() + "for additional service processing");
+      }
+    }
+    ctr--;
+  }
+  return ret;
+}
+
 
 void PacketHandler::doAdditionalProcessing(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& soadata)
 {
   DNSName content;
   std::unordered_set<DNSName> lookup;
   const auto& rrs = r->getRRS();
+
   lookup.reserve(rrs.size());
   for(auto& rr : rrs) {
     if(rr.dr.d_place != DNSResourceRecord::ADDITIONAL) {
@@ -458,6 +496,24 @@ void PacketHandler::doAdditionalProcessing(DNSPacket& p, std::unique_ptr<DNSPack
         case QType::SRV:
           content=std::move(getRR<SRVRecordContent>(rr.dr)->d_target);
           break;
+        case QType::SVCB: {
+          auto rrc = getRR<SVCBRecordContent>(rr.dr);
+          content = rrc->getTarget();
+          if (content.isRoot()) {
+            content = rr.dr.d_name;
+          }
+          content = doAdditionalServiceProcessing(content, rr.dr.d_type, soadata.domain_id, r);
+          break;
+        }
+        case QType::HTTPS: {
+          auto rrc = getRR<HTTPSRecordContent>(rr.dr);
+          content = rrc->getTarget();
+          if (content.isRoot()) {
+            content = rr.dr.d_name;
+          }
+          content = doAdditionalServiceProcessing(content, rr.dr.d_type, soadata.domain_id, r);
+          break;
+        }
         default:
           continue;
       }
index 36201d1047974be93041509725b940f231603c16..3ffba371e31ecc650d3c7b6f4671ecf0fb9e1633 100644 (file)
@@ -74,6 +74,7 @@ private:
   bool addCDS(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd);
   bool addNSEC3PARAM(const DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd);
   void doAdditionalProcessing(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd);
+  DNSName doAdditionalServiceProcessing(const DNSName &firstTarget, const uint16_t &qtype, const int domain_id, std::unique_ptr<DNSPacket>& r);
   void addNSECX(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName &target, const DNSName &wildcard, const DNSName &auth, int mode);
   void addNSEC(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName &target, const DNSName &wildcard, const DNSName& auth, int mode);
   void addNSEC3(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName &target, const DNSName &wildcard, const DNSName& auth, const NSEC3PARAMRecordContent& nsec3param, bool narrow, int mode);