diff options
Diffstat (limited to 'src/resolve/resolved-dns-scope.c')
-rw-r--r-- | src/resolve/resolved-dns-scope.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index be4548599..972e661d7 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -554,9 +554,8 @@ DnsScopeMatch dns_scope_good_domain( 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. */ - if (dns_scope_has_route_only_domains(s)) + /* See if this scope is suitable as default route. */ + if (!dns_scope_is_default_route(s)) return DNS_SCOPE_NO; /* Exclude link-local IP ranges */ @@ -1392,15 +1391,17 @@ int dns_scope_remove_dnssd_services(DnsScope *scope) { return 0; } -bool dns_scope_has_route_only_domains(DnsScope *scope) { +static bool dns_scope_has_route_only_domains(DnsScope *scope) { DnsSearchDomain *domain, *first; bool route_only = false; - /* Check if the scope has any route-only domains except for "~.", i. e. whether it should only be - * used for particular domains */ + assert(scope); + assert(scope->protocol == DNS_PROTOCOL_DNS); - if (scope->protocol != DNS_PROTOCOL_DNS) - return false; + /* Returns 'true' if this scope is suitable for queries to specific domains only. For that we check + * if there are any route-only domains on this interface, as a heuristic to discern VPN-style links + * from non-VPN-style links. Returns 'false' for all other cases, i.e. if the scope is intended to + * take queries to arbitrary domains, i.e. has no routing domains set. */ if (scope->link) first = scope->link->search_domains; @@ -1408,7 +1409,10 @@ bool dns_scope_has_route_only_domains(DnsScope *scope) { first = scope->manager->search_domains; LIST_FOREACH(domains, domain, first) { - /* "." means "any domain", thus the interface takes any kind of traffic. */ + /* "." means "any domain", thus the interface takes any kind of traffic. Thus, we exit early + * here, as it doesn't really matter whether this link has any route-only domains or not, + * "~." really trumps everything and clearly indicates that this interface shall receive all + * traffic it can get. */ if (dns_name_is_root(DNS_SEARCH_DOMAIN_NAME(domain))) return false; @@ -1418,3 +1422,24 @@ bool dns_scope_has_route_only_domains(DnsScope *scope) { return route_only; } + +bool dns_scope_is_default_route(DnsScope *scope) { + assert(scope); + + /* Only use DNS scopes as default routes */ + if (scope->protocol != DNS_PROTOCOL_DNS) + return false; + + /* The global DNS scope is always suitable as default route */ + if (!scope->link) + return true; + + /* Honour whatever is explicitly configured. This is really the best approach, and trumps any + * automatic logic. */ + if (scope->link->default_route >= 0) + return scope->link->default_route; + + /* Otherwise check if we have any route-only domains, as a sensible heuristic: if so, let's not + * volunteer as default route. */ + return !dns_scope_has_route_only_domains(scope); +} |