Hi,
While adding Debian GNU/Hurd support to HiPerConTracer
(https://www.nntb.no/~dreibh/hipercontracer/), I encountered an issue
when sending packets over raw sockets using Boost.Asio.
Boost.Asio automatically sets the MSG_NOSIGNAL flag on send operations
(send() / send_to()). On Linux, POSIX, and standard Hurd UDP sockets,
passing MSG_NOSIGNAL to non-stream sockets is accepted/ignored. However,
on GNU/Hurd raw sockets, the call fails with "Invalid argument":
Invalid argument [system:1073741846 at
/usr/include/boost/asio/detail/reactive_socket_service.hpp:261:5 in
function 'size_t
boost::asio::detail::reactive_socket_service<Protocol>::send_to(...)']
--- REPRODUCTION ---
Attached are two minimal C++ test cases:
- s1.cc: Raw socket (SOCK_RAW / IPPROTO_UDP) with IP_HDRINCL
- s2.cc: Standard UDP socket (SOCK_DGRAM)
Compilation:
g++ s1.cc -o s1 -lboost_system
g++ s2.cc -o s2 -lboost_system
Run:
sudo ./s1 127.0.0.1 12345 127.0.0.1 7777
./s2 127.0.0.1 12345 127.0.0.1 7777
Result:
- s2 (UDP socket) succeeds on GNU/Hurd.
- s1 (Raw socket) fails on GNU/Hurd with "Invalid argument".
Workaround in application code:
Uncommenting the following block in s1.cc before Boost header inclusion
allows s1 to work on Hurd:
#if defined(__GNU__)
#include <sys/socket.h>
#undef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
--- ROOT CAUSE IN PFINET ---
Comparing pfinet's protocol handlers reveals an inconsistency in flag
bitmask checking between UDP and raw sockets.
In pfinet/linux-src/net/ipv4/udp.c:
if (msg->msg_flags & ~(MSG_DONTROUTE|MSG_DONTWAIT|MSG_NOSIGNAL))
return -EINVAL;
In pfinet/linux-src/net/ipv4/raw.c (raw_sendmsg):
if (msg->msg_flags & ~(MSG_DONTROUTE|MSG_DONTWAIT))
return(-EINVAL);
Because MSG_NOSIGNAL is omitted from the allowed flag mask in
pfinet/linux-src/net/ipv4/raw.c, raw_sendmsg() returns -EINVAL whenever
MSG_NOSIGNAL is set.
Adding MSG_NOSIGNAL to the permitted flag mask in
pfinet/linux-src/net/ipv4/raw.c (and pfinet/linux-src/net/ipv6/raw.c if
applicable) would probably align raw socket behavior with standard UDP
sockets and resolve Boost.Asio compatibility on Hurd.