Skip to content

net: Dialer.Dial{TCP,UDP,IP} incorrectly treats invalid addresses as :: #81620

Closed

Description

@database64128

Go version

go version go1.27.1-X:nodwarf5 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v3'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN='/home/database64128/go/bin'
GOCACHE='/home/database64128/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/database64128/.config/go/env'
GOEXE=''
GOEXPERIMENT='nodwarf5'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1790460134=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/database64128/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPACKAGESDRIVER=''
GOPATH='/home/database64128/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/database64128/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.27.1-X:nodwarf5'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Call one of the context-aware Dialer methods DialTCP, DialUDP, DialIP (introduced in #49097, Go 1.26) with zero value laddr and/or raddr.

What did you see happen?

For DialTCP, DialUDP, the zero value netip.AddrPort is treated as [::]:0.

For DialIP, the zero value netip.Addr is treated as ::.

What did you expect to see?

If raddr is the zero value, return an error, just like other dial methods and functions.

If laddr is the zero value, do not call bind(2) before connect(2). Calling bind([::]:0) forces the operating system to allocate an available ephemeral port to the socket, because it does not know whether the next call will be listen(2) or connect(2). This disables source 2-tuple reuse for TCP sockets, and will result in ephemeral port exhaustion on busy servers. Read more about it in https://blog.cloudflare.com/how-to-stop-running-out-of-ephemeral-ports-and-start-to-love-long-lived-connections/

The current implementation unconditionally calls TCPAddrFromAddrPort/UDPAddrFromAddrPort/ipAddrFromAddr on laddr and raddr, and then passes a non-nil *net.TCPAddr/*net.UDPAddr/*net.IPAddr to the old dial functions. These are equivalent to [::]:0 and causes bind(2) to be called on the socket.

This is an easy fix. Sending a CL.

Update: mailed CL 835805

Activity

  1. gopherbot commented on Sep 20, 2026

    @gopherbot
    Contributor

    Change https://go.dev/cl/835805 mentions this issue: net: fix zero value address handling in Dialer.Dial{TCP,UDP,IP}

  2. database64128 commented on Sep 20, 2026

    @database64128
    ContributorAuthor
  3. prattmic commented on Sep 29, 2026

    @prattmic
    Member
  4. added
    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
    on Sep 29, 2026
  5. added
    FixPendingIssues that have a fix which has not yet been reviewed or submitted.
    and removed
    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
    on Oct 5, 2026
  6. added this to the Go1.28 milestone on Oct 5, 2026
  7. database64128 commented on Oct 5, 2026

    @database64128
    ContributorAuthor

    @gopherbot please open backport issues. As mentioned in the issue description, users who migrate to these new APIs could face port exhaustion issues that would result in reduced capacity or service disruption. The merged fix just adds trivial address validity checks, so the risk should be very low.

    On the other hand, the easiest workaround is to simply not migrate until 1.28. But that'd be a very confusing situation, since these methods were added in Go 1.26, but then you're not supposed to use them until 1.28. A more involved workaround is to unconditionally enable IP_BIND_ADDRESS_NO_PORT, but that's only available on Linux.

  8. gopherbot commented on Oct 5, 2026

    @gopherbot
    Contributor

    Backport issue(s) opened: #82022 (for 1.26), #82023 (for 1.28).

    Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.

  9. added a commit that references this issue on Oct 5, 2026
    0b6b838
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixPendingIssues that have a fix which has not yet been reviewed or submitted.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions