From: Miod Vallat Date: Wed, 4 Dec 2024 15:22:41 +0000 (+0100) Subject: Handle empty ipv*hint values as "auto", when coming from lmdb. X-Git-Tag: dnsdist-2.0.0-alpha0~3^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=863c7565211e0816f698ffbb48675a5f8e25f58f;p=thirdparty%2Fpdns.git Handle empty ipv*hint values as "auto", when coming from lmdb. Fixes #12653 --- diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 36841e619a..8b6860ee5a 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1009,7 +1009,7 @@ static std::shared_ptr deserializeContentZR(uint16_t qtype, co if (qtype == QType::A && content.size() == 4) { return std::make_shared(*((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 diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index e1f81a14d3..5dd2de0ce9 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -80,7 +80,7 @@ void UnknownRecordContent::toPacket(DNSPacketWriter& pw) const pw.xfrBlob(string(d_record.begin(),d_record.end())); } -shared_ptr DNSRecordContent::deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass) +shared_ptr 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::deserialize(const DNSName& qname, dr.d_type = qtype; dr.d_name = qname; dr.d_clen = serialized.size(); - PacketReader pr(std::string_view(reinterpret_cast(packet.data()), packet.size()), packet.size() - serialized.size() - sizeof(dnsrecordheader)); + PacketReader pr(std::string_view(reinterpret_cast(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 &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: { diff --git a/pdns/dnsparser.hh b/pdns/dnsparser.hh index 21ad0205c1..ae9778a7d7 100644 --- a/pdns/dnsparser.hh +++ b/pdns/dnsparser.hh @@ -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::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 deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass=QClass::IN); + static shared_ptr deserialize(const DNSName& qname, uint16_t qtype, const string& serialized, uint16_t qclass=QClass::IN, bool trusted = false); void doRecordCheck(const struct DNSRecord&){}