summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Yan <tom.ty89@gmail.com>2021-12-08 10:53:07 +0800
committerTom Yan <tom.ty89@gmail.com>2021-12-13 23:08:40 +0800
commitaf45251e4ce2ff48eb86769cccf48ffd51f49ce0 (patch)
treed211530f6cf305a0984d7088f13a1b618a0f6a1e
parentfdae4504c78861e7c628b64055dea59a77e2641f (diff)
downloadsystemd-af45251e4ce2ff48eb86769cccf48ffd51f49ce0.tar.gz
resolved: filter stub listeners in manager_get_dns_server()
Commit 49ef064c8dcd8ed12d98e6c705e676babade0897 attempts to handle "stub loop" by switching to the next server *after the query has been made*. The approach may be good enough for link scopes. However, for the manager / global scope, it is not. First of all, there are more than one types (SYSTEM and FALLBACK) of servers it can use. Also, whether those of type FALLBACK should be used depends. Besides, dns_scope_good_domain() determines whether things should be routed to a scope by checking whether the scope has a server. The decision made would be incorrect if stubs were not filtered beforehand. Therefore, to avoid failing query unnecessarily, and to make sure that extra stub listeners will not trigger unexpected and/or inconsistent behavior, make manager_get_dns_server() do what it should have done.
-rw-r--r--src/resolve/resolved-dns-server.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 7d180378b6..cd755b13d4 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -875,9 +875,18 @@ DnsServer *manager_get_dns_server(Manager *m) {
manager_read_resolv_conf(m);
/* If no DNS server was chosen so far, pick the first one */
- if (!m->current_dns_server)
+ if (!m->current_dns_server ||
+ /* In case m->current_dns_server != m->dns_servers */
+ manager_server_is_stub(m, m->current_dns_server))
manager_set_dns_server(m, m->dns_servers);
+ while (m->current_dns_server &&
+ manager_server_is_stub(m, m->current_dns_server)) {
+ manager_next_dns_server(m, NULL);
+ if (m->current_dns_server == m->dns_servers)
+ manager_set_dns_server(m, NULL);
+ }
+
if (!m->current_dns_server) {
bool found = false;