From 6773488cc03fe3a8dec57bb20ac9cce72a0ca5b4 Mon Sep 17 00:00:00 2001 From: Maximilian Moehl Date: Thu, 10 Aug 2023 17:56:09 +0200 Subject: [PATCH] fix: ensure we receive all messages we expect After sending a message only a single call to `conn.Receive` is made which can cause messages to queue up in the receive buffer if not all messages can be returned at once. This causes `ENOBUFS` as the kernel is unable to write any further messages. This commit introduces a check that ensures we call `conn.Receive` as often as needed to get the right number of responses: one for acknowledgment and one for the echo. Resolves: #235 --- conn.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/conn.go b/conn.go index 711d7f6..dfacd5c 100644 --- a/conn.go +++ b/conn.go @@ -230,13 +230,23 @@ func (cc *Conn) Flush() error { return fmt.Errorf("SendMessages: %w", err) } - // Fetch the requested acknowledgement for each message we sent. + // Fetch the requested acknowledgement and echo for each message we sent. for _, msg := range cc.messages { - if msg.Header.Flags&netlink.Acknowledge == 0 { - continue // message did not request an acknowledgement + var expectedResponses int + if msg.Header.Flags&netlink.Acknowledge != 0 { + expectedResponses++ } - if _, err := conn.Receive(); err != nil { - return fmt.Errorf("conn.Receive: %w", err) + if msg.Header.Flags&netlink.Echo != 0 { + expectedResponses++ + } + + for i := 0; i < expectedResponses; { + responses, err := conn.Receive() + if err != nil { + return fmt.Errorf("conn.Receive: %w", err) + } + + i += len(responses) } }