Files
kata-containers/vendor/github.com/mdlayher/vsock/conn_linux.go
Jose Carlos Venegas Munoz dad59fe092 vendor: Move virtcontainers to project's root directory
Lets have a global vendor base on virtcontainers.

Signed-off-by: Julio Montes <julio.montes@intel.com>
Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
2018-03-14 11:42:02 -06:00

98 lines
2.4 KiB
Go

//+build linux
package vsock
import (
"errors"
"net"
"os"
"time"
"golang.org/x/sys/unix"
)
var (
// errDeadlinesNotImplemented is returned by the SetDeadline family of methods
// for conn, because access is not yet available to the runtime network poller
// for non-standard sockets types.
// See: https://github.com/golang/go/issues/10565.
errDeadlinesNotImplemented = errors.New("vsock: deadlines not implemented")
)
var _ net.Conn = &conn{}
// A conn is the net.Conn implementation for VM sockets.
type conn struct {
*os.File
localAddr *Addr
remoteAddr *Addr
}
// LocalAddr and RemoteAddr implement the net.Conn interface for conn.
func (c *conn) LocalAddr() net.Addr { return c.localAddr }
func (c *conn) RemoteAddr() net.Addr { return c.remoteAddr }
// SetDeadline functions implement the net.Conn interface for conn.
func (c *conn) SetDeadline(_ time.Time) error { return errDeadlinesNotImplemented }
func (c *conn) SetReadDeadline(_ time.Time) error { return errDeadlinesNotImplemented }
func (c *conn) SetWriteDeadline(_ time.Time) error { return errDeadlinesNotImplemented }
// dialStream is the entry point for DialStream on Linux.
func dialStream(cid, port uint32) (net.Conn, error) {
fd, err := unix.Socket(unix.AF_VSOCK, unix.SOCK_STREAM, 0)
if err != nil {
return nil, err
}
cfd := &sysFD{fd: fd}
return dialStreamLinuxHandleError(cfd, cid, port)
}
// dialStreamLinuxHandleError ensures that any errors from dialStreamLinux result
// in the socket being cleaned up properly.
func dialStreamLinuxHandleError(cfd fd, cid, port uint32) (net.Conn, error) {
c, err := dialStreamLinux(cfd, cid, port)
if err != nil {
// If any system calls fail during setup, the socket must be closed
// to avoid file descriptor leaks.
_ = cfd.Close()
return nil, err
}
return c, nil
}
// dialStreamLinux is the entry point for tests on Linux.
func dialStreamLinux(cfd fd, cid, port uint32) (net.Conn, error) {
rsa := &unix.SockaddrVM{
CID: cid,
Port: port,
}
if err := cfd.Connect(rsa); err != nil {
return nil, err
}
lsa, err := cfd.Getsockname()
if err != nil {
return nil, err
}
lsavm := lsa.(*unix.SockaddrVM)
localAddr := &Addr{
ContextID: lsavm.CID,
Port: lsavm.Port,
}
remoteAddr := &Addr{
ContextID: cid,
Port: port,
}
return &conn{
File: cfd.NewFile(remoteAddr.fileName()),
localAddr: localAddr,
remoteAddr: remoteAddr,
}, nil
}