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
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));
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);
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: {
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");
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;
}
// 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&){}