Re-arm SocketAddress.Size before every ReceiveFrom (fixes the red net8.0 leg) - #1
Merged
Merged
Conversation
… whole again The receive path now survives empty polls on .NET 8. Socket.ReceiveFrom requires the reusable SocketAddress sized to the family maximum before each call, and .NET 8 overwrites Size with the received address length BEFORE checking the recvfrom result - so the first EWOULDBLOCK poll (the steady state of a non-blocking socket) zeroes it and the next call throws ArgumentOutOfRangeException "SocketAddress is too small" out of NetcodeSocket.ReceivePacket. .NET 9 moved that assignment below the error check, which is why only the LTS leg failed. Local runs cannot see this: the net8.0 TFM rolls forward to the .NET 10 runtime here, so both legs (46 tests each) pass locally and CI's real .NET 8 is the proof that counts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the one red CI on main (383666e): both OS legs fail deterministically in
test_client_server_ipv4_socket_connectwithArgumentOutOfRangeException: Provided SocketAddress is too small for given AddressFamilyatSocket.ReceiveFrom, viaNetcodeSocket.ReceivePacket.Mechanism (read straight from the runtime source, release/8.0 vs release/9.0
Socket.cs): the SocketAddress-takingReceiveFromoverload guardsreceivedAddress.Size >= SocketAddress.GetMaximumAddressSize(AddressFamily)before every call. On .NET 8 it then assignsreceivedAddress.Size = socketAddressSizebefore checking the recvfrom result, so the first empty poll of our non-blocking socket (EWOULDBLOCK, the steady state) zeroesSize, and the next call trips the guard. .NET 9 moved that assignment below the error check, which is exactly why the net10 leg is green and only the LTS leg burns.Fix: one field store at the top of
ReceivePacket— re-arm_receiveAddress.Sizeto the family maximum before each call. No allocation (the zero-allocation steady-state test still passes).Verified locally:
dotnet build tests/Tests.csproj -c Release(both TFMs, warnings-as-errors, clean) and both test legs, 46/46 each. Caveat stated plainly: this machine has only the .NET 10 runtime, so the net8.0 TFM ran underDOTNET_ROLL_FORWARD=LatestMajor— which is precisely why the defect never showed locally. This PR exists so CI's real .NET 8 proves the fix before it lands on main.