Fix delivery of zero-byte UDP datagrams#5347
Conversation
|
please stop editing the next release release notes file directly. |
|
Hi @mvanhorn, The changelog - fixed label was added to this pull request; all PRs with a changelog label need to have release notes included as part of the PR. If you haven't added release notes already, please do. Release notes are added by creating a uniquely named file in the The basic format of the release notes (using markdown) should be: Thanks. |
|
please give this PR a title that is a good entry in the CHANGELOG |
…lang#5289) Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
6d7620f to
4fc8c47
Compare
|
@SeanTAllen thanks, both fixed in
Sorry for the direct edit, won't happen again. |
Two small follow-ups after a self-review pass with ponylang/llm-skills' pony-code-review skill: - packages/net/udp_socket.pony: expand the _pending_reads docstring to describe the actual budget semantics (4 KB of read work, with empty datagrams charged 1 byte each) and add an inline comment explaining the .max(1) DoS guard. - packages/net/_test.pony: add the "unreliable-appveyor-osx" label on _TestUDPZeroByteDatagram, matching _TestBroadcast precedent for UDP tests that bind to the wildcard address and rely on local_address() delivery.
|
@SeanTAllen - I ran pony-code-review against this PR per your ask. The review came back clean on the fix itself: adversarial couldn't construct a scenario where the bug still occurs, correctness found no blocking issues, the test passes the counterfactual check against the two most obvious reverts. Pushed 85473d0 with three small polishes the review surfaced:
Two parked items the review surfaced that I left for your call:
|
Summary
pony_os_recvfromno longer treats a zero-byte POSIXrecvfromas an error. Zero-byte UDP datagrams are now delivered toUDPNotify.receivedwith an empty payload, matching RFC 768. TCPpony_os_recvbehavior is unchanged.Why this matters
RFC 768 says UDP datagrams "may be of any length greater than or equal to zero." Before this change, applications using zero-byte UDP datagrams as heartbeats, keepalives, or presence pings saw the socket torn down because the runtime called
pony_error()onrecvd == 0.Maintainer @SeanTAllen called out the fix shape in the issue thread:
A note on the implementation:
pony_os_recvfromstill returnssize_tin this tree (noPONY_SOCKET_*enum visible insrc/libponyrt/lang/socket.c). To match the existingpony_os_recvcalling convention used elsewhere, this patch uses the existing(size_t)-1/SIZE_MAXsentinel for "would block / no data" and letsrecvd == 0fall through as a normallen == 0read.udp_socket.ponycheckslen == USize.max_value()to mean "no data yet" (replacing the priorlen == 0check, which now legitimately means "empty datagram"). If the three-state enum design has actually landed somewhere I missed, happy to rewrite to use it.Testing
New PonyTest case
_TestUDPZeroByteDatagramround-trips a zero-byte datagram through a bound UDP socket and asserts the notifier receivesdata.size() == 0. Existing TCP suite is untouched.Fixes #5289