Skip to content

syscall: Peername() does not work on socketpair sockets on Illumos #53739

Open
@problame

Description

@problame

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

$ go version
go version go1.17.5 linux/amd64

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
O111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/cs/.cache/go-build"
GOENV="/home/cs/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/cs/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/cs/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/cs/go1.17.5"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/cs/go1.17.5/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.5"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/cs/zrepl/zrepl/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-build1505417924=/tmp/go-build -gno-record-gcc-switches"

What did you do?

(This is the presumed root cause for zrepl/zrepl#598 )

Take the following code snippet:

package main

import (
	"log"
	"syscall"
)

func main() {
	fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
	if err != nil {
		panic(err)
	}

	sockname, err := syscall.Getsockname(fds[0])
	if err != nil {
		panic(err)
	}

	peername, err := syscall.Getpeername(fds[0])
	if err != nil {
		panic(err)
	}

	log.Printf("socketname=%T %#v", sockname, sockname)
	log.Printf("peername=%T %#v", peername, peername)
}

What did you expect to see?

On Linux, it prints

2022/07/08 00:30:11 socketname=*syscall.SockaddrUnix &syscall.SockaddrUnix{Name:"@", raw:syscall.RawSockaddrUnix{Family:0x0, Path:[108]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}
2022/07/08 00:30:11 peername=*syscall.SockaddrUnix &syscall.SockaddrUnix{Name:"@", raw:syscall.RawSockaddrUnix{Family:0x0, Path:[108]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}

On Illumos (SunOS openindiana 5.11 illumos-e302d6af52 i86pc i386 i86pc), Getpeername appears to not work

root@openindiana:~# /opt/iss-589-repro 
panic: address family not supported by protocol family

goroutine 1 [running]:
main.main()
        /home/cs/zrepl/zrepl/iss-589/iss-589-repro.go:21 +0x237

Ccompiled with

GOARCH=amd64 GOOS=illumos go build -o iss-589-repro ./iss-589
scp iss-589-repro root@192.168.122.33:/opt/

However, a corresponding C program works fine on both platforms, i.e., the getpeername libc call returns no error.

#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <aio.h>

int main() {

    int fds[2];
    int err = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
    if (err != 0)
        abort();

    struct sockaddr_un name;
    socklen_t len = sizeof(name);
    err = getpeername(fds[0], (struct sockaddr *)&name, &len);
    if (err != 0)
        abort();

    printf("sun_path=%s\n", name.sun_path);

    return 0;
}

Compiled with:

gcc -lsocket test.c

Relevant truss of the Go program:

/1:     so_socket(PF_UNIX, SOCK_STREAM, 0, 0x00000000, SOV_XPG4_2) = 3
/1:     so_socket(PF_UNIX, SOCK_STREAM, 0, 0x00000000, SOV_XPG4_2) = 4
/1:     so_socketpair(0xC00004EEC8)                     = 0
/1:     close(3)                                        = 0
/1:     getsockname(5, 0xC00004EDD4, 0xC00004EDD0, SOV_DEFAULT) = 0
/1:     getpeername(5, 0xC00004EDD4, 0xC00004EDD0, SOV_DEFAULT) = 0

Relevant truss of the C program:

so_socket(PF_UNIX, SOCK_STREAM, 0, 0x00000000, SOV_DEFAULT) = 3
so_socket(PF_UNIX, SOCK_STREAM, 0, 0x00000000, SOV_DEFAULT) = 4
so_socketpair(0x7FFFBFFFD4D4)                   = 0
close(3)                                        = 0
getpeername(5, 0x7FFFBFFFD460, 0x7FFFBFFFD45C, SOV_DEFAULT) = 0

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-SolarisOS-illumoscompiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Triage Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions