mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-03-06 12:58:22 +03:00
resolved: rework how we determine which scope to send a query to
Fixes: #10830 #9825 #9472
This commit is contained in:
parent
89307df394
commit
a97a3b256c
@ -682,22 +682,15 @@ int dns_query_go(DnsQuery *q) {
|
||||
continue;
|
||||
|
||||
match = dns_scope_good_domain(s, q->ifindex, q->flags, name);
|
||||
if (match < 0)
|
||||
return match;
|
||||
|
||||
if (match == DNS_SCOPE_NO)
|
||||
if (match < 0) {
|
||||
log_debug("Couldn't check if '%s' matches against scope, ignoring.", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
found = match;
|
||||
|
||||
if (match == DNS_SCOPE_YES) {
|
||||
if (match > found) { /* Does this match better? If so, remember how well it matched, and the first one
|
||||
* that matches this well */
|
||||
found = match;
|
||||
first = s;
|
||||
break;
|
||||
} else {
|
||||
assert(match == DNS_SCOPE_MAYBE);
|
||||
|
||||
if (!first)
|
||||
first = s;
|
||||
}
|
||||
}
|
||||
|
||||
@ -725,10 +718,12 @@ int dns_query_go(DnsQuery *q) {
|
||||
continue;
|
||||
|
||||
match = dns_scope_good_domain(s, q->ifindex, q->flags, name);
|
||||
if (match < 0)
|
||||
goto fail;
|
||||
if (match < 0) {
|
||||
log_debug("Couldn't check if '%s' matches agains scope, ignoring.", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (match != found)
|
||||
if (match < found)
|
||||
continue;
|
||||
|
||||
r = dns_query_add_candidate(q, s);
|
||||
|
@ -459,9 +459,25 @@ int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *add
|
||||
return dns_scope_socket(s, SOCK_STREAM, family, address, server, port, ret_socket_address);
|
||||
}
|
||||
|
||||
DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
|
||||
DnsScopeMatch dns_scope_good_domain(
|
||||
DnsScope *s,
|
||||
int ifindex,
|
||||
uint64_t flags,
|
||||
const char *domain) {
|
||||
|
||||
DnsSearchDomain *d;
|
||||
|
||||
/* This returns the following return values:
|
||||
*
|
||||
* DNS_SCOPE_NO → This scope is not suitable for lookups of this domain, at all
|
||||
* DNS_SCOPE_MAYBE → This scope is suitable, but only if nothing else wants it
|
||||
* DNS_SCOPE_YES_BASE+n → This scope is suitable, and 'n' suffix labels match
|
||||
*
|
||||
* (The idea is that the caller will only use the scopes with the longest 'n' returned. If no scopes return
|
||||
* DNS_SCOPE_YES_BASE+n, then it should use those which returned DNS_SCOPE_MAYBE. It should never use those
|
||||
* which returned DNS_SCOPE_NO.)
|
||||
*/
|
||||
|
||||
assert(s);
|
||||
assert(domain);
|
||||
|
||||
@ -497,6 +513,7 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
|
||||
|
||||
case DNS_PROTOCOL_DNS: {
|
||||
DnsServer *dns_server;
|
||||
int n_best = -1;
|
||||
|
||||
/* Never route things to scopes that lack DNS servers */
|
||||
dns_server = dns_scope_get_dns_server(s);
|
||||
@ -507,8 +524,22 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
|
||||
* we return DNS_SCOPE_YES here, rather than just DNS_SCOPE_MAYBE, which means other wildcard scopes
|
||||
* won't be considered anymore. */
|
||||
LIST_FOREACH(domains, d, dns_scope_get_search_domains(s))
|
||||
if (dns_name_endswith(domain, d->name) > 0)
|
||||
return DNS_SCOPE_YES;
|
||||
if (dns_name_endswith(domain, d->name) > 0) {
|
||||
int c;
|
||||
|
||||
c = dns_name_count_labels(d->name);
|
||||
if (c < 0)
|
||||
continue;
|
||||
|
||||
if (c > n_best)
|
||||
n_best = c;
|
||||
}
|
||||
|
||||
/* Let's return the number of labels in the best matching result */
|
||||
if (n_best >= 0) {
|
||||
assert(n_best <= DNS_SCOPE_YES_END - DNS_SCOPE_YES_BASE);
|
||||
return DNS_SCOPE_YES_BASE + n_best;
|
||||
}
|
||||
|
||||
/* If the DNS server has route-only domains, don't send other requests to it. This would be a privacy
|
||||
* violation, will most probably fail anyway, and adds unnecessary load. */
|
||||
|
@ -18,7 +18,8 @@ typedef struct DnsScope DnsScope;
|
||||
typedef enum DnsScopeMatch {
|
||||
DNS_SCOPE_NO,
|
||||
DNS_SCOPE_MAYBE,
|
||||
DNS_SCOPE_YES,
|
||||
DNS_SCOPE_YES_BASE, /* Add the number of matching labels to this */
|
||||
DNS_SCOPE_YES_END = DNS_SCOPE_YES_BASE + DNS_N_LABELS_MAX,
|
||||
_DNS_SCOPE_MATCH_MAX,
|
||||
_DNS_SCOPE_MATCH_INVALID = -1
|
||||
} DnsScopeMatch;
|
||||
|
Loading…
x
Reference in New Issue
Block a user