Loading src/posix/udp.cpp +21 −9 Original line number Diff line number Diff line Loading @@ -56,13 +56,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define UDP_GRO 104 #endif // macOS lacks sendmmsg/recvmmsg; so do OpenBSD, NetBSD and DragonFly BSD -- // only FreeBSD 11+ and Linux have them. This guard previously only checked // __APPLE__, so every other BSD unconditionally called ::sendmmsg/::recvmmsg // (declared, if at all, only via a stray <sys/uio.h> comment, not an actual // prototype) -- whatever happened to link/run before was accidental, not a // tested code path. #if defined(__linux__) || defined(__FreeBSD__) // macOS lacks sendmmsg/recvmmsg entirely, so do OpenBSD, NetBSD and // DragonFly BSD -- calling them there doesn't compile. FreeBSD 11+ does // have the symbols, but sendmmsg() to an explicit (unconnected) peer // address has been observed there to fail a QUIC server's Retry/handshake // sends with EINVAL, even though the identical arguments work fine via // plain sendto() -- not something a Linux dev box can repro (it accepts // this call shape fine). Rather than special-case that one FreeBSD failure // mode, only Linux -- where this path is actually exercised and trusted -- // gets the real sendmmsg/recvmmsg path; every other platform, FreeBSD // included, uses the sendto/recvfrom fallback below. #if !defined(__linux__) && !defined(__FreeBSD__) #define NETPLUS_NO_MMSG 1 #endif Loading Loading @@ -462,7 +466,12 @@ ssize_t udp::sendBatch( // --- sendmmsg path --- #ifdef NETPLUS_NO_MMSG // Fallback: sendto loop for platforms without sendmmsg // Fallback: sendto loop for platforms without a trusted sendmmsg. // Mirrors sendmmsg()'s own contract (-1/errno if nothing at all went // out, otherwise the count sent before the first failure) instead of // silently reporting "0 sent, no error" -- callers like // quic::sendRetryPacket() log errno precisely because they need to see // real failures, not just a suspiciously-low count. int sent = 0; for (size_t i = 0; i < count; ++i) { ssize_t r; Loading @@ -472,7 +481,10 @@ ssize_t udp::sendBatch( } else { r = ::send(_Socket, datagrams[i].first, datagrams[i].second, MSG_DONTWAIT); } if (r < 0) break; if (r < 0) { if (sent == 0) return -1; break; } ++sent; } #else Loading Loading
src/posix/udp.cpp +21 −9 Original line number Diff line number Diff line Loading @@ -56,13 +56,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define UDP_GRO 104 #endif // macOS lacks sendmmsg/recvmmsg; so do OpenBSD, NetBSD and DragonFly BSD -- // only FreeBSD 11+ and Linux have them. This guard previously only checked // __APPLE__, so every other BSD unconditionally called ::sendmmsg/::recvmmsg // (declared, if at all, only via a stray <sys/uio.h> comment, not an actual // prototype) -- whatever happened to link/run before was accidental, not a // tested code path. #if defined(__linux__) || defined(__FreeBSD__) // macOS lacks sendmmsg/recvmmsg entirely, so do OpenBSD, NetBSD and // DragonFly BSD -- calling them there doesn't compile. FreeBSD 11+ does // have the symbols, but sendmmsg() to an explicit (unconnected) peer // address has been observed there to fail a QUIC server's Retry/handshake // sends with EINVAL, even though the identical arguments work fine via // plain sendto() -- not something a Linux dev box can repro (it accepts // this call shape fine). Rather than special-case that one FreeBSD failure // mode, only Linux -- where this path is actually exercised and trusted -- // gets the real sendmmsg/recvmmsg path; every other platform, FreeBSD // included, uses the sendto/recvfrom fallback below. #if !defined(__linux__) && !defined(__FreeBSD__) #define NETPLUS_NO_MMSG 1 #endif Loading Loading @@ -462,7 +466,12 @@ ssize_t udp::sendBatch( // --- sendmmsg path --- #ifdef NETPLUS_NO_MMSG // Fallback: sendto loop for platforms without sendmmsg // Fallback: sendto loop for platforms without a trusted sendmmsg. // Mirrors sendmmsg()'s own contract (-1/errno if nothing at all went // out, otherwise the count sent before the first failure) instead of // silently reporting "0 sent, no error" -- callers like // quic::sendRetryPacket() log errno precisely because they need to see // real failures, not just a suspiciously-low count. int sent = 0; for (size_t i = 0; i < count; ++i) { ssize_t r; Loading @@ -472,7 +481,10 @@ ssize_t udp::sendBatch( } else { r = ::send(_Socket, datagrams[i].first, datagrams[i].second, MSG_DONTWAIT); } if (r < 0) break; if (r < 0) { if (sent == 0) return -1; break; } ++sent; } #else Loading