Repository: go
Issue: x/net: invalid address when reading socket error queue with SO_TIMESTAMPING
Labels: NeedsInvestigation

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version go1.16.6 linux/amd64
</pre>

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`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ 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"
</pre></details>


My Linux kernel is:
```sh
$ 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](https://www.kernel.org/doc/Documentation/networking/timestamping.txt) in [pingo](https://github.com/mitinarseny/pingo).

Firstly, create socket with following:
```go
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`:
```go
c4 := ipv4.NewPacketConn(c)
```

Then I am trying to receive multiple messages with from socket's error queue:
```go
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.