diff options
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/resolved-dns-scope.c | 8 | ||||
-rw-r--r-- | src/resolve/resolved-dns-server.c | 21 | ||||
-rw-r--r-- | src/resolve/resolved-dns-server.h | 2 | ||||
-rw-r--r-- | src/resolve/resolved-resolv-conf.c | 10 |
4 files changed, 41 insertions, 0 deletions
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index ed0c6aa105..03811ac8e7 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -407,6 +407,7 @@ int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *add DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) { DnsSearchDomain *d; + DnsServer *dns_server; assert(s); assert(domain); @@ -447,6 +448,13 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co if (dns_name_endswith(domain, d->name) > 0) return DNS_SCOPE_YES; + /* 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. */ + dns_server = dns_scope_get_dns_server(s); + if (dns_server && dns_server_limited_domains(dns_server)) + return DNS_SCOPE_NO; + switch (s->protocol) { case DNS_PROTOCOL_DNS: diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index 9b7b471600..97cc8c0e09 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -576,6 +576,27 @@ void dns_server_warn_downgrade(DnsServer *server) { server->warned_downgrade = true; } +bool dns_server_limited_domains(DnsServer *server) +{ + DnsSearchDomain *domain; + bool domain_restricted = false; + + /* Check if the server has route-only domains without ~., i. e. whether + * it should only be used for particular domains */ + if (!server->link) + return false; + + LIST_FOREACH(domains, domain, server->link->search_domains) + if (domain->route_only) { + domain_restricted = true; + /* ~. means "any domain", thus it is a global server */ + if (streq(DNS_SEARCH_DOMAIN_NAME(domain), ".")) + return false; + } + + return domain_restricted; +} + static void dns_server_hash_func(const void *p, struct siphash *state) { const DnsServer *s = p; diff --git a/src/resolve/resolved-dns-server.h b/src/resolve/resolved-dns-server.h index c1732faffd..83e288a202 100644 --- a/src/resolve/resolved-dns-server.h +++ b/src/resolve/resolved-dns-server.h @@ -128,6 +128,8 @@ bool dns_server_dnssec_supported(DnsServer *server); void dns_server_warn_downgrade(DnsServer *server); +bool dns_server_limited_domains(DnsServer *server); + DnsServer *dns_server_find(DnsServer *first, int family, const union in_addr_union *in_addr, int ifindex); void dns_server_unlink_all(DnsServer *first); diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c index 31b25ca50f..801014caf5 100644 --- a/src/resolve/resolved-resolv-conf.c +++ b/src/resolve/resolved-resolv-conf.c @@ -154,6 +154,16 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) { return; } + /* Check if the DNS server is limited to particular domains; + * resolv.conf does not have a syntax to express that, so it must not + * appear as a global name server to avoid routing unrelated domains to + * it (which is a privacy violation, will most probably fail anyway, + * and adds unnecessary load) */ + if (dns_server_limited_domains(s)) { + log_debug("DNS server %s has route-only domains, not using as global name server", dns_server_string(s)); + return; + } + if (*count == MAXNS) fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f); (*count)++; |