Skip to content

net: DNS Resolution functions return truncated results when UDP responses are fragmented #69644

Closed
@LeeBrotherston

Description

@LeeBrotherston

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions