mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-31 21:06:18 +01:00
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