Repository: go
Issue: net: DNS address resolution quirks (AAAA records inconsistency)
Labels: NeedsInvestigation

This bug reports is about an inconsistency on how resolution is handled between the Go resolver and the CGO one.

I do not expect a bugfix (although probably beneficial, but I leave that estimation to others) but at least an understanding of why the Go resolver behaves this way.

### What version of Go are you using (`go version`)?
```
go version go1.10.1 linux/amd64
```

### Does this issue reproduce with the latest release?
Latest release is 1.10.2 at the time of writing; not tested, by reading the release notes, nothing should have changed on the relevant code.

### What operating system and processor architecture are you using (`go env`)?
```
GOARCH="amd64"
GOBIN=""
GOCACHE="[...]"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="[...]"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build482647299=/tmp/go-build -gno-record-gcc-switches"
```

### Test setup

issue25321.go can be obtained from https://play.golang.org/p/kE_Unq4VvkO

IPv6 is disabled on this box; the DNS server may or may not return `AAAA` records (I have a toggle for that).

When AAAA answers are allowed:
```
$ nslookup -query=AAAA www.googleapis.com
Server:		127.0.0.1
Address:	127.0.0.1#53

Non-authoritative answer:
www.googleapis.com	canonical name = googleapis.l.google.com.
googleapis.l.google.com	has AAAA address 2a00:1450:4001:825::200a

Authoritative answers can be found from:

```
When they are not allowed:
```
$ nslookup -query=AAAA www.googleapis.com
Server:		127.0.0.1
Address:	127.0.0.1#53

*** Can't find www.googleapis.com: No answer

```

But in both cases, an A query works:
```
$ nslookup -query=A www.googleapis.com
;; Warning: Message parser reports malformed message packet.
;; Truncated, retrying in TCP mode.
Server:		127.0.0.1
Address:	127.0.0.1#53

Non-authoritative answer:
www.googleapis.com	canonical name = googleapis.l.google.com.
Name:	googleapis.l.google.com
Address: 216.58.207.74
[... amended ...]
```
### Test results

Reminder: IPv6 is always disabled, only the netdns resolver and the responses of the DNS are varying for the below tests.

| Command        | DNS returns AAAA           | DNS does not return AAAA  |
| ------------- |-------------| -----|
| `go run issue25321.go`      | :finnadie: `2018/05/10 00:52:01 dial failed www.googleapis.com Get http://[2a00:1450:4001:821::200a]:80/: dial tcp [2a00:1450:4001:821::200a]:80: connect: cannot assign requested address`<br>`2018/05/10 00:52:11 HTTP failed www.googleapis.com Get http://www.googleapis.com/: dial tcp [2a00:1450:4001:821::200a]:80: connect: cannot assign requested address` | :finnadie: `2018/05/10 00:43:23 dial failed www.googleapis.com lookup www.googleapis.com on 127.0.0.1:53: read udp 127.0.0.1:59700->127.0.0.1:53: i/o timeout`<br>`2018/05/10 00:43:33 HTTP failed www.googleapis.com Get http://www.googleapis.com/: dial tcp: lookup www.googleapis.com on 127.0.0.1:53: read udp 127.0.0.1:43538->127.0.0.1:53: i/o timeout` |
| `GODEBUG=netdns=cgo go run issue25321.go`      |   :feelsgood: `2018/05/10 00:47:23 dial failed www.googleapis.com Get http://[2a00:1450:4001:81d::200a]:80/: dial tcp [2a00:1450:4001:81d::200a]:80: connect: cannot assign requested address`<br>`2018/05/10 00:47:23 OK www.googleapis.com 192.168.1.12:57248 -> 216.58.207.74:80`    |  :suspect: `2018/05/10 00:43:07 OK www.googleapis.com 192.168.1.12:57156 -> 216.58.207.74:80` |

Forgive the horrible representation, but there are two log lines at most in those table cells, you can see them better by copy/pasting their content.

Worthy of note: in the case of CGO resolver and AAAA answers allowed, first there is a failure (dialer) and then a success (HTTP request).

Another note: resolving `www.bing.com` is not affected by this problem, so problem must be related to how the records are returned from the DNS.

### Expected results
The expected result for all the 4 combinations would be (since IPv6 is disabled on this box): do not try `AAAA` and use an `A` record, like on the bottom-right cell of the tests matrix.

### Questions arising from this test

1. how is the order of answers handled? is there a preference to `AAAA` records somehow? (I am inclined to think so)
2. how could ever the resolution timeout when no `AAAA` is returned? this would be somehow the most serious part of the bug (if acknowledged), although it should first be determined if it is not a problem of the DNS (server-side)

### Related

* #8453
*  https://github.com/ncw/rclone/issues/2302