resolved: Recover from slow DNS responses
authorKai Krakow <kai@kaishome.de>
Sat, 13 May 2017 10:30:56 +0000 (12:30 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 27 Jun 2017 20:04:16 +0000 (22:04 +0200)
When DNS is unreliable temporarily, the current implementation will
never improve resend behavior again and switch DNS servers only late
(current maximum timeout is 5 seconds).

We can improve this by biasing the resend_timeout back to the current
RTT when a successful response was received. Next time, a timeout is hit
on this server, it will switch to the next server faster.

Fixes: #5953

src/resolve/resolved-dns-server.c

index 63cb6a5..9c3ee01 100644 (file)
@@ -304,7 +304,10 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve
         if (s->max_rtt < rtt) {
                 s->max_rtt = rtt;
                 s->resend_timeout = CLAMP(s->max_rtt * 2, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
-        }
+        } else if (s->resend_timeout > rtt)
+                /* If we received the packet faster than the resend_timeout, bias
+                 * the resend_timeout back to the rtt. */
+                s->resend_timeout = CLAMP((2 * s->resend_timeout + rtt) / 3, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
 }
 
 void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel level, usec_t usec) {