]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
pdnsutil: some consistency checks for SVCB
authorPieter Lexis <pieter.lexis@powerdns.com>
Mon, 15 Mar 2021 13:01:11 +0000 (14:01 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Mon, 29 Mar 2021 17:10:32 +0000 (19:10 +0200)
pdns/dnsrecords.cc
pdns/dnsrecords.hh
pdns/pdnsutil.cc

index 1258583b71d93a836b7282d2e0671dd597d85cec..2a3560f3eb6f078df418e53de1ca4bdfab06f2f7 100644 (file)
@@ -764,6 +764,25 @@ bool SVCBBaseRecordContent::hasParams() const {
   return d_params.size() > 0;
 }
 
+bool SVCBBaseRecordContent::hasParam(const SvcParam::SvcParamKey &key) const {
+  auto p = std::find_if(d_params.begin(), d_params.end(),
+      [&key](const SvcParam &param) {
+        return param.getKey() == key;
+      });
+  return p != d_params.end();
+}
+
+SvcParam SVCBBaseRecordContent::getParam(const SvcParam::SvcParamKey &key) const {
+  auto p = std::find_if(d_params.begin(), d_params.end(),
+      [&key](const SvcParam &param) {
+        return param.getKey() == key;
+      });
+  if (p == d_params.end()) {
+    throw std::out_of_range("No param with key " + SvcParam::keyToString(key));
+  }
+  return *p;
+}
+
 /* SVCB end */
 
 boilerplate_conv(TKEY,
index 9c62981121dfc5dedf8b7b482bb2ac555583d750..03936e161a9cbdc5bedb1c608c27462561a07a21 100644 (file)
@@ -510,6 +510,10 @@ class SVCBBaseRecordContent : public DNSRecordContent
     void removeParam(const SvcParam::SvcParamKey &key);
     // Whether or not there are any param
     bool hasParams() const;
+    // Whether or not the param of |key| exists
+    bool hasParam(const SvcParam::SvcParamKey &key) const;
+    // Get the parameter with |key|, will throw out_of_range if param isn't there
+    SvcParam getParam(const SvcParam::SvcParamKey &key) const;
 
   protected:
     uint16_t d_priority;
index c51ff6bb6cf199a2e2ff3d07264fd23d335f3c4a..53e468f1df5f0bc07f712fbc59e57582b607bed0 100644 (file)
@@ -422,6 +422,28 @@ static int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone, con
         numwarnings++;
       }
 
+      if(svcbrc->getPriority() != 0) {
+        // Service Form
+        if (svcbrc->hasParam(SvcParam::no_default_alpn) && !svcbrc->hasParam(SvcParam::alpn)) {
+          /* draft-ietf-dnsop-svcb-https-03 section 6.1
+           *  When "no-default-alpn" is specified in an RR, "alpn" must
+           *  also be specified in order for the RR to be "self-consistent
+           *  (Section 2.4.3).
+           */
+          cout<<"[Warning] "<<rr.qname<<"|"<<rr.qtype.getName()<<" is not self-consistent: 'no-default-alpn' parameter without 'alpn' parameter"<<endl;
+          numwarnings++;
+        }
+        if (svcbrc->hasParam(SvcParam::mandatory)) {
+          auto keys = svcbrc->getParam(SvcParam::mandatory).getMandatory();
+          for (auto const &k: keys) {
+            if (!svcbrc->hasParam(k)) {
+              cout<<"[Warning] "<<rr.qname<<"|"<<rr.qtype.getName()<<" is not self-consistent: 'mandatory' parameter lists '"+ SvcParam::keyToString(k) +"', but that parameter does not exist"<<endl;
+              numwarnings++;
+            }
+          }
+        }
+      }
+
       switch (rr.qtype.getCode()) {
       case QType::SVCB:
         if (svcbrc->getPriority() == 0) {