bsd.org> List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-bugs@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D295009 Bug ID: 295009 Summary: UDP receive with zero-size buffer immediately returns, no wait, no EAGAIN Product: Base System Version: 15.0-RELEASE Hardware: Any OS: Any Status: New Severity: Affects Many People Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: thierry@lelegard.fr On FreeBSD 15.0-RELEASE-p8, receiving a UDP datagram using recv(), recvfrom= (), or recvmsg() with a zero-size data buffer immediately returns with value ze= ro, even when no datagram is sent, even when the socket is in non-blocking mode. According to the POSIX spec and the FreeBSD man pages, when zero is specifi= ed as reception buffer size, the correct behaviour should be: - In blocking mode: wait for a datagram, return zero, optionally report the truncation of the message in flags. - In non-blocking mode, when no message is immediately available, return -1 and set errno to EAGAIN. Other operating systems: - macOS 26.4.1 behaves as FreeBSD. The bug is probably in their common root= s. - Linux 7.0: expected POSIX behaviour. The following code reproduces the problem. It opens a UDP socket, binds it = to 127.0.0.1:1234, and receives a message (typically a text string to display). There are two parameters: receive buffer size and optional non-blocking mod= e. Syntax: udpzero [bufsize [-n]] bufsize : receive buffer size, default: 256 -n : non-blocking Sample command to send a 4-byte message using bash: echo -n "abcd" >/dev/udp/127.0.0.1/1234 On FreeBSD 15.0-RELEASE-p8 and macOS 26.4.1: $ ./udpzero receive buffer size: 256, blocking mode [... wait for a message ...] received size: 4, data: "abcd" $ $ ./udpzero 10 -n receive buffer size: 10, non-blocking mode recv: Resource temporarily unavailable $ $ ./udpzero 0 receive buffer size: 0, blocking mode received size: 0, data: "" $ $ ./udpzero 0 -n receive buffer size: 0, non-blocking mode received size: 0, data: "" On Linux 7.0 (Ubuntu 26.04): $ ./udpzero receive buffer size: 256, blocking mode [... wait for a message ...] received size: 4, data: "abcd" $ $ ./udpzero 10 -n receive buffer size: 10, non-blocking mode recv: Resource temporarily unavailable $ $ ./udpzero 0 receive buffer size: 0, blocking mode [... wait for a message ...] received size: 0, data: "" $ $ ./udpzero 0 -n receive buffer size: 0, non-blocking mode recv: Resource temporarily unavailable ----------------------------------------------------- #include #include #include #include #include #include #include #include void check(int cond, const char* message) { if (!cond) { perror(message); exit(EXIT_FAILURE); } } int main(int argc, char* argv[]) { const int bufsize =3D argc < 2 ? 256 : atoi(argv[1]); const int nonblock =3D argc >=3D 3 && strcmp(argv[2], "-n") =3D=3D 0; printf("receive buffer size: %d, %sblocking mode\n", bufsize, nonblock ? "non-" : ""); char* data =3D malloc(bufsize); check(data !=3D NULL, "malloc"); int sock =3D socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); check(sock >=3D 0, "socket"); if (nonblock) { int flags =3D fcntl(sock, F_GETFL, 0); check(flags !=3D -1, "fcntl"); flags =3D fcntl(sock, F_SETFL, flags | O_NONBLOCK); check(flags !=3D -1, "fcntl"); } struct sockaddr_in addr; addr.sin_family =3D AF_INET; addr.sin_addr.s_addr =3D htonl(0x7F000001); // 127.0.0.1 addr.sin_port =3D htons(1234); int status =3D bind(sock, (struct sockaddr*)&addr, sizeof(addr)); check(status =3D=3D 0, "bind"); socklen_t len =3D sizeof(addr); ssize_t insize =3D recvfrom(sock, data, bufsize, 0, (struct sockaddr*)&= addr, &len); check(insize >=3D 0, "recv"); printf("received size: %ld, data: \"%.*s\"\n", insize, (int)insize, dat= a); close(sock); return EXIT_SUCCESS; } --=20 You are receiving this mail because: You are the assignee for the bug.=