|
|
|
|
@@ -101,13 +101,13 @@ func (c *Conn) Close() error {
|
|
|
|
|
return c.f.Close()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Recvfrom wraps recv(2) with nonblocking behaviour via the runtime network poller.
|
|
|
|
|
// Recvmsg wraps recv(2) with nonblocking behaviour via the runtime network poller.
|
|
|
|
|
//
|
|
|
|
|
// The returned slice is valid until the next call to Recvfrom.
|
|
|
|
|
func (c *Conn) Recvfrom(
|
|
|
|
|
// The returned slice is valid until the next call to Recvmsg.
|
|
|
|
|
func (c *Conn) Recvmsg(
|
|
|
|
|
ctx context.Context,
|
|
|
|
|
flags int,
|
|
|
|
|
) (data []byte, from syscall.Sockaddr, err error) {
|
|
|
|
|
) (data []byte, recvflags int, from syscall.Sockaddr, err error) {
|
|
|
|
|
if err = c.f.SetReadDeadline(time.Time{}); err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@@ -117,7 +117,7 @@ func (c *Conn) Recvfrom(
|
|
|
|
|
done := make(chan error, 1)
|
|
|
|
|
go func() {
|
|
|
|
|
rcErr := c.raw.Read(func(fd uintptr) (done bool) {
|
|
|
|
|
n, from, err = syscall.Recvfrom(int(fd), data, flags)
|
|
|
|
|
n, _, recvflags, from, err = syscall.Recvmsg(int(fd), data, nil, flags)
|
|
|
|
|
return err != syscall.EWOULDBLOCK
|
|
|
|
|
})
|
|
|
|
|
if n >= 0 {
|
|
|
|
|
@@ -129,7 +129,7 @@ func (c *Conn) Recvfrom(
|
|
|
|
|
select {
|
|
|
|
|
case rcErr := <-done:
|
|
|
|
|
if err != nil {
|
|
|
|
|
err = os.NewSyscallError("recvfrom", err)
|
|
|
|
|
err = os.NewSyscallError("recvmsg", err)
|
|
|
|
|
} else {
|
|
|
|
|
err = rcErr
|
|
|
|
|
}
|
|
|
|
|
@@ -147,12 +147,12 @@ func (c *Conn) Recvfrom(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sendto wraps send(2) with nonblocking behaviour via the runtime network poller.
|
|
|
|
|
func (c *Conn) Sendto(
|
|
|
|
|
// Sendmsg wraps send(2) with nonblocking behaviour via the runtime network poller.
|
|
|
|
|
func (c *Conn) Sendmsg(
|
|
|
|
|
ctx context.Context,
|
|
|
|
|
p []byte,
|
|
|
|
|
flags int,
|
|
|
|
|
to syscall.Sockaddr,
|
|
|
|
|
flags int,
|
|
|
|
|
) (err error) {
|
|
|
|
|
if err = c.f.SetWriteDeadline(time.Time{}); err != nil {
|
|
|
|
|
return
|
|
|
|
|
@@ -161,7 +161,7 @@ func (c *Conn) Sendto(
|
|
|
|
|
done := make(chan error, 1)
|
|
|
|
|
go func() {
|
|
|
|
|
done <- c.raw.Write(func(fd uintptr) (done bool) {
|
|
|
|
|
err = syscall.Sendto(int(fd), p, flags, to)
|
|
|
|
|
err = syscall.Sendmsg(int(fd), p, nil, to, flags)
|
|
|
|
|
return err != syscall.EWOULDBLOCK
|
|
|
|
|
})
|
|
|
|
|
}()
|
|
|
|
|
@@ -169,7 +169,7 @@ func (c *Conn) Sendto(
|
|
|
|
|
select {
|
|
|
|
|
case rcErr := <-done:
|
|
|
|
|
if err != nil {
|
|
|
|
|
err = os.NewSyscallError("sendto", err)
|
|
|
|
|
err = os.NewSyscallError("sendmsg", err)
|
|
|
|
|
} else {
|
|
|
|
|
err = rcErr
|
|
|
|
|
}
|
|
|
|
|
@@ -278,7 +278,7 @@ type HandlerFunc func(resp []syscall.NetlinkMessage) error
|
|
|
|
|
func (c *Conn) receive(ctx context.Context, f HandlerFunc, flags int) error {
|
|
|
|
|
for {
|
|
|
|
|
var resp []syscall.NetlinkMessage
|
|
|
|
|
if data, _, err := c.Recvfrom(ctx, flags); err != nil {
|
|
|
|
|
if data, _, _, err := c.Recvmsg(ctx, flags); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
} else if len(data) < syscall.NLMSG_HDRLEN {
|
|
|
|
|
return syscall.EBADE
|
|
|
|
|
@@ -302,9 +302,9 @@ func (c *Conn) Roundtrip(ctx context.Context, f HandlerFunc) error {
|
|
|
|
|
}
|
|
|
|
|
defer func() { c.seq++ }()
|
|
|
|
|
|
|
|
|
|
if err := c.Sendto(ctx, c.pending(), 0, &syscall.SockaddrNetlink{
|
|
|
|
|
if err := c.Sendmsg(ctx, c.pending(), &syscall.SockaddrNetlink{
|
|
|
|
|
Family: syscall.AF_NETLINK,
|
|
|
|
|
}); err != nil {
|
|
|
|
|
}, 0); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|