From 830f50ab1e03fa7ee262876ed42023d10e89688d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 23 Feb 2022 07:49:40 +0900 Subject: [PATCH 1/3] resolve: drop never matched condition As dns_scope_good_domain() does not return negative errno. --- src/resolve/resolved-dns-query.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 9b296e7aa6..7dc346794e 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -744,11 +744,7 @@ int dns_query_go(DnsQuery *q) { continue; match = dns_scope_good_domain(s, q->ifindex, q->flags, name); - if (match < 0) { - log_debug("Couldn't check if '%s' matches against scope, ignoring.", name); - continue; - } - + assert(match >= 0); if (match > found) { /* Does this match better? If so, remember how well it matched, and the first one * that matches this well */ found = match; @@ -780,11 +776,7 @@ int dns_query_go(DnsQuery *q) { continue; match = dns_scope_good_domain(s, q->ifindex, q->flags, name); - if (match < 0) { - log_debug("Couldn't check if '%s' matches against scope, ignoring.", name); - continue; - } - + assert(match >= 0); if (match < found) continue; From 176a9a2cca47f7c1553d96f7dd51c2193a269dbc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 23 Feb 2022 07:50:30 +0900 Subject: [PATCH 2/3] resolve: make dns_scope_good_domain() take DnsQuery* --- src/resolve/resolved-dns-query.c | 14 ++------------ src/resolve/resolved-dns-scope.c | 21 +++++++++++++++++---- src/resolve/resolved-dns-scope.h | 4 ++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 7dc346794e..c0bb40937a 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -737,13 +737,8 @@ int dns_query_go(DnsQuery *q) { LIST_FOREACH(scopes, s, q->manager->dns_scopes) { DnsScopeMatch match; - const char *name; - name = dns_question_first_name(dns_query_question_for_protocol(q, s->protocol)); - if (!name) - continue; - - match = dns_scope_good_domain(s, q->ifindex, q->flags, name); + match = dns_scope_good_domain(s, q); assert(match >= 0); if (match > found) { /* Does this match better? If so, remember how well it matched, and the first one * that matches this well */ @@ -769,13 +764,8 @@ int dns_query_go(DnsQuery *q) { LIST_FOREACH(scopes, s, first->scopes_next) { DnsScopeMatch match; - const char *name; - name = dns_question_first_name(dns_query_question_for_protocol(q, s->protocol)); - if (!name) - continue; - - match = dns_scope_good_domain(s, q->ifindex, q->flags, name); + match = dns_scope_good_domain(s, q); assert(match >= 0); if (match < found) continue; diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index c3a2e2fc60..69101fb5a2 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -584,11 +584,13 @@ static DnsScopeMatch match_subnet_reverse_lookups( DnsScopeMatch dns_scope_good_domain( DnsScope *s, - int ifindex, - uint64_t flags, - const char *domain) { + DnsQuery *q) { + DnsQuestion *question; DnsSearchDomain *d; + const char *domain; + uint64_t flags; + int ifindex; /* This returns the following return values: * @@ -602,7 +604,18 @@ DnsScopeMatch dns_scope_good_domain( */ assert(s); - assert(domain); + assert(q); + + question = dns_query_question_for_protocol(q, s->protocol); + if (!question) + return DNS_SCOPE_NO; + + domain = dns_question_first_name(question); + if (!domain) + return DNS_SCOPE_NO; + + ifindex = q->ifindex; + flags = q->flags; /* Checks if the specified domain is something to look up on this scope. Note that this accepts * non-qualified hostnames, i.e. those without any search path suffixed. */ diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h index a2b9546b38..1f9d22b7d1 100644 --- a/src/resolve/resolved-dns-scope.h +++ b/src/resolve/resolved-dns-scope.h @@ -10,7 +10,7 @@ typedef struct DnsScope DnsScope; #include "resolved-dns-cache.h" #include "resolved-dns-dnssec.h" #include "resolved-dns-packet.h" - +#include "resolved-dns-query.h" #include "resolved-dns-search-domain.h" #include "resolved-dns-server.h" #include "resolved-dns-stream.h" @@ -76,7 +76,7 @@ int dns_scope_emit_udp(DnsScope *s, int fd, int af, DnsPacket *p); int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *address, DnsServer *server, uint16_t port, union sockaddr_union *ret_socket_address); int dns_scope_socket_udp(DnsScope *s, DnsServer *server); -DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain); +DnsScopeMatch dns_scope_good_domain(DnsScope *s, DnsQuery *q); bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key); DnsServer *dns_scope_get_dns_server(DnsScope *s); From 30fa3aa1fa56d9a1a4f3a26c0bc02253d44dfa0f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 4 Feb 2022 12:05:33 +0900 Subject: [PATCH 3/3] resolve: synthesize empty domain only when A and/or AAAA key is requested Follow-up for 3b2ac14ac45bef01cf489c3231b868936866444b (#22231). Before this commit. --- $ dig -t SRV '.' ; <<>> DiG 9.16.24-RH <<>> -t SRV . ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16836 ;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; QUESTION SECTION: ;. IN SRV ;; Query time: 1 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) ;; WHEN: Fri Feb 04 12:01:09 JST 2022 ;; MSG SIZE rcvd: 28 --- After this commit. --- $ dig -t SRV '.' ; <<>> DiG 9.16.24-RH <<>> -t SRV . ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19861 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; QUESTION SECTION: ;. IN SRV ;; AUTHORITY SECTION: . 86394 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2022020302 1800 900 604800 86400 ;; Query time: 20 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) ;; WHEN: Fri Feb 04 12:00:12 JST 2022 ;; MSG SIZE rcvd: 103 --- Fixes #22401. --- src/resolve/resolved-dns-scope.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 69101fb5a2..16c5e0094c 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -626,10 +626,6 @@ DnsScopeMatch dns_scope_good_domain( if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, false, false) & flags) == 0) return DNS_SCOPE_NO; - /* Never resolve empty name. */ - if (dns_name_is_empty(domain)) - return DNS_SCOPE_NO; - /* Never resolve any loopback hostname or IP address via DNS, LLMNR or mDNS. Instead, always rely on * synthesized RRs for these. */ if (is_localhost(domain) || @@ -652,6 +648,22 @@ DnsScopeMatch dns_scope_good_domain( DnsScopeMatch m; int n_best = -1; + if (dns_name_is_empty(domain)) { + DnsResourceKey *t; + bool found = false; + + /* Refuse empty name if only A and/or AAAA records are requested. */ + + DNS_QUESTION_FOREACH(t, question) + if (!IN_SET(t->type, DNS_TYPE_A, DNS_TYPE_AAAA)) { + found = true; + break; + } + + if (!found) + return DNS_SCOPE_NO; + } + /* Never route things to scopes that lack DNS servers */ if (!dns_scope_get_dns_server(s)) return DNS_SCOPE_NO;