Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 11 additions & 19 deletions conn_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,28 +121,20 @@ func (c *conn) Send(m Message) error {

// Receive receives one or more Messages from netlink.
func (c *conn) Receive() ([]Message, error) {
b := make([]byte, os.Getpagesize())
for {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether the reason for the loop here was to make sure we are not falling behind the kernel in an async scenario. Perhaps @mdlayher wanted to avoid setting the buffer to the exact number of available bytes.

Is it possible for more bytes come in before the next recvmsg call ? I think that shouldn't happen but have you confirmed that @florianl ?

If it's indeed safe then it'd be nice to have this.

// Peek at the buffer to see how many bytes are available.
//
// TODO(mdlayher): deal with OOB message data if available, such as
// when PacketInfo ConnOption is true.
n, _, _, _, err := c.s.Recvmsg(context.Background(), b, nil, unix.MSG_PEEK)
if err != nil {
return nil, err
}

// Break when we can read all messages
if n < len(b) {
break
}

// Double in size if not enough bytes
b = make([]byte, len(b)*2)
b := make([]byte, unix.SizeofNlMsghdr)
// Peek at the buffer to see how many bytes are available.
//
// TODO(mdlayher): deal with OOB message data if available, such as
// when PacketInfo ConnOption is true.
n, _, _, _, err := c.s.Recvmsg(context.Background(), b, nil, unix.MSG_PEEK|unix.MSG_TRUNC)
if err != nil {
return nil, err
}
// Resize buffer to the expected size.
b = make([]byte, nlmsgAlign(n))

// Read out all available messages
n, _, _, _, err := c.s.Recvmsg(context.Background(), b, nil, 0)
n, _, _, _, err = c.s.Recvmsg(context.Background(), b, nil, 0)
if err != nil {
return nil, err
}
Expand Down