diff options
| author | Vladimir Grebenshchikov <vova@zote.me> | 2026-10-21 22:14:33 +0000 |
|---|---|---|
| committer | Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org> | 2026-10-28 15:15:51 +0000 |
| commit | afeb885b4ae41357a648f547d3835a5e0dcde81e (patch) | |
| tree | 0b1c11147b1c7c9d5f8cff603784d6106d7c0534 /usr.bin/ctlstat/ctlstat.8 | |
| parent | ad9ab26ab52a0a88933806c81f34d2670c0f69a9 (diff) | |
linux_recvmmsg_common() currently returns the error from the next
recvmsg() attempt even when one or more datagrams have already been
received and copied to userspace.
This is especially visible with non-blocking UDP sockets. After
receiving the first datagram, the next iteration commonly returns
EAGAIN. The syscall then reports EAGAIN instead of the number of
messages already stored in the mmsghdr array, causing applications to
discard successfully received packets.
This differs from Linux recvmmsg() semantics, where an error encountered
after receiving at least one message is deferred and the number of
received messages is returned.
Return the accumulated datagram count and clear the error whenever at
least one message was received. Preserve the original error when no
messages were received.
This fixes packet loss in applications such as wireguard-go, whose
non-blocking receive path uses recvmmsg() for batches of UDP packets.
In the observed failure, WireGuard handshake responses reached the UDP
socket, but a subsequent EAGAIN caused recvmmsg() to hide the received
response and the handshake timed out.
Reviewed by: kib
Pull Request: https://github.com/freebsd/freebsd-src/pull/2484
Differential Revision: https://reviews.freebsd.org/D60961
Diffstat (limited to 'usr.bin/ctlstat/ctlstat.8')
0 files changed, 0 insertions, 0 deletions
