From 1957bb5e6d1f523308b49060df02171d06ddfc77 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 20 Apr 2020 15:09:32 +0200 Subject: [PATCH] unix: add SockaddrUnix tests on linux Follow the existing examples of the SockaddrTIPC and SockaddrL2TPIP{,6} tests. Handling of abstract socket addresses is different on linux than on other platforms, thus these are currently linux-specific. Change-Id: I66686d979e1dd317ab7a8a6dd85f98e670ad89b6 Reviewed-on: https://go-review.googlesource.com/c/sys/+/228764 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- unix/syscall_internal_linux_test.go | 104 ++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/unix/syscall_internal_linux_test.go b/unix/syscall_internal_linux_test.go index 4dafac80..22199b21 100644 --- a/unix/syscall_internal_linux_test.go +++ b/unix/syscall_internal_linux_test.go @@ -8,6 +8,7 @@ package unix import ( "reflect" + "strings" "testing" "unsafe" ) @@ -136,6 +137,25 @@ func Test_anyToSockaddr(t *testing.T) { }, skt: SocketSpec{domain: AF_INET6, typ: SOCK_DGRAM, protocol: IPPROTO_L2TP}, }, + { + name: "AF_UNIX unnamed/abstract", + rsa: sockaddrUnixToAny(RawSockaddrUnix{ + Family: AF_UNIX, + }), + sa: &SockaddrUnix{ + Name: "@", + }, + }, + { + name: "AF_UNIX named", + rsa: sockaddrUnixToAny(RawSockaddrUnix{ + Family: AF_UNIX, + Path: [108]int8{'g', 'o', 'p', 'h', 'e', 'r'}, + }), + sa: &SockaddrUnix{ + Name: "gopher", + }, + }, { name: "AF_MAX EAFNOSUPPORT", rsa: &RawSockaddrAny{ @@ -373,6 +393,76 @@ func TestSockaddrL2TPIP6_sockaddr(t *testing.T) { } } +func TestSockaddrUnix_sockaddr(t *testing.T) { + tests := []struct { + name string + sa *SockaddrUnix + raw *RawSockaddrUnix + slen _Socklen + err error + }{ + { + name: "unnamed", + sa: &SockaddrUnix{}, + raw: &RawSockaddrUnix{ + Family: AF_UNIX, + }, + slen: 2, // family (uint16) + }, + { + name: "abstract", + sa: &SockaddrUnix{ + Name: "@", + }, + raw: &RawSockaddrUnix{ + Family: AF_UNIX, + }, + slen: 3, // family (uint16) + NULL + }, + { + name: "named", + sa: &SockaddrUnix{ + Name: "gopher", + }, + raw: &RawSockaddrUnix{ + Family: AF_UNIX, + Path: [108]int8{'g', 'o', 'p', 'h', 'e', 'r'}, + }, + slen: _Socklen(3 + len("gopher")), // family (uint16) + len(gopher) + }, + { + name: "named too long", + sa: &SockaddrUnix{ + Name: strings.Repeat("A", 108), + }, + err: EINVAL, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + out, l, err := tt.sa.sockaddr() + if err != tt.err { + t.Fatalf("unexpected error: %v, want: %v", err, tt.err) + } + + if l != tt.slen { + t.Fatalf("unexpected Socklen: %d, want %d", l, tt.slen) + } + if out == nil { + // No pointer to cast, return early. + return + } + + raw := (*RawSockaddrUnix)(out) + if !reflect.DeepEqual(raw, tt.raw) { + t.Fatalf("unexpected RawSockaddrUnix:\n got: %#v\nwant: %#v", raw, tt.raw) + } + }) + } + +} + // These helpers explicitly copy the contents of in into out to produce // the correct sockaddr structure, without relying on unsafe casting to // a type of a larger size. @@ -402,3 +492,17 @@ func sockaddrL2TPIP6ToAny(in RawSockaddrL2TPIP6) *RawSockaddrAny { ) return &out } + +func sockaddrUnixToAny(in RawSockaddrUnix) *RawSockaddrAny { + var out RawSockaddrAny + + // Explicitly copy the contents of in into out to produce the correct + // sockaddr structure, without relying on unsafe casting to a type of a + // larger size. + copy( + (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:], + (*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:], + ) + + return &out +}