Repository navigation
fix(libkernel): count a dissolved datagram association as disconnected on macOS - #10544
maximilianfv wants to merge 1 commit into
Conversation
…d on macOS On macOS, connect to AF_UNSPEC on a connected datagram socket dissolves the association but returns -1, with EAFNOSUPPORT for IPv4 and EINVAL for IPv6. Disconnect took that as a failure, so connect to port 0 on a connected datagram socket failed with 47 instead of EADDRNOTAVAIL (49). Treat the call as successful when the socket is no longer connected. Co-authored-by: marion909 <103169397+marion909@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
MarcZX10
left a comment
There was a problem hiding this comment.
The macOS behavior appears correct from the probes and targeted guest_socket_port_zero result, but this PR duplicates an exact, still-open change already present in #7201. I verified #7201 is open and its current Udp.cpp hunk has the same failed-connect / getpeername / ENOTCONN logic. The repository contribution rule asks contributors to check that no open PR already implements the same change. Please coordinate with the #7201 author/maintainers on which PR carries this hunk and establish the sequencing so only one open change implements it before this can be approved. This is a duplicate-work concern, not a request to close PRs because of queue size. Also consider adding a guest regression for the direct AF_UNSPEC path whose result changes here; the current test evidence covers the port-zero caller.
|
Repeated your probe on an M5 Pro, macOS 27.2 (26B5086k), built both x86_64 (Rosetta 2) and arm64. Both give the same results, for explicitly bound and implicitly bound sockets:
I also checked that the socket stays usable after the dissolve: a second
AI-assisted: yes |
What
On macOS,
connecttoAF_UNSPECon a connected datagram socket dissolves the association but returns -1:EAFNOSUPPORT(47) for IPv4 andEINVAL(22) for IPv6.Disconnectinlibkernel/Socket/src/Udp.cpptook that as a failure. It is used byconnectto port 0 on a datagram socket (ZeroPortConnect, added in #9105) and by a guestconnecttoAF_UNSPEC, so on macOSconnectto port 0 on a connected datagram socket failed with 47 instead ofEADDRNOTAVAIL(49), andguest_socket_port_zerofailed.This adds an
__APPLE__branch toDisconnect: when the hostconnect(AF_UNSPEC)fails butgetpeernamethen fails withENOTCONN, the association is gone andDisconnectgoes on as on Linux; otherwise it fails with theconnecterror as before. Linux and Windows code is unchanged.Host behaviour, from standalone C probes (x86_64 under Rosetta 2):
connect(AF_UNSPEC): IPv4 returns -1 with errno 47, IPv6 -1 with errno 22; in both casesgetpeernamethen fails withENOTCONN(57) and the local port is kept.0.0.0.0and keeps the port, for an explicitly and an implicitly bound socket. That is what FreeBSD 11.4'sudp_disconnect()does, as the existing "connect to AF_UNSPEC" entry indocs/dev/debt/libkernel.mddescribes, so the debt file is unchanged.connecttoAF_UNSPECalready returned 47 on macOS IPv4, becauseDisconnectfailed with the host's 47; with this change it follows the Linux path.Prior art: the whole-port PR #7201 by @marion909 has the same change (commit c31e82f, 2026-10-16): the same check (after the failed
connect,getpeernamemust fail withENOTCONN), nested as#if defined(__APPLE__)inside the non-Windows branch and using a separate local for the peer address. I found the bug independently with the probes above, but #7201 had the fix first, so marion909 is credited as co-author on the commit. #7201 also changesDisconnect, so whichever merges second will conflict there; this PR carries only this fix so it can land on its own. #8658 and the PRs split from it (#10362, #10419) do not touchDisconnect.One guest-visible result changes away from FreeBSD on macOS: a guest
connecttoAF_UNSPECwith a 16-byte address on a connected IPv6 datagram socket returnedEINVAL(22) before this change, by way of the host's error, and now returnsEAFNOSUPPORT(47), which Linux and Windows already return. FreeBSD 11.4 returns 22 there (in6_pcbladdrchecks the address length before the family). With a 28-byte address the result changes from 22 to 47, which matches FreeBSD. The address-length checks are a separate gap (#10299 reworks them).Possible follow-up, not part of this PR:
libSceNet/Export.cpphas its own copy of this disconnect code (from #4669) with the same pattern. It is not changed here, and I make no claim that it is broken:guest_sce_netstops earlier on macOS (GuestSceNet.cpp:175,CheckSocketHostErrors) with and without this change, so its datagram-disconnect check is not reached.Tested
Apple M1 Pro, macOS 27.0.1, x86_64 build under Rosetta 2.
mainalone does not build on macOS, so this was tested in a tree made of mugurc's macOS series (27e9689) merged withmainat 1e20650, plus the macOS build parts of #10419 and other unopened macOS fixes, toggling only this change.ctest -R '^(guest_socket_.*|guest_udp|guest_poll|guest_refused_connect|guest_datagram_.*|net_dontwait_.*|guest_sce_net|guest_inet_address)$'(33 tests):guest_socket_port_zerofails withconnect to port 0 on a connected datagram socket must fail with EADDRNOTAVAIL (49) (errno 47).guest_sce_net,guest_pollandguest_socket_pairabort;guest_socket_read_writeaborted in that run.guest_socket_port_zeropasses.guest_sce_net,guest_pollandguest_socket_pairstill abort;guest_refused_connectaborted in that run.guest_refused_connectandguest_socket_read_writeare flaky on this machine whether or not the change is applied. Over 5 repeated runs each (counted by hand, not kept as logs),guest_refused_connectpassed 1/5 with and 1/5 without the change, andguest_socket_read_writepassed 5/5 with and 4/5 without.guest_sce_netstops atGuestSceNet.cpp:175(found with lldb on a-O0rebuild), before it reaches the datagram disconnect check. Whereguest_pollandguest_socket_pairstop was not found.Not tested on Linux or Windows; their code is unchanged, as the new branch is
__APPLE__only.Checklist
main; no other open PR implements the same functions (except Macos port #7201, the whole macOS port, see What)NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code