DnsQuestion *question;
const char *domain;
uint64_t flags;
- int ifindex;
+ int ifindex, r;
/* This returns the following return values:
*
is_dns_proxy_stub_hostname(domain))
return DNS_SCOPE_NO;
+ /* Never send SOA or NS or DNSSEC request to LLMNR, where they make little sense. */
+ r = dns_question_types_suitable_for_protocol(question, s->protocol);
+ if (r <= 0)
+ return DNS_SCOPE_NO;
+
switch (s->protocol) {
case DNS_PROTOCOL_DNS: {
JSON_BUILD_PAIR_CONDITION(scope->link, "ifname", JSON_BUILD_STRING(scope->link ? scope->link->ifname : NULL)),
JSON_BUILD_PAIR_VARIANT("cache", cache)));
}
+
+int dns_type_suitable_for_protocol(uint16_t type, DnsProtocol protocol) {
+
+ /* Tests whether it makes sense to route queries for the specified DNS RR types to the specified
+ * protocol. For classic DNS pretty much all RR types are suitable, but for LLMNR/mDNS let's
+ * allowlist only a few that make sense. We use this when routing queries so that we can more quickly
+ * return errors for queries that will almost certainly fail/time-out otherwise. For example, this
+ * ensures that SOA, NS, or DS/DNSKEY queries are never routed to mDNS/LLMNR where they simply make
+ * no sense. */
+
+ if (dns_type_is_obsolete(type))
+ return false;
+
+ if (!dns_type_is_valid_query(type))
+ return false;
+
+ switch (protocol) {
+
+ case DNS_PROTOCOL_DNS:
+ return true;
+
+ case DNS_PROTOCOL_LLMNR:
+ return IN_SET(type,
+ DNS_TYPE_ANY,
+ DNS_TYPE_A,
+ DNS_TYPE_AAAA,
+ DNS_TYPE_CNAME,
+ DNS_TYPE_PTR,
+ DNS_TYPE_TXT);
+
+ case DNS_PROTOCOL_MDNS:
+ return IN_SET(type,
+ DNS_TYPE_ANY,
+ DNS_TYPE_A,
+ DNS_TYPE_AAAA,
+ DNS_TYPE_CNAME,
+ DNS_TYPE_PTR,
+ DNS_TYPE_TXT,
+ DNS_TYPE_SRV,
+ DNS_TYPE_NSEC,
+ DNS_TYPE_HINFO);
+
+ default:
+ return -EPROTONOSUPPORT;
+ }
+}
+
+int dns_question_types_suitable_for_protocol(DnsQuestion *q, DnsProtocol protocol) {
+ DnsResourceKey *key;
+ int r;
+
+ /* Tests whether the types in the specified question make any sense to be routed to the specified
+ * protocol, i.e. if dns_type_suitable_for_protocol() is true for any of the contained RR types */
+
+ DNS_QUESTION_FOREACH(key, q) {
+ r = dns_type_suitable_for_protocol(key->type, protocol);
+ if (r != 0)
+ return r;
+ }
+
+ return false;
+}
bool dns_scope_is_default_route(DnsScope *scope);
int dns_scope_dump_cache_to_json(DnsScope *scope, JsonVariant **ret);
+
+int dns_type_suitable_for_protocol(uint16_t type, DnsProtocol protocol);
+int dns_question_types_suitable_for_protocol(DnsQuestion *q, DnsProtocol protocol);