Skip to content

x/sys: cannot create AF_UNSPEC sockaddr #64006

Description

@msteinert

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

$ go version
go version go1.21.3 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
$ go env
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/msteinert/Library/Caches/go-build'
GOENV='/Users/msteinert/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/msteinert/go/pkg/mod'
GONOPROXY='git.drwholdings.com'
GONOSUMDB='git.drwholdings.com'
GOOS='darwin'
GOPATH='/Users/msteinert/go'
GOPRIVATE='git.drwholdings.com'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.21.3/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.21.3/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.3'
GCCGO='gccgo'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/Users/msteinert/src/git/monstack/jimi/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/fold
ers/m5/f15ps3xd7lz2gbn361wzn07r0000gp/T/go-build3450338831=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

I would like to reset/disconnect a socket connection. The specification for connect says:

If the sa_family member of address is AF_UNSPEC, the socket's peer address shall be reset.

What did you expect to see?

A way to call unix.Connect with a socket address that has the family set to AF_UNSPEC.

For example, a SockaddrUnspec type:

diff --git a/unix/syscall_unix.go b/unix/syscall_unix.go
index 77081de..548855f 100644
--- a/unix/syscall_unix.go
+++ b/unix/syscall_unix.go
@@ -232,6 +232,17 @@ type SockaddrUnix struct {
        raw  RawSockaddrUnix
 }

+// SockaddrUnspec implements the Sockaddr interface for AF_UNSPEC type sockets.
+type SockaddrUnspec struct {
+ raw RawSockaddr
+}
+
+func (sa *SockaddrUnspec) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Len = 16
+ sa.raw.Family = AF_UNSPEC
+ return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
 func Bind(fd int, sa Sockaddr) (err error) {
        ptr, n, err := sa.sockaddr()
        if err != nil {

I tested the above patch with the following function:

func Disconnect(fd int) error {
        sa := unix.SockaddrUnspec{}
        var err error = unix.EINTR
        for err == unix.EINTR {
                err = unix.Connect(fd, &sa)
        }
        if err != nil {
                if err != unix.EAFNOSUPPORT && err != unix.EINVAL {
                        return err
                }
        }
        return nil
}

The connect manpage on MacOS also mentions that passing a NULL address achieves the same effect. When I passed a nil address to unix.Connect I got a segmentation fault.

I realize this patch is probably not formatted correctly. It looks like the struct size and the sockaddr() interface function should be generated per-platform basis. I submitted a bug/question here to see if there is another way to do it or if something like the above patch might be accepted (if I figure out how to do it correctly).

What did you see instead?

No way to pass an AF_UNSPEC address to unix.Connect.

Activity

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

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

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions