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

$ go version
go version go1.16.6 linux/amd64

In my go.mod:

golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d

Does this issue reproduce with the latest release?

Yes

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/mitinarseny/.cache/go-build"
GOENV="/home/mitinarseny/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/mitinarseny/dev/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/mitinarseny/dev/go"
GOPRIVATE=""
GOROOT="/usr/lib/go"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/mitinarseny/dev/pingo/go.mod"
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-build2246281240=/tmp/go-build -gno-record-gcc-switches"

My Linux kernel is:

$ uname -a
Linux mitinarseny 5.13.8_1 #1 SMP Wed Aug 4 15:28:27 UTC 2021 x86_64 GNU/Linux

What did you do?

I am trying to implement socket timestamps in pingo.

Firstly, create socket with following:

s, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, unix.IPPROTO_ICMP)
if err != nil {
    return nil, os.NewSyscallError("socket", err)
}
if err := unix.SetsockoptInt(s, unix.IPPROTO_IP, unix.IP_RECVERR, 1); err != nil {
    unix.Close(s)
    return nil, os.NewSyscallError("setsockopt", err)
}
// TODO: this may be not supported
if err := unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_TIMESTAMPNS, 1); err != nil {
    unix.Close(s)
    return nil, os.NewSyscallError("setsockopt", err)
}
// TODO: unix.SOF_TIMESTAMPING_OPT_TSONLY
if err := unix.SetsockoptInt(s, unix.SOL_SOCKET, unix.SO_TIMESTAMPING,
    unix.SOF_TIMESTAMPING_RX_SOFTWARE|
    unix.SOF_TIMESTAMPING_TX_SOFTWARE|
    unix.SOF_TIMESTAMPING_OPT_CMSG|
    unix.SOF_TIMESTAMPING_OPT_ID|
    unix.SOF_TIMESTAMPING_TX_SCHED|
    unix.SOF_TIMESTAMPING_SOFTWARE); err != nil {
    unix.Close(s)
    return nil, os.NewSyscallError("setsockopt", err)
}
if err := unix.Bind(s, sockaddr(laddr)); err != nil {
    unix.Close(s)
    return nil, os.NewSyscallError("bind", err)
}
f := os.NewFile(uintptr(s), "datagram-oriented icmp")
c, err := net.FilePacketConn(f)
if cerr := f.Close(); cerr != nil {
    return nil, cerr
}
return c, err

Then, create ipv4.PacketConn:

c4 := ipv4.NewPacketConn(c)

Then I am trying to receive multiple messages with from socket's error queue:

n, err := p.c4.ReadBatch(ms, unix.MSG_ERRQUEUE|unix.MSG_DONTWAIT)

What did you expect to see?

Nil error

What did you see instead?

The error at this point is following:

read udp 0.0.0.0:59: invalid address

Which originates from here: https://github.com/golang/net/blob/60bc85c4be6d32924bcfddb728394cb8713f2c78/internal/socket/rawconn_mmsg.go#L22-L24 https://github.com/golang/net/blob/60bc85c4be6d32924bcfddb728394cb8713f2c78/internal/socket/sys_posix.go#L67-L70

I guess, kernel does not put any address for transmit timestamp messages, so there should be nothing to parse. This leads to an error, which is created by errors.New, which is unable to detect with errors.Is from the perspective of caller.

Comment From: mitinarseny

Any progress?

Comment From: hendrikcech

This problem is still present with go1.24.3 on linux/amd64.