From efe0ab37a1ded98fe879c366ccfa6d6db3d6ed78 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 20 May 2020 15:11:34 +0200 Subject: [PATCH] Resolver: fix error handling if we didn't receive a response Commit 2a480d515e9c44533922f453649a866048a40a75 updated the DNS library and updated the error handling. Due to changes in the library, we now had to check the response itself to check if the response was truncated (Truncated DNS replies should be sent to the client so that the client can retry over TCP). However, 1e02aae252fdd8878daf59baefddb0526a5410b1 added an incorrect `nil` check to fix a panic, which ignored situations where an error was returned, but no response (for example, if we failed to connect to the DNS server). In that situation, the error would be ignored, and further down we would consider the connection to have been succesfull, but the DNS server not returning a result. After a "successful" lookup (but no results), we break the loop, and don't attempt lookups in other DNS servers. Versions before 1e02aae252fdd8878daf59baefddb0526a5410b1 would produce: Name To resolve: bbc.co.uk. [resolver] query bbc.co.uk. (A) from 172.21.0.2:36181, forwarding to udp:192.168.5.1 [resolver] read from DNS server failed, read udp 172.21.0.2:36181->192.168.5.1:53: i/o timeout [resolver] query bbc.co.uk. (A) from 172.21.0.2:38582, forwarding to udp:8.8.8.8 [resolver] received A record "151.101.0.81" for "bbc.co.uk." from udp:8.8.8.8 [resolver] received A record "151.101.192.81" for "bbc.co.uk." from udp:8.8.8.8 [resolver] received A record "151.101.64.81" for "bbc.co.uk." from udp:8.8.8.8 [resolver] received A record "151.101.128.81" for "bbc.co.uk." from udp:8.8.8.8 Versions after that commit would ignore the error, and stop further lookups: Name To resolve: bbc.co.uk. [resolver] query bbc.co.uk. (A) from 172.21.0.2:59870, forwarding to udp:192.168.5.1 [resolver] external DNS udp:192.168.5.1 returned empty response for "bbc.co.uk." This patch updates the logic to handle the error to log the error (and continue with the next DNS): - if an error is returned, and no response was received - if an error is returned, but it was not related to a truncated response Signed-off-by: Sebastiaan van Stijn Signed-off-by: Tibor Vass --- libnetwork/resolver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnetwork/resolver.go b/libnetwork/resolver.go index e32522a254..bc8b964cdf 100644 --- a/libnetwork/resolver.go +++ b/libnetwork/resolver.go @@ -484,7 +484,7 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { resp, err = co.ReadMsg() // Truncated DNS replies should be sent to the client so that the // client can retry over TCP - if err != nil && (resp != nil && !resp.Truncated) { + if err != nil && (resp == nil || !resp.Truncated) { r.forwardQueryEnd() logrus.Debugf("[resolver] read from DNS server failed, %s", err) continue