diff options
author | Lennart Poettering <lennart@poettering.net> | 2020-11-05 17:00:20 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-02-15 21:59:05 +0100 |
commit | 5e8bc852d538544a2285ced429e3a805f13ea260 (patch) | |
tree | 9a1035166393b2fa79fc4da3fad48ba3a394aba3 /src/resolve/resolved-link.c | |
parent | resolved: reuse check for link-local IP address lookups (diff) | |
download | systemd-5e8bc852d538544a2285ced429e3a805f13ea260.tar.xz systemd-5e8bc852d538544a2285ced429e3a805f13ea260.zip |
resolved: don't redundantly switch DNS servers because of transaction failures
When a transaction fails and we decide to switch DNS servers, don#t do
so unconditionally. Check if the current DNS server is still the same as
when the transaction was initiated. And if not, do not do anything.
That should reduce the number of redundant DNS server switches if many
parallel transactions fail simultaneously (which is pretty likely if
DNSSEC is on).
Fixes: #17040
Diffstat (limited to 'src/resolve/resolved-link.c')
-rw-r--r-- | src/resolve/resolved-link.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index 3a549691c8..9778ebfff7 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -731,19 +731,27 @@ DnsServer *link_get_dns_server(Link *l) { return l->current_dns_server; } -void link_next_dns_server(Link *l) { +void link_next_dns_server(Link *l, DnsServer *if_current) { assert(l); + /* If the current server of the transaction is specified, and we already are at a different one, + * don't do anything */ + if (if_current && l->current_dns_server != if_current) + return; + + /* If currently have no DNS server, then don't do anything, we'll pick it lazily the next time a DNS + * server is needed. */ if (!l->current_dns_server) return; - /* Change to the next one, but make sure to follow the linked - * list only if this server is actually still linked. */ + /* Change to the next one, but make sure to follow the linked list only if this server is actually + * still linked. */ if (l->current_dns_server->linked && l->current_dns_server->servers_next) { link_set_dns_server(l, l->current_dns_server->servers_next); return; } + /* Pick the first one again, after we reached the end */ link_set_dns_server(l, l->dns_servers); } |