Skip to content

net: unexpected slowness with cgo resolving a domain that is manually added to /etc/hosts on Darwin #63428

@twmb

Description

@twmb

What version of Go are you using (go version)?

$ go version
go version go1.21.2 darwin/arm64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/travisbischel/Library/Caches/go-build'
GOENV='/Users/travisbischel/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/travisbischel/go/pkg/mod'
GONOPROXY='''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/travisbischel/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.21.2/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.21.2/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.2'
GCCGO='gccgo'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/travisbischel/t2/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/vn/34y9tqdx6998z47x1dwbg_f40000gn/T/go-build2882954796=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Modify /etc/hosts to contain the following line:

93.184.216.34 foo.example.local

Then have a tiny Go module:

--- go.mod ---
module foo

go 1.21.0

--- main.go ---
package main

import (
	"fmt"
	"net"
)

func main() {
	c, err := net.Dial("tcp", "foo.example.local:80")
	fmt.Println(c, err)
	if err == nil {
		c.Close()
	}
}

Then:

time go run main.go

What did you expect to see?

This to be quick.

What did you see instead?

This is slow -- always >5s.
If you use GODEBUG=netdns=go, this is fast.

I was debugging the difference between how librdkafka uses getaddr info and how Go uses getaddrinfo.
librdkafka uses a single flag, AI_ADDRCONFIG. Go uses this const which, with the mask, ends up being AI_CANONNAME.

If I change this line to 0x400 to match AI_ADDRCONFIG, the cgo resolver is fast.

I don't really understand the ramifications of the 0x1407 mask, nor which flag should be used when -- but it is odd that this specific single flag that is used forces getaddrinfo to always take 5s, whereas a different flag incantation is fast (and the pure Go resolver is also fast).

Please close this issue if this cannot be / wont be addressed, but I hope this is enough information to go on and to potentially fix something.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.OS-Darwin

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions