sandbox: support vsock connection to task api

Signed-off-by: Abel Feng <fshb1988@gmail.com>
This commit is contained in:
Abel Feng
2024-02-02 15:04:48 +08:00
parent 67ff3dbc8d
commit 522130a667
35 changed files with 3730 additions and 1 deletions

4
vendor/github.com/mdlayher/vsock/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,4 @@
cover.out
vsock.test
cmd/vscp/vscp
cmd/vsockhttp/vsockhttp

53
vendor/github.com/mdlayher/vsock/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,53 @@
# CHANGELOG
# v1.2.1
- [Improvement]: updated dependencies, test with Go 1.20.
# v1.2.0
**This is the first release of package vsock that only supports Go 1.18+. Users
on older versions of Go must use v1.1.1.**
- [Improvement]: drop support for older versions of Go so we can begin using
modern versions of `x/sys` and other dependencies.
## v1.1.1
**This is the last release of package vsock that supports Go 1.17 and below.**
- [Bug Fix] [commit](https://github.com/mdlayher/vsock/commit/ead86435c244d5d6baad549a6df0557ada3f4401):
fix build on non-UNIX platforms such as Windows. This is a no-op change on
Linux but provides a friendlier experience for non-Linux users.
## v1.1.0
- [New API] [commit](https://github.com/mdlayher/vsock/commit/44cd82dc5f7de644436f22236b111ab97fa9a14f):
`vsock.FileListener` can be used to create a `vsock.Listener` from an existing
`os.File`, which may be provided by systemd socket activation or another
external mechanism.
## v1.0.1
- [Bug Fix] [commit](https://github.com/mdlayher/vsock/commit/99a6dccdebad21d1fa5f757d228d677ccb1412dc):
upgrade `github.com/mdlayher/socket` to handle non-blocking `connect(2)`
errors (called in `vsock.Dial`) properly by checking the `SO_ERROR` socket
option. Lock in this behavior with a new test.
- [Improvement] [commit](https://github.com/mdlayher/vsock/commit/375f3bbcc363500daf367ec511638a4655471719):
downgrade the version of `golang.org/x/net` in use to support Go 1.12. We
don't need the latest version for this package.
## v1.0.0
**This is the first release of package vsock that only supports Go 1.12+.
Users on older versions of Go must use an unstable release.**
- Initial stable commit!
- [API change]: the `vsock.Dial` and `vsock.Listen` constructors now accept an
optional `*vsock.Config` parameter to enable future expansion in v1.x.x
without prompting further breaking API changes. Because `vsock.Config` has no
options as of this release, `nil` may be passed in all call sites to fix
existing code upon upgrading to v1.0.0.
- [New API]: the `vsock.ListenContextID` function can be used to create a
`*vsock.Listener` which is bound to an explicit context ID address, rather
than inferring one automatically as `vsock.Listen` does.

9
vendor/github.com/mdlayher/vsock/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,9 @@
# MIT License
Copyright (C) 2017-2022 Matt Layher
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

21
vendor/github.com/mdlayher/vsock/README.md generated vendored Normal file
View File

@@ -0,0 +1,21 @@
# vsock [![Test Status](https://github.com/mdlayher/vsock/workflows/Linux%20Test/badge.svg)](https://github.com/mdlayher/vsock/actions) [![Go Reference](https://pkg.go.dev/badge/github.com/mdlayher/vsock.svg)](https://pkg.go.dev/github.com/mdlayher/vsock) [![Go Report Card](https://goreportcard.com/badge/github.com/mdlayher/vsock)](https://goreportcard.com/report/github.com/mdlayher/vsock)
Package `vsock` provides access to Linux VM sockets (`AF_VSOCK`) for
communication between a hypervisor and its virtual machines. MIT Licensed.
For more information about VM sockets, see my blog about
[Linux VM sockets in Go](https://mdlayher.com/blog/linux-vm-sockets-in-go/) or
the [QEMU wiki page on virtio-vsock](http://wiki.qemu-project.org/Features/VirtioVsock).
## Stability
See the [CHANGELOG](./CHANGELOG.md) file for a description of changes between
releases.
This package has a stable v1 API and any future breaking changes will prompt
the release of a new major version. Features and bug fixes will continue to
occur in the v1.x.x series.
This package only supports the two most recent major versions of Go, mirroring
Go's own release policy. Older versions of Go may lack critical features and bug
fixes which are necessary for this package to function correctly.

62
vendor/github.com/mdlayher/vsock/conn_linux.go generated vendored Normal file
View File

@@ -0,0 +1,62 @@
//go:build linux
// +build linux
package vsock
import (
"context"
"github.com/mdlayher/socket"
"golang.org/x/sys/unix"
)
// A conn is the net.Conn implementation for connection-oriented VM sockets.
// We can use socket.Conn directly on Linux to implement all of the necessary
// methods.
type conn = socket.Conn
// dial is the entry point for Dial on Linux.
func dial(cid, port uint32, _ *Config) (*Conn, error) {
// TODO(mdlayher): Config default nil check and initialize. Pass options to
// socket.Config where necessary.
c, err := socket.Socket(unix.AF_VSOCK, unix.SOCK_STREAM, 0, "vsock", nil)
if err != nil {
return nil, err
}
sa := &unix.SockaddrVM{CID: cid, Port: port}
rsa, err := c.Connect(context.Background(), sa)
if err != nil {
_ = c.Close()
return nil, err
}
// TODO(mdlayher): getpeername(2) appears to return nil in the GitHub CI
// environment, so in the event of a nil sockaddr, fall back to the previous
// method of synthesizing the remote address.
if rsa == nil {
rsa = sa
}
lsa, err := c.Getsockname()
if err != nil {
_ = c.Close()
return nil, err
}
lsavm := lsa.(*unix.SockaddrVM)
rsavm := rsa.(*unix.SockaddrVM)
return &Conn{
c: c,
local: &Addr{
ContextID: lsavm.CID,
Port: lsavm.Port,
},
remote: &Addr{
ContextID: rsavm.CID,
Port: rsavm.Port,
},
}, nil
}

10
vendor/github.com/mdlayher/vsock/doc.go generated vendored Normal file
View File

@@ -0,0 +1,10 @@
// Package vsock provides access to Linux VM sockets (AF_VSOCK) for
// communication between a hypervisor and its virtual machines.
//
// The types in this package implement interfaces provided by package net and
// may be used in applications that expect a net.Listener or net.Conn.
//
// - *Addr implements net.Addr
// - *Conn implements net.Conn
// - *Listener implements net.Listener
package vsock

36
vendor/github.com/mdlayher/vsock/fd_linux.go generated vendored Normal file
View File

@@ -0,0 +1,36 @@
package vsock
import (
"fmt"
"os"
"golang.org/x/sys/unix"
)
// contextID retrieves the local context ID for this system.
func contextID() (uint32, error) {
f, err := os.Open(devVsock)
if err != nil {
return 0, err
}
defer f.Close()
return unix.IoctlGetUint32(int(f.Fd()), unix.IOCTL_VM_SOCKETS_GET_LOCAL_CID)
}
// isErrno determines if an error a matches UNIX error number.
func isErrno(err error, errno int) bool {
switch errno {
case ebadf:
return err == unix.EBADF
case enotconn:
return err == unix.ENOTCONN
default:
panicf("vsock: isErrno called with unhandled error number parameter: %d", errno)
return false
}
}
func panicf(format string, a ...interface{}) {
panic(fmt.Sprintf(format, a...))
}

133
vendor/github.com/mdlayher/vsock/listener_linux.go generated vendored Normal file
View File

@@ -0,0 +1,133 @@
//go:build linux
// +build linux
package vsock
import (
"context"
"net"
"os"
"time"
"github.com/mdlayher/socket"
"golang.org/x/sys/unix"
)
var _ net.Listener = &listener{}
// A listener is the net.Listener implementation for connection-oriented
// VM sockets.
type listener struct {
c *socket.Conn
addr *Addr
}
// Addr and Close implement the net.Listener interface for listener.
func (l *listener) Addr() net.Addr { return l.addr }
func (l *listener) Close() error { return l.c.Close() }
func (l *listener) SetDeadline(t time.Time) error { return l.c.SetDeadline(t) }
// Accept accepts a single connection from the listener, and sets up
// a net.Conn backed by conn.
func (l *listener) Accept() (net.Conn, error) {
c, rsa, err := l.c.Accept(context.Background(), 0)
if err != nil {
return nil, err
}
savm := rsa.(*unix.SockaddrVM)
remote := &Addr{
ContextID: savm.CID,
Port: savm.Port,
}
return &Conn{
c: c,
local: l.addr,
remote: remote,
}, nil
}
// name is the socket name passed to package socket.
const name = "vsock"
// listen is the entry point for Listen on Linux.
func listen(cid, port uint32, _ *Config) (*Listener, error) {
// TODO(mdlayher): Config default nil check and initialize. Pass options to
// socket.Config where necessary.
c, err := socket.Socket(unix.AF_VSOCK, unix.SOCK_STREAM, 0, name, nil)
if err != nil {
return nil, err
}
// Be sure to close the Conn if any of the system calls fail before we
// return the Conn to the caller.
if port == 0 {
port = unix.VMADDR_PORT_ANY
}
if err := c.Bind(&unix.SockaddrVM{CID: cid, Port: port}); err != nil {
_ = c.Close()
return nil, err
}
if err := c.Listen(unix.SOMAXCONN); err != nil {
_ = c.Close()
return nil, err
}
l, err := newListener(c)
if err != nil {
_ = c.Close()
return nil, err
}
return l, nil
}
// fileListener is the entry point for FileListener on Linux.
func fileListener(f *os.File) (*Listener, error) {
c, err := socket.FileConn(f, name)
if err != nil {
return nil, err
}
l, err := newListener(c)
if err != nil {
_ = c.Close()
return nil, err
}
return l, nil
}
// newListener creates a Listener from a raw socket.Conn.
func newListener(c *socket.Conn) (*Listener, error) {
lsa, err := c.Getsockname()
if err != nil {
return nil, err
}
// Now that the library can also accept arbitrary os.Files, we have to
// verify the address family so we don't accidentally create a
// *vsock.Listener backed by TCP or some other socket type.
lsavm, ok := lsa.(*unix.SockaddrVM)
if !ok {
// All errors should wrapped with os.SyscallError.
return nil, os.NewSyscallError("listen", unix.EINVAL)
}
addr := &Addr{
ContextID: lsavm.CID,
Port: lsavm.Port,
}
return &Listener{
l: &listener{
c: c,
addr: addr,
},
}, nil
}

435
vendor/github.com/mdlayher/vsock/vsock.go generated vendored Normal file
View File

@@ -0,0 +1,435 @@
package vsock
import (
"errors"
"fmt"
"io"
"net"
"os"
"strings"
"syscall"
"time"
)
const (
// Hypervisor specifies that a socket should communicate with the hypervisor
// process. Note that this is _not_ the same as a socket owned by a process
// running on the hypervisor. Most users should probably use Host instead.
Hypervisor = 0x0
// Local specifies that a socket should communicate with a matching socket
// on the same machine. This provides an alternative to UNIX sockets or
// similar and may be useful in testing VM sockets applications.
Local = 0x1
// Host specifies that a socket should communicate with processes other than
// the hypervisor on the host machine. This is the correct choice to
// communicate with a process running on a hypervisor using a socket dialed
// from a guest.
Host = 0x2
// Error numbers we recognize, copied here to avoid importing x/sys/unix in
// cross-platform code.
ebadf = 9
enotconn = 107
// devVsock is the location of /dev/vsock. It is exposed on both the
// hypervisor and on virtual machines.
devVsock = "/dev/vsock"
// network is the vsock network reported in net.OpError.
network = "vsock"
// Operation names which may be returned in net.OpError.
opAccept = "accept"
opClose = "close"
opDial = "dial"
opListen = "listen"
opRawControl = "raw-control"
opRawRead = "raw-read"
opRawWrite = "raw-write"
opRead = "read"
opSet = "set"
opSyscallConn = "syscall-conn"
opWrite = "write"
)
// TODO(mdlayher): plumb through socket.Config.NetNS if it makes sense.
// Config contains options for a Conn or Listener.
type Config struct{}
// Listen opens a connection-oriented net.Listener for incoming VM sockets
// connections. The port parameter specifies the port for the Listener. Config
// specifies optional configuration for the Listener. If config is nil, a
// default configuration will be used.
//
// To allow the server to assign a port automatically, specify 0 for port. The
// address of the server can be retrieved using the Addr method.
//
// Listen automatically infers the appropriate context ID for this machine by
// calling ContextID and passing that value to ListenContextID. Callers with
// advanced use cases (such as using the Local context ID) may wish to use
// ListenContextID directly.
//
// When the Listener is no longer needed, Close must be called to free
// resources.
func Listen(port uint32, cfg *Config) (*Listener, error) {
cid, err := ContextID()
if err != nil {
// No addresses available.
return nil, opError(opListen, err, nil, nil)
}
return ListenContextID(cid, port, cfg)
}
// ListenContextID is the same as Listen, but also accepts an explicit context
// ID parameter. This function is intended for advanced use cases and most
// callers should use Listen instead.
//
// See the documentation of Listen for more details.
func ListenContextID(contextID, port uint32, cfg *Config) (*Listener, error) {
l, err := listen(contextID, port, cfg)
if err != nil {
// No remote address available.
return nil, opError(opListen, err, &Addr{
ContextID: contextID,
Port: port,
}, nil)
}
return l, nil
}
// FileListener returns a copy of the network listener corresponding to an open
// os.File. It is the caller's responsibility to close the Listener when
// finished. Closing the Listener does not affect the os.File, and closing the
// os.File does not affect the Listener.
//
// This function is intended for advanced use cases and most callers should use
// Listen instead.
func FileListener(f *os.File) (*Listener, error) {
l, err := fileListener(f)
if err != nil {
// No addresses available.
return nil, opError(opListen, err, nil, nil)
}
return l, nil
}
var _ net.Listener = &Listener{}
// A Listener is a VM sockets implementation of a net.Listener.
type Listener struct {
l *listener
}
// Accept implements the Accept method in the net.Listener interface; it waits
// for the next call and returns a generic net.Conn. The returned net.Conn will
// always be of type *Conn.
func (l *Listener) Accept() (net.Conn, error) {
c, err := l.l.Accept()
if err != nil {
return nil, l.opError(opAccept, err)
}
return c, nil
}
// Addr returns the listener's network address, a *Addr. The Addr returned is
// shared by all invocations of Addr, so do not modify it.
func (l *Listener) Addr() net.Addr { return l.l.Addr() }
// Close stops listening on the VM sockets address. Already Accepted connections
// are not closed.
func (l *Listener) Close() error {
return l.opError(opClose, l.l.Close())
}
// SetDeadline sets the deadline associated with the listener. A zero time value
// disables the deadline.
func (l *Listener) SetDeadline(t time.Time) error {
return l.opError(opSet, l.l.SetDeadline(t))
}
// opError is a convenience for the function opError that also passes the local
// address of the Listener.
func (l *Listener) opError(op string, err error) error {
// No remote address for a Listener.
return opError(op, err, l.Addr(), nil)
}
// Dial dials a connection-oriented net.Conn to a VM sockets listener. The
// context ID and port parameters specify the address of the listener. Config
// specifies optional configuration for the Conn. If config is nil, a default
// configuration will be used.
//
// If dialing a connection from the hypervisor to a virtual machine, the VM's
// context ID should be specified.
//
// If dialing from a VM to the hypervisor, Hypervisor should be used to
// communicate with the hypervisor process, or Host should be used to
// communicate with other processes on the host machine.
//
// When the connection is no longer needed, Close must be called to free
// resources.
func Dial(contextID, port uint32, cfg *Config) (*Conn, error) {
c, err := dial(contextID, port, cfg)
if err != nil {
// No local address, but we have a remote address we can return.
return nil, opError(opDial, err, nil, &Addr{
ContextID: contextID,
Port: port,
})
}
return c, nil
}
var (
_ net.Conn = &Conn{}
_ syscall.Conn = &Conn{}
)
// A Conn is a VM sockets implementation of a net.Conn.
type Conn struct {
c *conn
local *Addr
remote *Addr
}
// Close closes the connection.
func (c *Conn) Close() error {
return c.opError(opClose, c.c.Close())
}
// CloseRead shuts down the reading side of the VM sockets connection. Most
// callers should just use Close.
func (c *Conn) CloseRead() error {
return c.opError(opClose, c.c.CloseRead())
}
// CloseWrite shuts down the writing side of the VM sockets connection. Most
// callers should just use Close.
func (c *Conn) CloseWrite() error {
return c.opError(opClose, c.c.CloseWrite())
}
// LocalAddr returns the local network address. The Addr returned is shared by
// all invocations of LocalAddr, so do not modify it.
func (c *Conn) LocalAddr() net.Addr { return c.local }
// RemoteAddr returns the remote network address. The Addr returned is shared by
// all invocations of RemoteAddr, so do not modify it.
func (c *Conn) RemoteAddr() net.Addr { return c.remote }
// Read implements the net.Conn Read method.
func (c *Conn) Read(b []byte) (int, error) {
n, err := c.c.Read(b)
if err != nil {
return n, c.opError(opRead, err)
}
return n, nil
}
// Write implements the net.Conn Write method.
func (c *Conn) Write(b []byte) (int, error) {
n, err := c.c.Write(b)
if err != nil {
return n, c.opError(opWrite, err)
}
return n, nil
}
// SetDeadline implements the net.Conn SetDeadline method.
func (c *Conn) SetDeadline(t time.Time) error {
return c.opError(opSet, c.c.SetDeadline(t))
}
// SetReadDeadline implements the net.Conn SetReadDeadline method.
func (c *Conn) SetReadDeadline(t time.Time) error {
return c.opError(opSet, c.c.SetReadDeadline(t))
}
// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
func (c *Conn) SetWriteDeadline(t time.Time) error {
return c.opError(opSet, c.c.SetWriteDeadline(t))
}
// SyscallConn returns a raw network connection. This implements the
// syscall.Conn interface.
func (c *Conn) SyscallConn() (syscall.RawConn, error) {
rc, err := c.c.SyscallConn()
if err != nil {
return nil, c.opError(opSyscallConn, err)
}
return &rawConn{
rc: rc,
local: c.local,
remote: c.remote,
}, nil
}
// opError is a convenience for the function opError that also passes the local
// and remote addresses of the Conn.
func (c *Conn) opError(op string, err error) error {
return opError(op, err, c.local, c.remote)
}
// TODO(mdlayher): see if we can port smarter net.OpError with local/remote
// address error logic into socket.Conn's SyscallConn type to avoid the need for
// this wrapper.
var _ syscall.RawConn = &rawConn{}
// A rawConn is a syscall.RawConn that wraps an internal syscall.RawConn in order
// to produce net.OpError error values.
type rawConn struct {
rc syscall.RawConn
local, remote *Addr
}
// Control implements the syscall.RawConn Control method.
func (rc *rawConn) Control(fn func(fd uintptr)) error {
return rc.opError(opRawControl, rc.rc.Control(fn))
}
// Control implements the syscall.RawConn Read method.
func (rc *rawConn) Read(fn func(fd uintptr) (done bool)) error {
return rc.opError(opRawRead, rc.rc.Read(fn))
}
// Control implements the syscall.RawConn Write method.
func (rc *rawConn) Write(fn func(fd uintptr) (done bool)) error {
return rc.opError(opRawWrite, rc.rc.Write(fn))
}
// opError is a convenience for the function opError that also passes the local
// and remote addresses of the rawConn.
func (rc *rawConn) opError(op string, err error) error {
return opError(op, err, rc.local, rc.remote)
}
var _ net.Addr = &Addr{}
// An Addr is the address of a VM sockets endpoint.
type Addr struct {
ContextID, Port uint32
}
// Network returns the address's network name, "vsock".
func (a *Addr) Network() string { return network }
// String returns a human-readable representation of Addr, and indicates if
// ContextID is meant to be used for a hypervisor, host, VM, etc.
func (a *Addr) String() string {
var host string
switch a.ContextID {
case Hypervisor:
host = fmt.Sprintf("hypervisor(%d)", a.ContextID)
case Local:
host = fmt.Sprintf("local(%d)", a.ContextID)
case Host:
host = fmt.Sprintf("host(%d)", a.ContextID)
default:
host = fmt.Sprintf("vm(%d)", a.ContextID)
}
return fmt.Sprintf("%s:%d", host, a.Port)
}
// fileName returns a file name for use with os.NewFile for Addr.
func (a *Addr) fileName() string {
return fmt.Sprintf("%s:%s", a.Network(), a.String())
}
// ContextID retrieves the local VM sockets context ID for this system.
// ContextID can be used to directly determine if a system is capable of using
// VM sockets.
//
// If the kernel module is unavailable, access to the kernel module is denied,
// or VM sockets are unsupported on this system, it returns an error.
func ContextID() (uint32, error) {
return contextID()
}
// opError unpacks err if possible, producing a net.OpError with the input
// parameters in order to implement net.Conn. As a convenience, opError returns
// nil if the input error is nil.
func opError(op string, err error, local, remote net.Addr) error {
if err == nil {
return nil
}
// TODO(mdlayher): this entire function is suspect and should probably be
// looked at carefully, especially with Go 1.13+ error wrapping.
//
// Eventually this *net.OpError logic should probably be ported into
// mdlayher/socket because similar checks are necessary to comply with
// nettest.TestConn.
// Unwrap inner errors from error types.
//
// TODO(mdlayher): errors.Cause or similar in Go 1.13.
switch xerr := err.(type) {
// os.PathError produced by os.File method calls.
case *os.PathError:
// Although we could make use of xerr.Op here, we're passing it manually
// for consistency, since some of the Conn calls we are making don't
// wrap an os.File, which would return an Op for us.
//
// As a special case, if the error is related to access to the /dev/vsock
// device, we don't unwrap it, so the caller has more context as to why
// their operation actually failed than "permission denied" or similar.
if xerr.Path != devVsock {
err = xerr.Err
}
}
switch {
case err == io.EOF, isErrno(err, enotconn):
// We may see a literal io.EOF as happens with x/net/nettest, but
// "transport not connected" also means io.EOF in Go.
return io.EOF
case err == os.ErrClosed, isErrno(err, ebadf), strings.Contains(err.Error(), "use of closed"):
// Different operations may return different errors that all effectively
// indicate a closed file.
//
// To rectify the differences, net.TCPConn uses an error with this text
// from internal/poll for the backing file already being closed.
err = errors.New("use of closed network connection")
default:
// Nothing to do, return this directly.
}
// Determine source and addr using the rules defined by net.OpError's
// documentation: https://golang.org/pkg/net/#OpError.
var source, addr net.Addr
switch op {
case opClose, opDial, opRawRead, opRawWrite, opRead, opWrite:
if local != nil {
source = local
}
if remote != nil {
addr = remote
}
case opAccept, opListen, opRawControl, opSet, opSyscallConn:
if local != nil {
addr = local
}
}
return &net.OpError{
Op: op,
Net: network,
Source: source,
Addr: addr,
Err: err,
}
}

45
vendor/github.com/mdlayher/vsock/vsock_others.go generated vendored Normal file
View File

@@ -0,0 +1,45 @@
//go:build !linux
// +build !linux
package vsock
import (
"fmt"
"net"
"os"
"runtime"
"syscall"
"time"
)
// errUnimplemented is returned by all functions on platforms that
// cannot make use of VM sockets.
var errUnimplemented = fmt.Errorf("vsock: not implemented on %s", runtime.GOOS)
func fileListener(_ *os.File) (*Listener, error) { return nil, errUnimplemented }
func listen(_, _ uint32, _ *Config) (*Listener, error) { return nil, errUnimplemented }
type listener struct{}
func (*listener) Accept() (net.Conn, error) { return nil, errUnimplemented }
func (*listener) Addr() net.Addr { return nil }
func (*listener) Close() error { return errUnimplemented }
func (*listener) SetDeadline(_ time.Time) error { return errUnimplemented }
func dial(_, _ uint32, _ *Config) (*Conn, error) { return nil, errUnimplemented }
type conn struct{}
func (*conn) Close() error { return errUnimplemented }
func (*conn) CloseRead() error { return errUnimplemented }
func (*conn) CloseWrite() error { return errUnimplemented }
func (*conn) Read(_ []byte) (int, error) { return 0, errUnimplemented }
func (*conn) Write(_ []byte) (int, error) { return 0, errUnimplemented }
func (*conn) SetDeadline(_ time.Time) error { return errUnimplemented }
func (*conn) SetReadDeadline(_ time.Time) error { return errUnimplemented }
func (*conn) SetWriteDeadline(_ time.Time) error { return errUnimplemented }
func (*conn) SyscallConn() (syscall.RawConn, error) { return nil, errUnimplemented }
func contextID() (uint32, error) { return 0, errUnimplemented }
func isErrno(_ error, _ int) bool { return false }