]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Handle empty ipv*hint values as "auto", when coming from lmdb.
authorMiod Vallat <miod.vallat@open-xchange.com>
Wed, 4 Dec 2024 15:22:41 +0000 (16:22 +0100)
committerMiod Vallat <miod.vallat@open-xchange.com>
Fri, 6 Dec 2024 09:22:02 +0000 (10:22 +0100)
Fixes #12653

modules/lmdbbackend/lmdbbackend.cc
pdns/dnsparser.cc
pdns/dnsparser.hh

index 36841e619a6831af1e74190d7c6db39318587399..8b6860ee5a089e463a5f30c8b2da88ba57ac9bed 100644 (file)
@@ -1009,7 +1009,7 @@ static std::shared_ptr<DNSRecordContent> deserializeContentZR(uint16_t qtype, co
   if (qtype == QType::A && content.size() == 4) {
     return std::make_shared<ARecordContent>(*((uint32_t*)content.c_str()));
   }
-  return DNSRecordContent::deserialize(qname, qtype, content);
+  return DNSRecordContent::deserialize(qname, qtype, content, QClass::IN, true);
 }
 
 /* design. If you ask a question without a zone id, we lookup the best
index e1f81a14d3e86295a83a38652718934293c72e35..5dd2de0ce9e34020d7cd5ca0aee4765a7f95435c 100644 (file)
@@ -80,7 +80,7 @@ void UnknownRecordContent::toPacket(DNSPacketWriter& pw) const
   pw.xfrBlob(string(d_record.begin(),d_record.end()));
 }
 
-shared_ptr<DNSRecordContent> DNSRecordContent::deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass)
+shared_ptr<DNSRecordContent> DNSRecordContent::deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass, bool trusted)
 {
   dnsheader dnsheader;
   memset(&dnsheader, 0, sizeof(dnsheader));
@@ -118,7 +118,7 @@ shared_ptr<DNSRecordContent> DNSRecordContent::deserialize(const DNSName& qname,
   dr.d_type = qtype;
   dr.d_name = qname;
   dr.d_clen = serialized.size();
-  PacketReader pr(std::string_view(reinterpret_cast<const char*>(packet.data()), packet.size()), packet.size() - serialized.size() - sizeof(dnsrecordheader));
+  PacketReader pr(std::string_view(reinterpret_cast<const char*>(packet.data()), packet.size()), packet.size() - serialized.size() - sizeof(dnsrecordheader), trusted);
   /* needed to get the record boundaries right */
   pr.getDnsrecordheader(drh);
   auto content = DNSRecordContent::make(dr, pr, Opcode::Query);
@@ -665,7 +665,12 @@ void PacketReader::xfrSvcParamKeyVals(set<SvcParam> &kvs) {
         xfrCAWithoutPort(key, addr);
         addresses.push_back(addr);
       }
-      kvs.insert(SvcParam(key, std::move(addresses)));
+      // If there were no addresses, and the input comes from a trusted source,
+      // we can reasonably suppose this is the serialization of "auto".
+      bool doAuto{d_trusted && len == 0};
+      auto param = SvcParam(key, std::move(addresses));
+      param.setAutoHint(doAuto);
+      kvs.insert(param);
       break;
     }
     case SvcParam::ech: {
index 21ad0205c14a7f090ea781212ec0f5267bd6a716..ae9778a7d7fbca67169f4a05af43182f53ae5051 100644 (file)
@@ -68,8 +68,8 @@ class MOADNSParser;
 class PacketReader
 {
 public:
-  PacketReader(const std::string_view& content, uint16_t initialPos=sizeof(dnsheader))
-    : d_pos(initialPos), d_startrecordpos(initialPos), d_content(content)
+  PacketReader(const std::string_view& content, uint16_t initialPos=sizeof(dnsheader), bool trusted = false)
+    : d_pos(initialPos), d_startrecordpos(initialPos), d_content(content), d_trusted(trusted)
   {
     if(content.size() > std::numeric_limits<uint16_t>::max())
       throw std::out_of_range("packet too large");
@@ -186,6 +186,7 @@ private:
   uint16_t d_recordlen;      // ditto
   uint16_t not_used; // Aligns the whole class on 8-byte boundaries
   const std::string_view d_content;
+  bool d_trusted;
 };
 
 struct DNSRecord;
@@ -226,7 +227,7 @@ public:
   }
 
   // parse the content in wire format, possibly including compressed pointers pointing to the owner name
-  static shared_ptr<DNSRecordContent> deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass=QClass::IN);
+  static shared_ptr<DNSRecordContent> deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass=QClass::IN, bool trusted = false);
 
   void doRecordCheck(const struct DNSRecord&){}