unix: add SockaddrVM type and AF_VSOCK to anyToSockaddrGOOS to darwin

Change-Id: I511be555d92ac87a797949fc4c99fd8ef9515ace
Reviewed-on: https://go-review.googlesource.com/c/sys/+/354269
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Koichi Shiraishi
2021-10-06 21:48:17 +09:00
committed by Ian Lance Taylor
parent c8a6f52230
commit 1a26e0398e
2 changed files with 109 additions and 0 deletions

View File

@@ -48,6 +48,30 @@ func (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {
return unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil
}
// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.
// SockaddrVM provides access to Darwin VM sockets: a mechanism that enables
// bidirectional communication between a hypervisor and its guest virtual
// machines.
type SockaddrVM struct {
// CID and Port specify a context ID and port address for a VM socket.
// Guests have a unique CID, and hosts may have a well-known CID of:
// - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
// - VMADDR_CID_LOCAL: refers to local communication (loopback).
// - VMADDR_CID_HOST: refers to other processes on the host.
CID uint32
Port uint32
raw RawSockaddrVM
}
func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
sa.raw.Len = SizeofSockaddrVM
sa.raw.Family = AF_VSOCK
sa.raw.Port = sa.Port
sa.raw.Cid = sa.CID
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
}
func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_SYSTEM:
@@ -58,6 +82,13 @@ func anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
sa.Unit = pp.Sc_unit
return sa, nil
}
case AF_VSOCK:
pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
sa := &SockaddrVM{
CID: pp.Cid,
Port: pp.Port,
}
return sa, nil
}
return nil, EAFNOSUPPORT
}

View File

@@ -50,6 +50,23 @@ func Test_anyToSockaddr_darwin(t *testing.T) {
Unit: 0xC71,
},
},
{
name: "AF_VSOCK emtpy",
rsa: sockaddrVMToAny(RawSockaddrVM{}),
err: EAFNOSUPPORT,
},
{
name: "AF_VSOCK Cid and Port",
rsa: sockaddrVMToAny(RawSockaddrVM{
Family: AF_VSOCK,
Cid: VMADDR_CID_HOST,
Port: VMADDR_PORT_ANY,
}),
sa: &SockaddrVM{
CID: VMADDR_CID_HOST,
Port: VMADDR_PORT_ANY,
},
},
}
for _, tt := range tests {
@@ -121,6 +138,58 @@ func TestSockaddrCtl_sockaddr(t *testing.T) {
}
}
func TestSockaddVM_sockaddr(t *testing.T) {
tests := []struct {
name string
sa *SockaddrVM
raw *RawSockaddrVM
err error
}{
{
name: "empty",
sa: &SockaddrVM{},
raw: &RawSockaddrVM{
Len: SizeofSockaddrVM,
Family: AF_VSOCK,
},
},
{
name: "with CID and Port",
sa: &SockaddrVM{
CID: VMADDR_CID_HOST,
Port: VMADDR_PORT_ANY,
},
raw: &RawSockaddrVM{
Len: SizeofSockaddrVM,
Family: AF_VSOCK,
Port: VMADDR_PORT_ANY,
Cid: VMADDR_CID_HOST,
},
},
}
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)
}
// Must be 0 on error or a fixed size otherwise.
if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrVM) {
t.Fatalf("unexpected Socklen: %d", l)
}
if out != nil {
raw := (*RawSockaddrVM)(out)
if !reflect.DeepEqual(raw, tt.raw) {
t.Fatalf("unexpected RawSockaddrVM:\n got: %#v\nwant: %#v", raw, tt.raw)
}
}
})
}
}
func sockaddrCtlToAny(in RawSockaddrCtl) *RawSockaddrAny {
var out RawSockaddrAny
copy(
@@ -129,3 +198,12 @@ func sockaddrCtlToAny(in RawSockaddrCtl) *RawSockaddrAny {
)
return &out
}
func sockaddrVMToAny(in RawSockaddrVM) *RawSockaddrAny {
var out RawSockaddrAny
copy(
(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
(*(*[SizeofSockaddrVM]byte)(unsafe.Pointer(&in)))[:],
)
return &out
}