Description
Go version
go version go1.23.1 darwin/arm64
Output of go env
in your module/workspace:
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/lee/Library/Caches/go-build'
GOENV='/Users/lee/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/lee/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/lee/go'
GOPRIVATE=''
GOPROXY='direct'
GOROOT='/opt/homebrew/Cellar/go/1.23.1/libexec'
GOSUMDB='off'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.23.1/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.23.1'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/lee/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/lee/tmp/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/j3/qv7s4b3j6jdd5h58n8jncnz80000gp/T/go-build1232499662=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
Select a DNS query which will return a response larger than the current MTU on your default interface. To illustrate I am using nat.travisci.net
is it returns 79 A records, with a packet size of just over 1300.
If you run the code snippet below, whilst connected via a standard ethernet connection (probably 1500 MTU), you should get 79 responses, which can be verified by comparing the output of the same query using nslookup
, host
, dig
, etc.
If you now use a connection with a lower MTU, for example using a VPN lowers my MTU to 1280, and run the same tests you will see that the code snippet below only returns 29 results, while nslookup
, host
, dig
, etc still return the full set of results.
If we use some sort of packetsniffer (e.g. wireshark, tcpdump, etc) to analyze the data on the wire, we can see that the response is fragmented due to being larger than the MTU, as we would expect. As far as I can tell the other tools successfully reconstruct the packet from the fragments, however go seems to truncate the response, presumably due to the fragmentation.
This seems to happen on Linux as well as macOS, with and without CGO.
Snippet for testing:
package main
import (
"fmt"
"net"
)
func main() {
ipList, err := net.LookupIP("nat.travisci.net")
if err != nil {
fmt.Printf("there was a problem: %s\n", err)
return
}
fmt.Printf("len: %d\n", len(ipList))
for x, y := range ipList {
fmt.Printf("%d => %v\n", x, y)
}
return
}
What did you see happen?
I saw the go lookup return truncated results whilst on a lower MTU connection, while nslookup, etc continued to return the full results.
What did you expect to see?
I expected to see the same results between the sample code and nslookup, etc no matter which connection I was using.