10
vendor/github.com/mdlayher/genetlink/go.mod
generated
vendored
10
vendor/github.com/mdlayher/genetlink/go.mod
generated
vendored
@@ -1,10 +0,0 @@
|
||||
module github.com/mdlayher/genetlink
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.3.1
|
||||
github.com/mdlayher/netlink v1.0.0
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be
|
||||
)
|
||||
22
vendor/github.com/mdlayher/genetlink/go.sum
generated
vendored
22
vendor/github.com/mdlayher/genetlink/go.sum
generated
vendored
@@ -1,22 +0,0 @@
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a h1:84IpUNXj4mCR9CuCEvSiCArMbzr/TMbuPIadKDwypkI=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0 h1:vySPY5Oxnn/8lxAPn2cK6kAzcZzYJl3KriSLO46OT18=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954 h1:JGZucVF/L/TotR719NbujzadOZ2AgnYlqphQGHDCKaU=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
5
vendor/github.com/mdlayher/netlink/CHANGELOG.md
generated
vendored
5
vendor/github.com/mdlayher/netlink/CHANGELOG.md
generated
vendored
@@ -1,5 +1,10 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.4.1
|
||||
|
||||
- [Improvement]: significant runtime network poller integration cleanup through
|
||||
the use of `github.com/mdlayher/socket`.
|
||||
|
||||
## v1.4.0
|
||||
|
||||
- [New API] [#185](https://github.com/mdlayher/netlink/pull/185): the
|
||||
|
||||
359
vendor/github.com/mdlayher/netlink/conn_linux.go
generated
vendored
359
vendor/github.com/mdlayher/netlink/conn_linux.go
generated
vendored
@@ -3,14 +3,13 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/mdlayher/socket"
|
||||
"golang.org/x/net/bpf"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
@@ -18,21 +17,13 @@ import (
|
||||
var _ Socket = &conn{}
|
||||
|
||||
// A conn is the Linux implementation of a netlink sockets connection.
|
||||
//
|
||||
// All conn methods must wrap system call errors with os.NewSyscallError to
|
||||
// enable more intelligible error messages in OpError.
|
||||
type conn struct {
|
||||
s *socket
|
||||
s *socket.Conn
|
||||
}
|
||||
|
||||
// dial is the entry point for Dial. dial opens a netlink socket using
|
||||
// system calls, and returns its PID.
|
||||
func dial(family int, config *Config) (*conn, uint32, error) {
|
||||
// Prepare sysSocket's internal loop and create the socket.
|
||||
//
|
||||
// The conditional is inverted because a zero value of false is desired
|
||||
// if no config, but it's easier to interpret within this code when the
|
||||
// value is inverted.
|
||||
if config == nil {
|
||||
config = &Config{}
|
||||
}
|
||||
@@ -65,17 +56,17 @@ func dial(family int, config *Config) (*conn, uint32, error) {
|
||||
defer threadNS.Restore()
|
||||
}
|
||||
|
||||
// Socket will establish the internal state of the socket structure.
|
||||
s, err := newSocket(family)
|
||||
// Prepare the netlink socket.
|
||||
s, err := socket.Socket(unix.AF_NETLINK, unix.SOCK_RAW, family, "netlink")
|
||||
if err != nil {
|
||||
return nil, 0, os.NewSyscallError("socket", err)
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return newConn(s, config)
|
||||
}
|
||||
|
||||
// newConn binds a connection to netlink using the input socket.
|
||||
func newConn(s *socket, config *Config) (*conn, uint32, error) {
|
||||
// newConn binds a connection to netlink using the input *socket.Conn.
|
||||
func newConn(s *socket.Conn, config *Config) (*conn, uint32, error) {
|
||||
if config == nil {
|
||||
config = &Config{}
|
||||
}
|
||||
@@ -90,13 +81,13 @@ func newConn(s *socket, config *Config) (*conn, uint32, error) {
|
||||
|
||||
if err := s.Bind(addr); err != nil {
|
||||
_ = s.Close()
|
||||
return nil, 0, os.NewSyscallError("bind", err)
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
sa, err := s.Getsockname()
|
||||
if err != nil {
|
||||
_ = s.Close()
|
||||
return nil, 0, os.NewSyscallError("getsockname", err)
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return &conn{
|
||||
@@ -117,7 +108,7 @@ func (c *conn) SendMessages(messages []Message) error {
|
||||
}
|
||||
|
||||
sa := &unix.SockaddrNetlink{Family: unix.AF_NETLINK}
|
||||
return os.NewSyscallError("sendmsg", c.s.Sendmsg(buf, nil, sa, 0))
|
||||
return c.s.Sendmsg(buf, nil, sa, 0)
|
||||
}
|
||||
|
||||
// Send sends a single Message to netlink.
|
||||
@@ -128,7 +119,7 @@ func (c *conn) Send(m Message) error {
|
||||
}
|
||||
|
||||
sa := &unix.SockaddrNetlink{Family: unix.AF_NETLINK}
|
||||
return os.NewSyscallError("sendmsg", c.s.Sendmsg(b, nil, sa, 0))
|
||||
return c.s.Sendmsg(b, nil, sa, 0)
|
||||
}
|
||||
|
||||
// Receive receives one or more Messages from netlink.
|
||||
@@ -141,7 +132,7 @@ func (c *conn) Receive() ([]Message, error) {
|
||||
// when PacketInfo ConnOption is true.
|
||||
n, _, _, _, err := c.s.Recvmsg(b, nil, unix.MSG_PEEK)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("recvmsg", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Break when we can read all messages
|
||||
@@ -156,7 +147,7 @@ func (c *conn) Receive() ([]Message, error) {
|
||||
// Read out all available messages
|
||||
n, _, _, _, err := c.s.Recvmsg(b, nil, 0)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("recvmsg", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
raw, err := syscall.ParseNetlinkMessage(b[:nlmsgAlign(n)])
|
||||
@@ -178,57 +169,23 @@ func (c *conn) Receive() ([]Message, error) {
|
||||
}
|
||||
|
||||
// Close closes the connection.
|
||||
func (c *conn) Close() error {
|
||||
return os.NewSyscallError("close", c.s.Close())
|
||||
}
|
||||
func (c *conn) Close() error { return c.s.Close() }
|
||||
|
||||
// JoinGroup joins a multicast group by ID.
|
||||
func (c *conn) JoinGroup(group uint32) error {
|
||||
return os.NewSyscallError("setsockopt", c.s.SetSockoptInt(
|
||||
unix.SOL_NETLINK,
|
||||
unix.NETLINK_ADD_MEMBERSHIP,
|
||||
int(group),
|
||||
))
|
||||
return c.s.SetsockoptInt(unix.SOL_NETLINK, unix.NETLINK_ADD_MEMBERSHIP, int(group))
|
||||
}
|
||||
|
||||
// LeaveGroup leaves a multicast group by ID.
|
||||
func (c *conn) LeaveGroup(group uint32) error {
|
||||
return os.NewSyscallError("setsockopt", c.s.SetSockoptInt(
|
||||
unix.SOL_NETLINK,
|
||||
unix.NETLINK_DROP_MEMBERSHIP,
|
||||
int(group),
|
||||
))
|
||||
return c.s.SetsockoptInt(unix.SOL_NETLINK, unix.NETLINK_DROP_MEMBERSHIP, int(group))
|
||||
}
|
||||
|
||||
// SetBPF attaches an assembled BPF program to a conn.
|
||||
func (c *conn) SetBPF(filter []bpf.RawInstruction) error {
|
||||
// We can't point to the first instruction in the array if no instructions
|
||||
// are present.
|
||||
if len(filter) == 0 {
|
||||
return os.NewSyscallError("setsockopt", unix.EINVAL)
|
||||
}
|
||||
|
||||
prog := unix.SockFprog{
|
||||
Len: uint16(len(filter)),
|
||||
Filter: (*unix.SockFilter)(unsafe.Pointer(&filter[0])),
|
||||
}
|
||||
|
||||
return os.NewSyscallError("setsockopt", c.s.SetSockoptSockFprog(
|
||||
unix.SOL_SOCKET,
|
||||
unix.SO_ATTACH_FILTER,
|
||||
&prog,
|
||||
))
|
||||
}
|
||||
func (c *conn) SetBPF(filter []bpf.RawInstruction) error { return c.s.SetBPF(filter) }
|
||||
|
||||
// RemoveBPF removes a BPF filter from a conn.
|
||||
func (c *conn) RemoveBPF() error {
|
||||
// 0 argument is ignored by SO_DETACH_FILTER.
|
||||
return os.NewSyscallError("setsockopt", c.s.SetSockoptInt(
|
||||
unix.SOL_SOCKET,
|
||||
unix.SO_DETACH_FILTER,
|
||||
0,
|
||||
))
|
||||
}
|
||||
func (c *conn) RemoveBPF() error { return c.s.RemoveBPF() }
|
||||
|
||||
// SetOption enables or disables a netlink socket option for the Conn.
|
||||
func (c *conn) SetOption(option ConnOption, enable bool) error {
|
||||
@@ -243,11 +200,7 @@ func (c *conn) SetOption(option ConnOption, enable bool) error {
|
||||
v = 1
|
||||
}
|
||||
|
||||
return os.NewSyscallError("setsockopt", c.s.SetSockoptInt(
|
||||
unix.SOL_NETLINK,
|
||||
o,
|
||||
v,
|
||||
))
|
||||
return c.s.SetsockoptInt(unix.SOL_NETLINK, o, v)
|
||||
}
|
||||
|
||||
func (c *conn) SetDeadline(t time.Time) error { return c.s.SetDeadline(t) }
|
||||
@@ -256,44 +209,13 @@ func (c *conn) SetWriteDeadline(t time.Time) error { return c.s.SetWriteDeadline
|
||||
|
||||
// SetReadBuffer sets the size of the operating system's receive buffer
|
||||
// associated with the Conn.
|
||||
func (c *conn) SetReadBuffer(bytes int) error {
|
||||
// First try SO_RCVBUFFORCE. Given necessary permissions this syscall
|
||||
// ignores limits. Fall back to the non-force version.
|
||||
err := os.NewSyscallError("setsockopt", c.s.SetSockoptInt(
|
||||
unix.SOL_SOCKET,
|
||||
unix.SO_RCVBUFFORCE,
|
||||
bytes,
|
||||
))
|
||||
if err != nil {
|
||||
err = os.NewSyscallError("setsockopt", c.s.SetSockoptInt(
|
||||
unix.SOL_SOCKET,
|
||||
unix.SO_RCVBUF,
|
||||
bytes,
|
||||
))
|
||||
}
|
||||
return err
|
||||
}
|
||||
func (c *conn) SetReadBuffer(bytes int) error { return c.s.SetReadBuffer(bytes) }
|
||||
|
||||
// SetReadBuffer sets the size of the operating system's transmit buffer
|
||||
// associated with the Conn.
|
||||
func (c *conn) SetWriteBuffer(bytes int) error {
|
||||
// First try SO_SNDBUFFORCE. Given necessary permissions this syscall
|
||||
// ignores limits. Fall back to the non-force version.
|
||||
err := os.NewSyscallError("setsockopt", c.s.SetSockoptInt(
|
||||
unix.SOL_SOCKET,
|
||||
unix.SO_SNDBUFFORCE,
|
||||
bytes,
|
||||
))
|
||||
if err != nil {
|
||||
err = os.NewSyscallError("setsockopt", c.s.SetSockoptInt(
|
||||
unix.SOL_SOCKET,
|
||||
unix.SO_SNDBUF,
|
||||
bytes,
|
||||
))
|
||||
}
|
||||
return err
|
||||
}
|
||||
func (c *conn) SetWriteBuffer(bytes int) error { return c.s.SetWriteBuffer(bytes) }
|
||||
|
||||
// SyscallConn returns a raw network connection.
|
||||
func (c *conn) SyscallConn() (syscall.RawConn, error) { return c.s.SyscallConn() }
|
||||
|
||||
// linuxOption converts a ConnOption to its Linux value.
|
||||
@@ -330,240 +252,3 @@ func sysToHeader(r syscall.NlMsghdr) Header {
|
||||
func newError(errno int) error {
|
||||
return syscall.Errno(errno)
|
||||
}
|
||||
|
||||
// A socket wraps system call operations.
|
||||
type socket struct {
|
||||
// Atomics must come first.
|
||||
closed uint32
|
||||
|
||||
fd *os.File
|
||||
rc syscall.RawConn
|
||||
}
|
||||
|
||||
// read executes f, a read function, against the associated file descriptor.
|
||||
func (s *socket) read(f func(fd int) bool) error {
|
||||
if atomic.LoadUint32(&s.closed) != 0 {
|
||||
return syscall.EBADF
|
||||
}
|
||||
|
||||
return s.rc.Read(func(sysfd uintptr) bool {
|
||||
return f(int(sysfd))
|
||||
})
|
||||
}
|
||||
|
||||
// write executes f, a write function, against the associated file descriptor.
|
||||
func (s *socket) write(f func(fd int) bool) error {
|
||||
if atomic.LoadUint32(&s.closed) != 0 {
|
||||
return syscall.EBADF
|
||||
}
|
||||
|
||||
return s.rc.Write(func(sysfd uintptr) bool {
|
||||
return f(int(sysfd))
|
||||
})
|
||||
}
|
||||
|
||||
// control executes f, a control function, against the associated file descriptor.
|
||||
func (s *socket) control(f func(fd int)) error {
|
||||
if atomic.LoadUint32(&s.closed) != 0 {
|
||||
return syscall.EBADF
|
||||
}
|
||||
|
||||
return s.rc.Control(func(sysfd uintptr) {
|
||||
f(int(sysfd))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *socket) SyscallConn() (syscall.RawConn, error) {
|
||||
if atomic.LoadUint32(&s.closed) != 0 {
|
||||
return nil, syscall.EBADF
|
||||
}
|
||||
|
||||
return s.rc, nil
|
||||
}
|
||||
|
||||
func newSocket(family int) (*socket, error) {
|
||||
// Mirror what the standard library does when creating file
|
||||
// descriptors: avoid racing a fork/exec with the creation
|
||||
// of new file descriptors, so that child processes do not
|
||||
// inherit netlink socket file descriptors unexpectedly.
|
||||
//
|
||||
// On Linux, SOCK_CLOEXEC was introduced in 2.6.27. OTOH,
|
||||
// Go supports Linux 2.6.23 and above. If we get EINVAL on
|
||||
// the first try, it may be that we are running on a kernel
|
||||
// older than 2.6.27. In that case, take syscall.ForkLock
|
||||
// and try again without SOCK_CLOEXEC.
|
||||
//
|
||||
// For a more thorough explanation, see similar work in the
|
||||
// Go tree: func sysSocket in net/sock_cloexec.go, as well
|
||||
// as the detailed comment in syscall/exec_unix.go.
|
||||
fd, err := unix.Socket(
|
||||
unix.AF_NETLINK,
|
||||
unix.SOCK_RAW|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC,
|
||||
family,
|
||||
)
|
||||
if err == unix.EINVAL {
|
||||
syscall.ForkLock.RLock()
|
||||
fd, err = unix.Socket(
|
||||
unix.AF_NETLINK,
|
||||
unix.SOCK_RAW,
|
||||
family,
|
||||
)
|
||||
if err == nil {
|
||||
unix.CloseOnExec(fd)
|
||||
}
|
||||
syscall.ForkLock.RUnlock()
|
||||
|
||||
if err := unix.SetNonblock(fd, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// os.NewFile registers the file descriptor with the runtime poller, which
|
||||
// is then used for most subsequent operations except those that require
|
||||
// raw I/O via SyscallConn.
|
||||
//
|
||||
// See also: https://golang.org/pkg/os/#NewFile
|
||||
f := os.NewFile(uintptr(fd), "netlink")
|
||||
rc, err := f.SyscallConn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &socket{
|
||||
fd: f,
|
||||
rc: rc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *socket) Bind(sa unix.Sockaddr) error {
|
||||
var err error
|
||||
doErr := s.control(func(fd int) {
|
||||
err = unix.Bind(fd, sa)
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *socket) Close() error {
|
||||
// The caller has expressed an intent to close the socket, so immediately
|
||||
// increment s.closed to force further calls to result in EBADF before also
|
||||
// closing the file descriptor to unblock any outstanding operations.
|
||||
//
|
||||
// Because other operations simply check for s.closed != 0, we will permit
|
||||
// double Close, which would increment s.closed beyond 1.
|
||||
if atomic.AddUint32(&s.closed, 1) != 1 {
|
||||
// Multiple Close calls.
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.fd.Close()
|
||||
}
|
||||
|
||||
func (s *socket) Getsockname() (unix.Sockaddr, error) {
|
||||
var (
|
||||
sa unix.Sockaddr
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := s.control(func(fd int) {
|
||||
sa, err = unix.Getsockname(fd)
|
||||
})
|
||||
if doErr != nil {
|
||||
return nil, doErr
|
||||
}
|
||||
|
||||
return sa, err
|
||||
}
|
||||
|
||||
func (s *socket) Recvmsg(p, oob []byte, flags int) (int, int, int, unix.Sockaddr, error) {
|
||||
var (
|
||||
n, oobn, recvflags int
|
||||
from unix.Sockaddr
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := s.read(func(fd int) bool {
|
||||
n, oobn, recvflags, from, err = unix.Recvmsg(fd, p, oob, flags)
|
||||
|
||||
// Check for readiness.
|
||||
return ready(err)
|
||||
})
|
||||
if doErr != nil {
|
||||
return 0, 0, 0, nil, doErr
|
||||
}
|
||||
|
||||
return n, oobn, recvflags, from, err
|
||||
}
|
||||
|
||||
func (s *socket) Sendmsg(p, oob []byte, to unix.Sockaddr, flags int) error {
|
||||
var err error
|
||||
doErr := s.write(func(fd int) bool {
|
||||
err = unix.Sendmsg(fd, p, oob, to, flags)
|
||||
|
||||
// Check for readiness.
|
||||
return ready(err)
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *socket) SetDeadline(t time.Time) error { return s.fd.SetDeadline(t) }
|
||||
func (s *socket) SetReadDeadline(t time.Time) error { return s.fd.SetReadDeadline(t) }
|
||||
func (s *socket) SetWriteDeadline(t time.Time) error { return s.fd.SetWriteDeadline(t) }
|
||||
|
||||
func (s *socket) SetSockoptInt(level, opt, value int) error {
|
||||
// Value must be in range of a C integer.
|
||||
if value < math.MinInt32 || value > math.MaxInt32 {
|
||||
return unix.EINVAL
|
||||
}
|
||||
|
||||
var err error
|
||||
doErr := s.control(func(fd int) {
|
||||
err = unix.SetsockoptInt(fd, level, opt, value)
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *socket) SetSockoptSockFprog(level, opt int, fprog *unix.SockFprog) error {
|
||||
var err error
|
||||
doErr := s.control(func(fd int) {
|
||||
err = unix.SetsockoptSockFprog(fd, level, opt, fprog)
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ready indicates readiness based on the value of err.
|
||||
func ready(err error) bool {
|
||||
// When a socket is in non-blocking mode, we might see
|
||||
// EAGAIN. In that case, return false to let the poller wait for readiness.
|
||||
// See the source code for internal/poll.FD.RawRead for more details.
|
||||
//
|
||||
// Starting in Go 1.14, goroutines are asynchronously preemptible. The 1.14
|
||||
// release notes indicate that applications should expect to see EINTR more
|
||||
// often on slow system calls (like recvmsg while waiting for input), so
|
||||
// we must handle that case as well.
|
||||
//
|
||||
// If the socket is in blocking mode, EAGAIN should never occur.
|
||||
switch err {
|
||||
case syscall.EAGAIN, syscall.EINTR:
|
||||
// Not ready.
|
||||
return false
|
||||
default:
|
||||
// Ready whether there was error or no error.
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
12
vendor/github.com/mdlayher/netlink/go.mod
generated
vendored
12
vendor/github.com/mdlayher/netlink/go.mod
generated
vendored
@@ -1,12 +0,0 @@
|
||||
module github.com/mdlayher/netlink
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.4
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b
|
||||
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777
|
||||
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65
|
||||
)
|
||||
66
vendor/github.com/mdlayher/netlink/go.sum
generated
vendored
66
vendor/github.com/mdlayher/netlink/go.sum
generated
vendored
@@ -1,66 +0,0 @@
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 h1:uhL5Gw7BINiiPAo24A2sxkcDI0Jt/sqp1v5xQCniEFA=
|
||||
github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201216134343-bde56ed16391/go.mod h1:cR77jAZG3Y3bsb8hF6fHJbFoyFukLFOkQ98S0pQz3xw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201220180245-69540ac93943/go.mod h1:z4c53zj6Eex712ROyh8WI0ihysb5j2ROyV42iNogmAs=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210122163228-8d122574c736/go.mod h1:ZXpIyOK59ZnN7J0BV99cZUPmsqDRZ3eq5X+st7u/oSA=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b h1:c3NTyLNozICy8B4mlMXemD3z/gXgQzVXZS/HqT+i3do=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U=
|
||||
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43 h1:WgyLFv10Ov49JAQI/ZLUkCZ7VJS3r74hwFIGXJsgZlY=
|
||||
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo=
|
||||
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
|
||||
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||
github.com/mdlayher/netlink v1.2.0/go.mod h1:kwVW1io0AZy9A1E2YYgaD4Cj+C+GPkU6klXCMzIJ9p8=
|
||||
github.com/mdlayher/netlink v1.2.1/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU=
|
||||
github.com/mdlayher/netlink v1.2.2-0.20210123213345-5cc92139ae3e/go.mod h1:bacnNlfhqHqqLo4WsYeXSqfyXkInQ9JneWI68v1KwSU=
|
||||
github.com/mdlayher/netlink v1.3.0/go.mod h1:xK/BssKuwcRXHrtN04UBkwQ6dY9VviGGuriDdoPSWys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65 h1:pTMjDVnP5eVRRlWO76rEWJ8JoC6Lf1CmyjPZXRiy2Sw=
|
||||
golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
9
vendor/github.com/mdlayher/socket/LICENSE.md
generated
vendored
Normal file
9
vendor/github.com/mdlayher/socket/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# MIT License
|
||||
|
||||
Copyright (C) 2021 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.
|
||||
14
vendor/github.com/mdlayher/socket/README.md
generated
vendored
Normal file
14
vendor/github.com/mdlayher/socket/README.md
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# socket [](https://github.com/mdlayher/socket/actions) [](https://pkg.go.dev/github.com/mdlayher/socket) [](https://goreportcard.com/report/github.com/mdlayher/socket)
|
||||
|
||||
Package `socket` provides a low-level network connection type which integrates
|
||||
with Go's runtime network poller to provide asynchronous I/O and deadline
|
||||
support. MIT Licensed.
|
||||
|
||||
This package focuses on UNIX-like operating systems which make use of BSD
|
||||
sockets system call APIs. It is meant to be used as a foundation for the
|
||||
creation of operating system-specific socket packages, for socket families such
|
||||
as Linux's `AF_NETLINK`, `AF_PACKET`, or `AF_VSOCK`. This package should not be
|
||||
used directly in end user applications.
|
||||
|
||||
Any use of package socket should be guarded by build tags, as one would also
|
||||
use when importing the `syscall` or `golang.org/x/sys` packages.
|
||||
23
vendor/github.com/mdlayher/socket/accept.go
generated
vendored
Normal file
23
vendor/github.com/mdlayher/socket/accept.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
//go:build !dragonfly && !freebsd && !illumos && !linux
|
||||
// +build !dragonfly,!freebsd,!illumos,!linux
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const sysAccept = "accept"
|
||||
|
||||
// accept wraps accept(2).
|
||||
func accept(fd, flags int) (int, unix.Sockaddr, error) {
|
||||
if flags != 0 {
|
||||
// These operating systems have no support for flags to accept(2).
|
||||
return 0, nil, fmt.Errorf("socket: Conn.Accept flags are ineffective on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
return unix.Accept(fd)
|
||||
}
|
||||
15
vendor/github.com/mdlayher/socket/accept4.go
generated
vendored
Normal file
15
vendor/github.com/mdlayher/socket/accept4.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
//go:build dragonfly || freebsd || illumos || linux
|
||||
// +build dragonfly freebsd illumos linux
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const sysAccept = "accept4"
|
||||
|
||||
// accept wraps accept4(2).
|
||||
func accept(fd, flags int) (int, unix.Sockaddr, error) {
|
||||
return unix.Accept4(fd, flags)
|
||||
}
|
||||
496
vendor/github.com/mdlayher/socket/conn.go
generated
vendored
Normal file
496
vendor/github.com/mdlayher/socket/conn.go
generated
vendored
Normal file
@@ -0,0 +1,496 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// A Conn is a low-level network connection which integrates with Go's runtime
|
||||
// network poller to provide asynchronous I/O and deadline support.
|
||||
type Conn struct {
|
||||
// Indicates whether or not Conn.Close has been called. Must be accessed
|
||||
// atomically. Atomics definitions must come first in the Conn struct.
|
||||
closed uint32
|
||||
|
||||
// A unique name for the Conn which is also associated with derived file
|
||||
// descriptors such as those created by accept(2).
|
||||
name string
|
||||
|
||||
// Provides access to the underlying file registered with the runtime
|
||||
// network poller, and arbitrary raw I/O calls.
|
||||
fd *os.File
|
||||
rc syscall.RawConn
|
||||
}
|
||||
|
||||
// High-level methods which provide convenience over raw system calls.
|
||||
|
||||
// Close closes the underlying file descriptor for the Conn, which also causes
|
||||
// all in-flight I/O operations to immediately unblock and return errors. Any
|
||||
// subsequent uses of Conn will result in EBADF.
|
||||
func (c *Conn) Close() error {
|
||||
// The caller has expressed an intent to close the socket, so immediately
|
||||
// increment s.closed to force further calls to result in EBADF before also
|
||||
// closing the file descriptor to unblock any outstanding operations.
|
||||
//
|
||||
// Because other operations simply check for s.closed != 0, we will permit
|
||||
// double Close, which would increment s.closed beyond 1.
|
||||
if atomic.AddUint32(&c.closed, 1) != 1 {
|
||||
// Multiple Close calls.
|
||||
return nil
|
||||
}
|
||||
|
||||
return os.NewSyscallError("close", c.fd.Close())
|
||||
}
|
||||
|
||||
// Read implements io.Reader by reading directly from the underlying file
|
||||
// descriptor.
|
||||
func (c *Conn) Read(b []byte) (int, error) { return c.fd.Read(b) }
|
||||
|
||||
// Write implements io.Writer by writing directly to the underlying file
|
||||
// descriptor.
|
||||
func (c *Conn) Write(b []byte) (int, error) { return c.fd.Write(b) }
|
||||
|
||||
// SetDeadline sets both the read and write deadlines associated with the Conn.
|
||||
func (c *Conn) SetDeadline(t time.Time) error { return c.fd.SetDeadline(t) }
|
||||
|
||||
// SetReadDeadline sets the read deadline associated with the Conn.
|
||||
func (c *Conn) SetReadDeadline(t time.Time) error { return c.fd.SetReadDeadline(t) }
|
||||
|
||||
// SetWriteDeadline sets the write deadline associated with the Conn.
|
||||
func (c *Conn) SetWriteDeadline(t time.Time) error { return c.fd.SetWriteDeadline(t) }
|
||||
|
||||
// ReadBuffer gets the size of the operating system's receive buffer associated
|
||||
// with the Conn.
|
||||
func (c *Conn) ReadBuffer() (int, error) {
|
||||
return c.GetsockoptInt(unix.SOL_SOCKET, unix.SO_RCVBUF)
|
||||
}
|
||||
|
||||
// WriteBuffer gets the size of the operating system's transmit buffer
|
||||
// associated with the Conn.
|
||||
func (c *Conn) WriteBuffer() (int, error) {
|
||||
return c.GetsockoptInt(unix.SOL_SOCKET, unix.SO_SNDBUF)
|
||||
}
|
||||
|
||||
// SetReadBuffer sets the size of the operating system's receive buffer
|
||||
// associated with the Conn.
|
||||
//
|
||||
// When called with elevated privileges on Linux, the SO_RCVBUFFORCE option will
|
||||
// be used to override operating system limits. Otherwise SO_RCVBUF is used
|
||||
// (which obeys operating system limits).
|
||||
func (c *Conn) SetReadBuffer(bytes int) error { return c.setReadBuffer(bytes) }
|
||||
|
||||
// SetWriteBuffer sets the size of the operating system's transmit buffer
|
||||
// associated with the Conn.
|
||||
//
|
||||
// When called with elevated privileges on Linux, the SO_SNDBUFFORCE option will
|
||||
// be used to override operating system limits. Otherwise SO_SNDBUF is used
|
||||
// (which obeys operating system limits).
|
||||
func (c *Conn) SetWriteBuffer(bytes int) error { return c.setWriteBuffer(bytes) }
|
||||
|
||||
// SyscallConn returns a raw network connection. This implements the
|
||||
// syscall.Conn interface.
|
||||
//
|
||||
// SyscallConn is intended for advanced use cases, such as getting and setting
|
||||
// arbitrary socket options using the socket's file descriptor. If possible,
|
||||
// those operations should be performed using methods on Conn instead.
|
||||
//
|
||||
// Once invoked, it is the caller's responsibility to ensure that operations
|
||||
// performed using Conn and the syscall.RawConn do not conflict with each other.
|
||||
func (c *Conn) SyscallConn() (syscall.RawConn, error) {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
return nil, os.NewSyscallError("syscallconn", unix.EBADF)
|
||||
}
|
||||
|
||||
// TODO(mdlayher): mutex or similar to enforce syscall.RawConn contract of
|
||||
// FD remaining valid for duration of calls?
|
||||
return c.rc, nil
|
||||
}
|
||||
|
||||
// Socket wraps the socket(2) system call to produce a Conn. domain, typ, and
|
||||
// proto are passed directly to socket(2), and name should be a unique name for
|
||||
// the socket type such as "netlink" or "vsock".
|
||||
//
|
||||
// If the operating system supports SOCK_CLOEXEC and SOCK_NONBLOCK, they are
|
||||
// automatically applied to typ to mirror the standard library's socket flag
|
||||
// behaviors.
|
||||
func Socket(domain, typ, proto int, name string) (*Conn, error) {
|
||||
var (
|
||||
fd int
|
||||
err error
|
||||
)
|
||||
|
||||
for {
|
||||
fd, err = unix.Socket(domain, typ|socketFlags, proto)
|
||||
switch {
|
||||
case err == nil:
|
||||
// Some OSes already set CLOEXEC with typ.
|
||||
if !flagCLOEXEC {
|
||||
unix.CloseOnExec(fd)
|
||||
}
|
||||
|
||||
// No error, prepare the Conn.
|
||||
return newConn(fd, name)
|
||||
case !ready(err):
|
||||
// System call interrupted or not ready, try again.
|
||||
continue
|
||||
case err == unix.EINVAL, err == unix.EPROTONOSUPPORT:
|
||||
// On Linux, SOCK_NONBLOCK and SOCK_CLOEXEC were introduced in
|
||||
// 2.6.27. On FreeBSD, both flags were introduced in FreeBSD 10.
|
||||
// EINVAL and EPROTONOSUPPORT check for earlier versions of these
|
||||
// OSes respectively.
|
||||
//
|
||||
// Mirror what the standard library does when creating file
|
||||
// descriptors: avoid racing a fork/exec with the creation of new
|
||||
// file descriptors, so that child processes do not inherit socket
|
||||
// file descriptors unexpectedly.
|
||||
//
|
||||
// For a more thorough explanation, see similar work in the Go tree:
|
||||
// func sysSocket in net/sock_cloexec.go, as well as the detailed
|
||||
// comment in syscall/exec_unix.go.
|
||||
syscall.ForkLock.RLock()
|
||||
fd, err = unix.Socket(domain, typ, proto)
|
||||
if err == nil {
|
||||
unix.CloseOnExec(fd)
|
||||
}
|
||||
syscall.ForkLock.RUnlock()
|
||||
|
||||
return newConn(fd, name)
|
||||
default:
|
||||
// Unhandled error.
|
||||
return nil, os.NewSyscallError("socket", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(mdlayher): consider exporting newConn as New?
|
||||
|
||||
// newConn wraps an existing file descriptor to create a Conn. name should be a
|
||||
// unique name for the socket type such as "netlink" or "vsock".
|
||||
func newConn(fd int, name string) (*Conn, error) {
|
||||
// All Conn I/O is nonblocking for integration with Go's runtime network
|
||||
// poller. Depending on the OS this might already be set but it can't hurt
|
||||
// to set it again.
|
||||
if err := unix.SetNonblock(fd, true); err != nil {
|
||||
return nil, os.NewSyscallError("setnonblock", err)
|
||||
}
|
||||
|
||||
// os.NewFile registers the non-blocking file descriptor with the runtime
|
||||
// poller, which is then used for most subsequent operations except those
|
||||
// that require raw I/O via SyscallConn.
|
||||
//
|
||||
// See also: https://golang.org/pkg/os/#NewFile
|
||||
f := os.NewFile(uintptr(fd), name)
|
||||
rc, err := f.SyscallConn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Conn{
|
||||
name: name,
|
||||
fd: f,
|
||||
rc: rc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Low-level methods which provide raw system call access.
|
||||
|
||||
// Accept wraps accept(2) or accept4(2) depending on the operating system, but
|
||||
// returns a Conn for the accepted connection rather than a raw file descriptor.
|
||||
//
|
||||
// If the operating system supports accept4(2) (which allows flags),
|
||||
// SOCK_CLOEXEC and SOCK_NONBLOCK are automatically applied to flags to mirror
|
||||
// the standard library's socket flag behaviors.
|
||||
//
|
||||
// If the operating system only supports accept(2) (which does not allow flags)
|
||||
// and flags is not zero, an error will be returned.
|
||||
func (c *Conn) Accept(flags int) (*Conn, unix.Sockaddr, error) {
|
||||
var (
|
||||
nfd int
|
||||
sa unix.Sockaddr
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := c.read(sysAccept, func(fd int) error {
|
||||
// Either accept(2) or accept4(2) depending on the OS.
|
||||
nfd, sa, err = accept(fd, flags|socketFlags)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return nil, nil, doErr
|
||||
}
|
||||
if err != nil {
|
||||
// sysAccept is either "accept" or "accept4" depending on the OS.
|
||||
return nil, nil, os.NewSyscallError(sysAccept, err)
|
||||
}
|
||||
|
||||
// Successfully accepted a connection, wrap it in a Conn for use by the
|
||||
// caller.
|
||||
ac, err := newConn(nfd, c.name)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return ac, sa, nil
|
||||
}
|
||||
|
||||
// Bind wraps bind(2).
|
||||
func (c *Conn) Bind(sa unix.Sockaddr) error {
|
||||
const op = "bind"
|
||||
|
||||
var err error
|
||||
doErr := c.control(op, func(fd int) error {
|
||||
err = unix.Bind(fd, sa)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// Connect wraps connect(2).
|
||||
func (c *Conn) Connect(sa unix.Sockaddr) error {
|
||||
const op = "connect"
|
||||
|
||||
var err error
|
||||
doErr := c.write(op, func(fd int) error {
|
||||
err = unix.Connect(fd, sa)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
if err == unix.EISCONN {
|
||||
// Darwin reports EISCONN if already connected, but the socket is
|
||||
// established and we don't need to report an error.
|
||||
return nil
|
||||
}
|
||||
|
||||
return os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// Getsockname wraps getsockname(2).
|
||||
func (c *Conn) Getsockname() (unix.Sockaddr, error) {
|
||||
const op = "getsockname"
|
||||
|
||||
var (
|
||||
sa unix.Sockaddr
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := c.control(op, func(fd int) error {
|
||||
sa, err = unix.Getsockname(fd)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return nil, doErr
|
||||
}
|
||||
|
||||
return sa, os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// GetsockoptInt wraps getsockopt(2) for integer values.
|
||||
func (c *Conn) GetsockoptInt(level, opt int) (int, error) {
|
||||
const op = "getsockopt"
|
||||
|
||||
var (
|
||||
value int
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := c.control(op, func(fd int) error {
|
||||
value, err = unix.GetsockoptInt(fd, level, opt)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return 0, doErr
|
||||
}
|
||||
|
||||
return value, os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// Listen wraps listen(2).
|
||||
func (c *Conn) Listen(n int) error {
|
||||
const op = "listen"
|
||||
|
||||
var err error
|
||||
doErr := c.control(op, func(fd int) error {
|
||||
err = unix.Listen(fd, n)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// Recvmsg wraps recvmsg(2).
|
||||
func (c *Conn) Recvmsg(p, oob []byte, flags int) (int, int, int, unix.Sockaddr, error) {
|
||||
const op = "recvmsg"
|
||||
|
||||
var (
|
||||
n, oobn, recvflags int
|
||||
from unix.Sockaddr
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := c.read(op, func(fd int) error {
|
||||
n, oobn, recvflags, from, err = unix.Recvmsg(fd, p, oob, flags)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return 0, 0, 0, nil, doErr
|
||||
}
|
||||
|
||||
return n, oobn, recvflags, from, os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// Recvfrom wraps recvfrom(2)
|
||||
func (c *Conn) Recvfrom(p []byte, flags int) (int, unix.Sockaddr, error) {
|
||||
const op = "recvfrom"
|
||||
|
||||
var (
|
||||
n int
|
||||
addr unix.Sockaddr
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := c.read(op, func(fd int) error {
|
||||
n, addr, err = unix.Recvfrom(fd, p, flags)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return 0, nil, doErr
|
||||
}
|
||||
|
||||
return n, addr, os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// Sendmsg wraps sendmsg(2).
|
||||
func (c *Conn) Sendmsg(p, oob []byte, to unix.Sockaddr, flags int) error {
|
||||
const op = "sendmsg"
|
||||
|
||||
var err error
|
||||
doErr := c.write(op, func(fd int) error {
|
||||
err = unix.Sendmsg(fd, p, oob, to, flags)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// Sendto wraps Sendto(2).
|
||||
func (c *Conn) Sendto(b []byte, to unix.Sockaddr, flags int) error {
|
||||
const op = "sendto"
|
||||
|
||||
var err error
|
||||
doErr := c.write(op, func(fd int) error {
|
||||
err = unix.Sendto(fd, b, flags, to)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// SetsockoptInt wraps setsockopt(2) for integer values.
|
||||
func (c *Conn) SetsockoptInt(level, opt, value int) error {
|
||||
const op = "setsockopt"
|
||||
|
||||
var err error
|
||||
doErr := c.control(op, func(fd int) error {
|
||||
err = unix.SetsockoptInt(fd, level, opt, value)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// Conn low-level read/write/control functions. These functions mirror the
|
||||
// syscall.RawConn APIs but the input closures return errors rather than
|
||||
// booleans. Any syscalls invoked within f should return their error to allow
|
||||
// the Conn to check for readiness with the runtime network poller, or to retry
|
||||
// operations which may have been interrupted by EINTR or similar.
|
||||
//
|
||||
// Note that errors from the input closure functions are not propagated to the
|
||||
// error return values of read/write/control, and the caller is still
|
||||
// responsible for error handling.
|
||||
|
||||
// read executes f, a read function, against the associated file descriptor.
|
||||
// op is used to create an *os.SyscallError if the file descriptor is closed.
|
||||
func (c *Conn) read(op string, f func(fd int) error) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
return os.NewSyscallError(op, unix.EBADF)
|
||||
}
|
||||
|
||||
return c.rc.Read(func(fd uintptr) bool {
|
||||
return ready(f(int(fd)))
|
||||
})
|
||||
}
|
||||
|
||||
// write executes f, a write function, against the associated file descriptor.
|
||||
// op is used to create an *os.SyscallError if the file descriptor is closed.
|
||||
func (c *Conn) write(op string, f func(fd int) error) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
return os.NewSyscallError(op, unix.EBADF)
|
||||
}
|
||||
|
||||
return c.rc.Write(func(fd uintptr) bool {
|
||||
return ready(f(int(fd)))
|
||||
})
|
||||
}
|
||||
|
||||
// control executes f, a control function, against the associated file
|
||||
// descriptor. op is used to create an *os.SyscallError if the file descriptor
|
||||
// is closed.
|
||||
func (c *Conn) control(op string, f func(fd int) error) error {
|
||||
if atomic.LoadUint32(&c.closed) != 0 {
|
||||
return os.NewSyscallError(op, unix.EBADF)
|
||||
}
|
||||
|
||||
return c.rc.Control(func(fd uintptr) {
|
||||
// Repeatedly attempt the syscall(s) invoked by f until completion is
|
||||
// indicated by the return value of ready.
|
||||
for {
|
||||
if ready(f(int(fd))) {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ready indicates readiness based on the value of err.
|
||||
func ready(err error) bool {
|
||||
// When a socket is in non-blocking mode, we might see EAGAIN or
|
||||
// EINPROGRESS. In that case, return false to let the poller wait for
|
||||
// readiness. See the source code for internal/poll.FD.RawRead for more
|
||||
// details.
|
||||
//
|
||||
// Starting in Go 1.14, goroutines are asynchronously preemptible. The 1.14
|
||||
// release notes indicate that applications should expect to see EINTR more
|
||||
// often on slow system calls (like recvmsg while waiting for input), so we
|
||||
// must handle that case as well.
|
||||
switch err {
|
||||
case unix.EAGAIN, unix.EINTR, unix.EINPROGRESS:
|
||||
// Not ready.
|
||||
return false
|
||||
default:
|
||||
// Ready regardless of whether there was an error or no error.
|
||||
return true
|
||||
}
|
||||
}
|
||||
88
vendor/github.com/mdlayher/socket/conn_linux.go
generated
vendored
Normal file
88
vendor/github.com/mdlayher/socket/conn_linux.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/net/bpf"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// SetBPF attaches an assembled BPF program to a Conn.
|
||||
func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
|
||||
// We can't point to the first instruction in the array if no instructions
|
||||
// are present.
|
||||
if len(filter) == 0 {
|
||||
return os.NewSyscallError("setsockopt", unix.EINVAL)
|
||||
}
|
||||
|
||||
prog := unix.SockFprog{
|
||||
Len: uint16(len(filter)),
|
||||
Filter: (*unix.SockFilter)(unsafe.Pointer(&filter[0])),
|
||||
}
|
||||
|
||||
return c.SetsockoptSockFprog(unix.SOL_SOCKET, unix.SO_ATTACH_FILTER, &prog)
|
||||
}
|
||||
|
||||
// RemoveBPF removes a BPF filter from a Conn.
|
||||
func (c *Conn) RemoveBPF() error {
|
||||
// 0 argument is ignored.
|
||||
return c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_DETACH_FILTER, 0)
|
||||
}
|
||||
|
||||
// SetsockoptSockFprog wraps setsockopt(2) for unix.SockFprog values.
|
||||
func (c *Conn) SetsockoptSockFprog(level, opt int, fprog *unix.SockFprog) error {
|
||||
const op = "setsockopt"
|
||||
|
||||
var err error
|
||||
doErr := c.control(op, func(fd int) error {
|
||||
err = unix.SetsockoptSockFprog(fd, level, opt, fprog)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return doErr
|
||||
}
|
||||
|
||||
return os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// GetSockoptTpacketStats wraps getsockopt(2) for getting TpacketStats
|
||||
func (c *Conn) GetSockoptTpacketStats(level, name int) (*unix.TpacketStats, error) {
|
||||
const op = "getsockopt"
|
||||
|
||||
var (
|
||||
stats *unix.TpacketStats
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := c.control(op, func(fd int) error {
|
||||
stats, err = unix.GetsockoptTpacketStats(fd, level, name)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return stats, doErr
|
||||
}
|
||||
return stats, os.NewSyscallError(op, err)
|
||||
}
|
||||
|
||||
// GetSockoptTpacketStatsV3 wraps getsockopt(2) for getting TpacketStatsV3
|
||||
func (c *Conn) GetSockoptTpacketStatsV3(level, name int) (*unix.TpacketStatsV3, error) {
|
||||
const op = "getsockopt"
|
||||
|
||||
var (
|
||||
stats *unix.TpacketStatsV3
|
||||
err error
|
||||
)
|
||||
|
||||
doErr := c.control(op, func(fd int) error {
|
||||
stats, err = unix.GetsockoptTpacketStatsV3(fd, level, name)
|
||||
return err
|
||||
})
|
||||
if doErr != nil {
|
||||
return stats, doErr
|
||||
}
|
||||
return stats, os.NewSyscallError(op, err)
|
||||
}
|
||||
13
vendor/github.com/mdlayher/socket/doc.go
generated
vendored
Normal file
13
vendor/github.com/mdlayher/socket/doc.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Package socket provides a low-level network connection type which integrates
|
||||
// with Go's runtime network poller to provide asynchronous I/O and deadline
|
||||
// support.
|
||||
//
|
||||
// This package focuses on UNIX-like operating systems which make use of BSD
|
||||
// sockets system call APIs. It is meant to be used as a foundation for the
|
||||
// creation of operating system-specific socket packages, for socket families
|
||||
// such as Linux's AF_NETLINK, AF_PACKET, or AF_VSOCK. This package should not
|
||||
// be used directly in end user applications.
|
||||
//
|
||||
// Any use of package socket should be guarded by build tags, as one would also
|
||||
// use when importing the syscall or golang.org/x/sys packages.
|
||||
package socket
|
||||
24
vendor/github.com/mdlayher/socket/setbuffer_linux.go
generated
vendored
Normal file
24
vendor/github.com/mdlayher/socket/setbuffer_linux.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package socket
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
// setReadBuffer wraps the SO_RCVBUF{,FORCE} setsockopt(2) options.
|
||||
func (c *Conn) setReadBuffer(bytes int) error {
|
||||
err := c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_RCVBUFFORCE, bytes)
|
||||
if err != nil {
|
||||
err = c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_RCVBUF, bytes)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// setWriteBuffer wraps the SO_SNDBUF{,FORCE} setsockopt(2) options.
|
||||
func (c *Conn) setWriteBuffer(bytes int) error {
|
||||
err := c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_SNDBUFFORCE, bytes)
|
||||
if err != nil {
|
||||
err = c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_SNDBUF, bytes)
|
||||
}
|
||||
return err
|
||||
}
|
||||
16
vendor/github.com/mdlayher/socket/setbuffer_others.go
generated
vendored
Normal file
16
vendor/github.com/mdlayher/socket/setbuffer_others.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package socket
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
// setReadBuffer wraps the SO_RCVBUF setsockopt(2) option.
|
||||
func (c *Conn) setReadBuffer(bytes int) error {
|
||||
return c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_RCVBUF, bytes)
|
||||
}
|
||||
|
||||
// setWriteBuffer wraps the SO_SNDBUF setsockopt(2) option.
|
||||
func (c *Conn) setWriteBuffer(bytes int) error {
|
||||
return c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_SNDBUF, bytes)
|
||||
}
|
||||
12
vendor/github.com/mdlayher/socket/typ_cloexec_nonblock.go
generated
vendored
Normal file
12
vendor/github.com/mdlayher/socket/typ_cloexec_nonblock.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
//go:build !darwin
|
||||
// +build !darwin
|
||||
|
||||
package socket
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const (
|
||||
// These operating systems support CLOEXEC and NONBLOCK socket options.
|
||||
flagCLOEXEC = true
|
||||
socketFlags = unix.SOCK_CLOEXEC | unix.SOCK_NONBLOCK
|
||||
)
|
||||
11
vendor/github.com/mdlayher/socket/typ_none.go
generated
vendored
Normal file
11
vendor/github.com/mdlayher/socket/typ_none.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
package socket
|
||||
|
||||
const (
|
||||
// These operating systems do not support CLOEXEC and NONBLOCK socket
|
||||
// options.
|
||||
flagCLOEXEC = false
|
||||
socketFlags = 0
|
||||
)
|
||||
Reference in New Issue
Block a user