CNA-BUG-267: A join beyond MaxGamers is not refused: the host sends ServerWelcome, AddRemoteGamer throws Session is full!, and the receive path's catch-all drops it, so SessionFull is never raised
Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
HandleClientHello sends ServerWelcome and registers wire ids before AddRemoteGamer checks capacity; the receive path swallows the exception, so an over-capacity client stays connected and NetworkSessionJoinError::SessionFull is never produced.
- Identifier
CNA-BUG-267- Category
- Bug
- Subsystem
- Networking & gamer services
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Medium (a triage suggestion, not a project priority)
- Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- Microsoft::Xna::Framework::Net::NetworkSession::Join on a full host (ENetBackend HandleClientHello, NetworkSession::AddRemoteGamer, NetworkSessionJoinError::SessionFull)
Expected behaviour
A client that joins a session already holding MaxGamers gamers should be refused with a NetworkSessionJoinException carrying NetworkSessionJoinError::SessionFull, the value the XNA API defines for exactly this case, and the host's roster and the other peers should be left alone.
Actual behaviour at TARGET
HandleClientHello rejects only a duplicate handshake and a join in progress that the host forbids. It then creates the joining client's NetworkGamer objects, assigns and registers their wire ids, sends ServerWelcome, and only afterwards calls NetworkSession::AddRemoteGamer, which throws InvalidOperationException(“Session is full!”) once allGamers_ has reached maxGamers_. The receive path wraps the whole message switch in a catch-all that drops the exception, so a bad packet cannot take down Update(). The over-capacity client therefore has been welcomed and stays connected with its wire ids registered, the gamers beyond the limit are never added to the host's roster or announced to the other peers, and SessionFull is produced nowhere in the module (it appears only in the enum header).
Source locations
modules/net/src/Internal/ENetBackend.cpp— HandleClientHello: no capacity check before ServerWelcome; the receive path's catch-allmodules/net/src/Xna/NetworkSession.cpp— AddRemoteGamer throws Session is full! after allGamers_ reaches maxGamers_modules/net/include/Microsoft/Xna/Framework/Net/NetworkSessionJoinError.hpp— SessionFull is declared and never raised
Evidence
Read at 009d40f5; nothing was executed. Found by the C10 conservation reviewer (unit ch51) and re-verified by the orchestrator against HandleClientHello, AddRemoteGamer and the receive path's exception handling. XNA's behaviour is taken from the API it defines (NetworkSessionJoinError::SessionFull), not from a decompiled join path.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
The capacity check in AddRemoteGamer is tested at the session level; no test connects an extra client to a full host and observes what the joiner sees.
Regression test
Start a host with maxGamers 2, connect a third client and expect its join to fail with SessionFull (or the host to disconnect the peer) instead of a welcomed client that the host never rosters.
Blast radius
SystemLink games with a fixed player limit whose lobby can be joined by more clients than the limit: the extra client believes it is in the session while the host ignores it. Sessions that never exceed their limit are unaffected.
Workaround
None in the library; a game can avoid it by checking the discovered session's open public slots before calling Join.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- Internals
- Networking internals
- Deep dives
- Network sessions: limits
- Known issues
- Bug index