Repository navigation
Conversation
…ge (T41) While the bridge holds a virtual address, plain AF_INET datagram sockets bound to the wildcard, the virtual address or a broadcast address (or sending before a bind) are carried as virtual LAN datagrams to the net service, and sceNetCtlGetInfo shows the virtual interface. Inactive means the host path as before.
12 tasks done
added 3 commits
October 28, 2026 17:16
…t first binds (T41) - A socket bound on the host while a session is active no longer sends to a broadcast or virtual address on the real network: those sends and connects fail with ENETUNREACH and multicast is dropped. - Two threads sending first on one unbound socket bound it twice and leaked a virtual port; the member socket is now bound once and a lost race leaves its group again. - Leaving a shared port removes one membership, not every entry of it. - Clearing SO_REUSEADDR or SO_REUSEPORT takes effect again. - The bind request to the net service no longer holds the lock the forwarder and every send take. - Tests: host sockets during a session, cleared reuse options, SO_REUSEPORT sharing, concurrent first sends, sceNetRecvmsg vectors, truncation and sender name; two waits in the existing tests that raced the fake service.
…allel runs do not clash (T41)
hypermoist
marked this pull request as ready for review
October 28, 2026 05:33
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.
Handed over to @hypermoist for T41; built, fixed and tested locally (below).
What
The engine side of the virtual LAN (bridge protocol, Broadcasts and the virtual LAN). Everything is behind the bridge's virtual address (
state.address != 0and a connected net service); with no session the host path is exactly as before.sceNetCtlGetInfoshows the virtual address (code 14),255.254.0.0(15), no gateway (16) and MTU 1200 (3) while a session is active. The virtual interface is also reported when the host has none.AF_INETSOCK_DGRAMsocket bound to0.0.0.0, the virtual address or a broadcast address, or one that sends/connects before a bind, is carried through the net service. Per virtual port one loopback group socket is registered withbind; sends leave through it with the 8-byte header, and a small forwarder thread copies each delivered datagram to every game socket on that port (soSO_REUSEADDR/SO_REUSEPORTsharing binds once and delivers to all). Port 0 takes a free virtual port, andgetsocknameshows the game's port.255.255.255.255and198.19.255.255needSO_BROADCAST(elseEACCES) and go out as broadcast frames;198.18.0.0/15unicast goes to that peer; multicast is dropped without an error; every other destination fails at once withENETUNREACH. A socket that stays on the host during a session (bound to a real or loopback address, or bound before the session) does not send to a broadcast or virtual address either: such a send or connect fails withENETUNREACH, and its multicast is dropped. Nothing is ever sent to the host network.connect/send/getpeernamework on these sockets and a connected socket only hears its peer.recv,recvfrom,recvmsg).net_bridge_lanagainstFakeNetServicecovers broadcast out (both addresses, noSO_BROADCAST, multicast, off-subnet), broadcast in, unicast, an inactive session (before and after), the interface answers, bind to the virtual address, ephemeral and implicit binds, connect, shared ports withSO_REUSEADDRandSO_REUSEPORT, a cleared reuse option, host sockets during a session, two first sends at once on one unbound socket, andsceNetRecvmsg(vectors,MSG_TRUNC, sender name).docs/dev/debt/libSceNet.md.Spec questions this design settles
198.19.255.255because the interface netmask is255.254.0.0.sceNetCtlGetInfo(the call seen at boot) is answered.sceNetGetIfList*andsceNetConfigGetIfaddrstill throw (not implemented today) and stay open.Still open
127.0.0.0/8or before the session started stay on the host (their broadcast and virtual sends fail, see Out); IPv6 sockets are untouched.libSceNet/Export.cpp(observation hook); whichever lands second mergesmainand resolves it.Tested
Built and run locally on Linux and on Windows (MinGW cross build, run under Wine), commit
5ede8a54d,mainmerged in.ctest -R 'net|bridge|^public_headers' --timeout 120passes, 124 of 124 that run;bridge_e2e_gameskips as designed without a live net service.net_bridge_lanalso passed 30 runs in a row and 16 runs 8 at a time.libSceNet.prx,libSceNetCtl.prxand every net/bridge test built.net_bridge_lan,net_bridge_p2p,net_bridge,guest_net_ctland the rest pass (net_bridge_lanpassed 50 serial runs).guest_sce_netandnet_ipv6only_patchedfail under Wine on unchangedmainsources too, so they are not from this PR.public_headers_compile_0hit its 30 s limit on a cold first run and passes when run alone.SO_REUSEADDR, the host-socket guard, the fix for two first sends at once,MSG_TRUNCinsceNetRecvmsg, theSO_BROADCASTcheck, and connected-peer filtering.test_public_headers.py --audit-onlyandtools/check_conventions.pypass.Fixed while testing: host sockets could still send broadcasts to the real network during a session; two threads sending first on one unbound socket bound it twice and leaked a virtual port (they could also fail with
EINVAL); leaving a shared port dropped every membership of that socket; a cleared reuse option stayed set; the bind request held the lock that the forwarder and every send need.Checklist
main; no other open PR implements the same functionsNotImplemented_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)Need help on this PR? Tag
@codesmith-botwith what you need.