CNA-BUG-250: LocalNetworkGamer::SendData in a Local or LocalWithLeaderboards session silently drops every packet, so neither the sender nor another local gamer ever receives it

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

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.

NetworkSession::Update raises PacketSend events only when real networking is enabled (SystemLink), so SendData in a Local or LocalWithLeaderboards session reports success and delivers nothing, although SendData is documented to reach every gamer in the session, the sender included.

Identifier
CNA-BUG-250
Category
Bug
Subsystem
Networking & gamer services
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (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::LocalNetworkGamer::SendData, ReceiveData and getIsDataAvailableProperty in a NetworkSession of type Local or LocalWithLeaderboards

Expected behaviour

XNA documents LocalNetworkGamer.SendData as sending to all gamers in a session ('This includes the gamer sending the packet') without any session-type qualifier, and describes Local sessions as making it easier to share code between local and online modes; the decompiled SendDataWorker queues every packet regardless of session type. CNA's own LocalNetworkGamer.hpp repeats 'every gamer in the session', known_gaps.md says nothing is missing about Local sessions, and CNA's CLAUDE.md says XNA wins over FNA where they disagree.

Actual behaviour at TARGET

LocalNetworkGamer::SendData enqueues a PacketSend event; NetworkSession::Update in NetworkSession.cpp delivers it only inside if (ENetBackend::RealNetworkingEnabled(sessionType_)), which is true for SystemLink alone (ENetBackend.cpp), so in Local and LocalWithLeaderboards sessions the event is silently dropped, including a packet a local gamer sends to itself or to another local gamer. SendData reports nothing and IsDataAvailable stays false. The drop is deliberate FNA parity, pinned by LocalNetworkGamerTest.SendDataThenReceiveDataRoundtrip and NetworkSessionTypePolicyTest.SendDataStaysFullySyntheticForEverySyntheticType, but no CNA header documents it and known_gaps.md says the opposite.

Source locations

Evidence

Checked by reading at 009d40f5; not executed. XNA's contract is from xna4-spec's NetworkSessionType documentation and the decompiled LocalNetworkGamer (SendDataWorker/SendDataNow have no session-type check). Classified as a functional gap because CNA chose and pins the behaviour; the SystemLink branch already contains the local-target delivery (localTarget->EnqueuePacket) a Local session would need. The network-sessions deep dive states the non-delivery.

Independently observed as a separate finding (merged): NetworkSession::Update delivers queued PacketSend only when real networking is enabled (SystemLink), so SendData between local gamers of a Local session never arrives; PlayerMatch, Ranked and JoinInvited are refused.

Independent re-verification: Checked by reading at 009d40f5; not executed. The XNA contract is from xna4-spec (LocalNetworkGamer.SendData, NetworkSessionType.Local) and the decompiled LocalNetworkGamer, which has no session-type check; the native XNA kernel that routes packets to local recipients cannot be read, so delivery in XNA's Local sessions is inferred from the documented API. Reclassified from functional-gap because the behaviour is silent, undocumented in CNA's headers and contradicts the SendData contract; the SystemLink branch already contains the local-target delivery a fix would reuse.

Focused reproduction

// Illustrative; mirrors LocalNetworkGamerTest.SendDataThenReceiveDataRoundtrip. One signed-in gamer.
NetworkSession* session = NetworkSession::Create(NetworkSessionType::Local, 1, 8);
LocalNetworkGamer* me = session->getLocalGamersProperty()[0];
std::vector<SharpRuntime::bytecs> payload{1, 2, 3, 4};
me->SendData(payload, SendDataOptions::Reliable, me);    // to itself
session->Update();
bool arrived = me->getIsDataAvailableProperty();         // false in CNA

Current tests

LocalNetworkGamerTests.cpp and NetworkSessionTypePolicyTests.cpp assert non-delivery for every synthetic type; SystemLink delivery is covered by ENetBackendTests.cpp and the two-process loopback test.

Regression test

Flip the two tests to expect delivery (a packet sent to a local recipient, or broadcast, arrives after the next Update) once Local sessions route PacketSend through the same local-target branch SystemLink uses.

Blast radius

Split-screen games that use a Local session and SendData/ReceiveData to exchange state between local players, and games that share one networking code path between Local and SystemLink. SystemLink sessions and Local games that send no packets are unaffected.

Workaround

Exchange local players' state directly in game code, or use a SystemLink session for every mode.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Known issues
Bug index