summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-08 02:29:02 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-11 19:39:59 +0100
commit6a1a5eec43892dee3ff6e208bceb1931c25c782e (patch)
treeb82947accaac31a912efacc2334b7fab08279908 /src
parentresolved: introduce dns_transaction_retry() and use it everywhere (diff)
downloadsystemd-6a1a5eec43892dee3ff6e208bceb1931c25c782e.tar.xz
systemd-6a1a5eec43892dee3ff6e208bceb1931c25c782e.zip
resolved: when DNS/TCP doesn't work, try DNS/UDP again
If we failed to contact a DNS server via TCP, bump of the feature level to UDP again. This way we'll switch back between UDP and TCP if we fail to contact a host. Generally, we prefer UDP over TCP, which is why UDP is a higher feature level. But some servers only support UDP but not TCP hence when reaching the lowest feature level of TCP and want to downgrade from there, pick UDP again. We this keep downgrading until we reach TCP and then we cycle through UDP and TCP.
Diffstat (limited to 'src')
-rw-r--r--src/resolve/resolved-dns-server.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index fbd1c27c14..0de6c8cec0 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -326,11 +326,21 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
log_info("Grace period over, resuming full feature set for DNS server %s", strna(ip));
} else if (s->possible_feature_level <= s->verified_feature_level)
s->possible_feature_level = s->verified_feature_level;
- else if (s->n_failed_attempts >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS &&
- s->possible_feature_level > DNS_SERVER_FEATURE_LEVEL_WORST) {
+ else if (s->n_failed_attempts >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS) {
_cleanup_free_ char *ip = NULL;
- s->possible_feature_level --;
+ /* Switch one feature level down. Except when we are at TCP already, in which case we try UDP
+ * again. Thus, if a DNS server is not responding we'll keep toggling between UDP and TCP until it
+ * responds on one of them. Note that we generally prefer UDP over TCP (which is why it is at a higher
+ * feature level), but many DNS servers support lack TCP support. */
+
+ if (s->possible_feature_level == DNS_SERVER_FEATURE_LEVEL_TCP)
+ s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_UDP;
+ else {
+ assert(s->possible_feature_level > DNS_SERVER_FEATURE_LEVEL_WORST);
+ s->possible_feature_level --;
+ }
+
s->n_failed_attempts = 0;
s->verified_usec = 0;