Hi!
I wanted to get the peer credentials on an UNIX socket (not send/receive
it, just get it passively) for a small thing that I'm doing, and
couldn't find a reasonably portable way to do that in Go.
In C, almost all UNIX-alikes have getpeereid() as a somewhat portable
abstraction.
I looked into it and most systems support this feature via slightly
different variants of getsockopt(). Linux' one is already present and
works fine, but the rest (*BSD and I guess Darwin) are missing.
So I wrote
https://go-review.googlesource.com/#/c/29310/ as a proof of
concept, which seems to work fine on Linux (untested everywhere else).
I have a few questions:
1) Is this something worth doing?
https://github.com/golang/go/issues/1101 has been open about this (or at
least in part about this) for a while.
Linux support exists, and I think the functionality is useful, but would
this be something you consider too obscure/not worth doing?
2) What would the API look like?
In the proof of concept, I went with:
type UnixPeerCreds struct { Uid, Gid, Pid int }
func (c *UnixConn) GetPeerCredentials() (creds *UnixPeerCreds, err error)
so that it could be potentially extended in the future, does this seem
ok to you? If not, what would you suggest?
3) What's the best way to implement it?
In the proof of concept I extended the syscall package with different
GetsockoptXXX functions, according to the platform; and then used them
in os-specific files in the net package.
However, IIUC the syscall package is supposed to be frozen. I looked at
internal/syscall/unix/ but it doesn't have much, and in particular does
not seem to have any use of cgo to get structures from C, so I'm not
sure if that'd be allowed there.
Similarly, are OS-specific files in net the best way? Should I just
provide a getpeereid()-equivalent at the syscall level, and then avoid
OS-specific files in net entirely?
What would be the right approach here?
Thanks a lot!
Alberto
PS: In case it's useful for reference, here are some of the
implementations of getpeereid() for non-Linux. Go already supports it on
Linux via syscall.GetsockoptUcred.
Linux+others:
https://cgit.freedesktop.org/libbsd/tree/src/getpeereid.c
FreeBSD:
https://github.com/freebsd/freebsd/blob/master/lib/libc/gen/getpeereid.c
OpenBSD:
https://github.com/openbsd/src/blob/master/lib/libc/net/getpeereid.c
DragonflyBSD:
https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/lib/libc/gen/getpeereid.c
NetBSD:
https://github.com/jsonn/src/blob/trunk/lib/libc/net/getpeereid.c
Darwin:
http://opensource.apple.com/source/Libc/Libc-1081.1.3/gen/FreeBSD/getpeereid.c (?)