Skip to content

Match C token lifetime limits and client address selection - #12

Merged
gafferongames merged 6 commits into
sprint/netcode-cs-portfrom
sprint/netcode-cs-port-block-2.w6.g1.e21
Oct 15, 2026
Merged

gafferongames merged 6 commits into
sprint/netcode-cs-portfrom
sprint/netcode-cs-port-block-2.w6.g1.e21

Conversation

@gafferongames

Copy link
Copy Markdown
Contributor

Connection requests now enforce the C reference lifetime limits and a finite preconnect mapping lifetime; clients skip server addresses for which they have no usable socket. The expiry floor also rejects equality, matching C.

Both the parent source read and independent cold review cleared da890bf. The full Linux .NET 8 runner and all ten interoperability legs passed against C 39f04965. The corrected address-selection harness uses no network syscalls, verified with strace. Production clock and transport behavior remain unchanged; fixture floors are adjusted only in tests.

Carried history combined one test with its fix; reconstructed pre-fix runs preserve the red evidence without rewriting that history. Detailed per-subtask report follows.

Head: da890bf
Branch: sprint/netcode-cs-port-block-2.w6.g1.e21
Verdict: LAND (candidate; parent owns publication and second independent cold read)
Gate: Linux nova@hetzner1, /home/nova/stella-netcode-port-e21. dotnet build tests/Tests.csproj -c Release: exit 0, 0 warnings/errors (logs/tests-build-recheck.log). dotnet run -c Release --project tests/Tests.csproj -f net8.0 --no-build: exit 0, "All tests passed" (logs/tests-full-recheck.log). scripts/interop.sh ../c-reference against mas-bandwidth/netcode 39f04965: exit 0, "INTEROP GATE PASSED", including legs 9 and 10 (logs/interop-full-recheck.log). C client-address mode under strace -e trace=network: exit 0, zero network syscalls (logs/client-address-syscalls-final.log). Local and Linux source SHA-256 lists match (logs/local-source-sha256.txt, logs/linux-source-sha256.txt).
Output: repo/ clean at head above; C reference in c-reference/ at 39f049657d6e738e533c751c2b5242fa7b2d4114. No push, PR, merge, or sprint finish.

Report:

  • Current stream base c4da669 is the direct ancestor of carried 3051cd7; no merge needed. The quoted locations shifted with stream work, but the named defects matched. All nine changed files against base are within PATHS. Diff stat: 9 files, 604 insertions, 36 deletions.
  • Subtask 1 (token lifetimes): carried f30d8f3 red test, ae6a97a fix, and 3051cd7 differential mode. On Linux at f30d8f3, test_preconnect_mapping_lifetime failed at tests/ClientServer.cs:1382 (server.NumEncryptionMappings == 0), and test_connection_request_packet failed at tests/Tests.cs:780 (UINT64_MAX refusal). These are this card's defects, not unchanged base failures. Logs: red-subtask1-mapping.log, red-subtask1-request.log. The C differential at red source showed timeout -1 never vs C 11, timeout 0 1/refused vs C 11/connects, and max/plus60/plus31 expiry accepted vs C refused (red-subtask1-lifetimes.log; c-lifetimes.log). Final mode prints five mapping offsets, five response verdicts, and seven expiry verdicts on fixed bytes and explicit timestamps. Its stdout matches C exactly (floor-c-final.log, floor-cs-final.log); full interop leg 9 passes. test_disable_timeout and test_zero_allocation_steady_state pass.
  • The cold review found a base-existing floor boundary mismatch in the same lifetime read path: C refuses expiry equal to the restart floor, while C# used <. A new packet-reader case failed before the one-line fix at tests/Tests.cs:787; the C differential was expiry floor -> refused vs C# accepted (floor-red-unit.log, floor-c.log, floor-cs-red.log). It passes after changing C# to <= (target-floor-green.log and final leg 9). This strict boundary initially made same-second 30-second token session fixtures fail at tests/ClientServer.cs:238 and tests/Hostile.cs:446; those failures were caused by this card's correction. Their test setup now places the fixture floor one second earlier while the packet-reader regression pins the exact production boundary. Full runner passes.
  • Subtask 2 (socket family): carry e4fa521 contained the fix and test together, so it lacked a separate historical red commit. I reconstructed a pre-fix ae6a97a checkout with only test scaffolding and the corrected socketless test. On Linux, test_client_refuses_server_address_without_socket failed at tests/ClientServer.cs:798 (client.State == InvalidConnectToken; red-subtask2-state.log). Its C differential was red for v6-only and v6-then-v4 addresses (red-subtask2-client-address.log). Final unit and C mode compare v6/none, v6v4/1, v4/0, plus v4v6 invalid on a direct next-address transition. Final stdout matches C (client-c-final.log, client-cs-final.log); full interop leg 10 passes.
  • The first client mode used a fake C IPv4 handle while calling netcode_client_update. Cold review correctly found that update drains receives before selecting the next address; netcode_client_connect can also send disconnect packets from a prior pending state. da890bf disconnects with override transport enabled, disables it only around connect from Disconnected, restores it immediately, and calls netcode_client_connect_to_next_server directly for v4v6. The C# test/mode call its now-internal counterpart directly. The final C mode made no network syscalls under strace. The in-memory marker is cleared before destroy.
  • ba5b965 repaired the carried C mode's NULL output-dir abort, wrote the actual private timeout to its encrypted token, counted active mappings rather than high-water slots, covered expiry/response verdicts, made token inputs deterministic, and added C ancestry checks. da890bf adds the reviewer corrections above. Both commits carry By: Stella and Co-Authored-By: GPT-6 Sol trailers.
  • Remaining procedural limitation: the carried attempt committed subtask 2's test with its fix rather than as a prior red commit. The reconstructed red and C differential failures preserve that evidence without rewriting carried history. Cold reviewer tools_removals cleared exact head da890bf after checking the socket-I/O path, strict floor, and Linux trace. The second independent cold read and publication remain with the parent.

rowan-claude and others added 6 commits October 15, 2026 03:12
…nect mappings and never-expiring tokens

TestPreconnectMappingLifetime drives an override-transport server with a timeout -1
token and requires the preconnect mapping to expire after its bounded lifetime, and a
timeout 0 token to survive one update so the response connects. TestConnectionRequestPacket
gains never-expiring and over-long expiry cases that require refusal by a lifetime check.
Both fail at the tip before the fix.

By: opencode
… refuse over-long tokens

A pre-connect encryption mapping now expires at time + (timeout > 0 ? timeout : 10)
instead of never for a negative timeout or immediately for zero, and ReadPacket refuses
a connection request whose expire timestamp is more than max_connect_token_lifetime past
the current timestamp. TestZeroAllocationSteadyState mints a 30-second token now.

By: opencode
… unusable server addresses

A client bound for one address family now skips a server address whose family it has
no socket for, and goes to InvalidConnectToken when no address in the token is usable.
CanReach is the pure decision; TestClientCanReach unit-tests it and
TestClientRefusesServerAddressWithoutSocket covers the state.

By: opencode
… C reference

Adds token-lifetimes and client-address scenario modes to compat/Compat.cs and
compat/c/compat.c, and legs 9 and 10 to scripts/interop.sh, so the preconnect mapping
lifetime and the socket-family refusal can be diffed against the C reference.

By: opencode
Repair both carried interop modes, exercise every token lifetime verdict, and use a socketless family seam for the address cases. Match the C reference when only later server addresses are unreachable.

By: Stella

Co-Authored-By: GPT-6 Sol
Exercise the next-address transition directly in the override harness, keep the fake C family marker away from packet I/O, and refuse tokens whose expiry equals the restart floor. Session fixtures allow a current-second token while the packet-reader test pins the exact floor.

By: Stella

Co-Authored-By: GPT-6 Sol
@gafferongames
gafferongames merged commit 7e2663c into sprint/netcode-cs-port Oct 15, 2026
1 check passed
@gafferongames
gafferongames deleted the sprint/netcode-cs-port-block-2.w6.g1.e21 branch October 15, 2026 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants