浏览代码

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 <github@gone.nl>
Signed-off-by: Tibor Vass <tibor@docker.com>
Sebastiaan van Stijn 5 年之前
父节点
当前提交
efe0ab37a1
共有 1 个文件被更改,包括 1 次插入1 次删除
  1. 1 1
      libnetwork/resolver.go

+ 1 - 1
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