Skip to content

Commit

Permalink
Ensure a minimum of 32KB for the buffer used in recvmsg()
Browse files Browse the repository at this point in the history
See iproute2 commit bb5ae621d0c7 ("lib/libnetlink: ensure a minimum of
32KB for the buffer used in rtnl_recvmsg()").
iproute2/iproute2@bb5ae621d0c7

Linux v4.9 and newer contains the two commits mentioned in the above
commit message:
"See kernel commits 9063e21fb026 ("netlink: autosize skb lengthes") and
d35c99ff77ec ("netlink: do not enter direct reclaim from netlink_dump()")
for more details."

Also, use unix.MSG_TRUNC to peek without copying the actual payload.

Related to issues mdlayher#178.
  • Loading branch information
wenjianhn authored and Jian Wen committed Oct 11, 2023
1 parent 657f7da commit 9de88ae
Showing 1 changed file with 14 additions and 17 deletions.
31 changes: 14 additions & 17 deletions conn_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,28 +121,25 @@ 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 {
// 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
}
b := []byte{}

// Break when we can read all messages
if n < len(b) {
break
}
// 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
}

// Double in size if not enough bytes
b = make([]byte, len(b)*2)
if n < 32768 {
n = 32768
}

b = make([]byte, 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

0 comments on commit 9de88ae

Please sign in to comment.