CNA-BUG-162: The phone notification channel and sender never initialise Winsock, cannot detect INVALID_SOCKET and have no Windows test
Evidence basis: source-verified at the pinned commit; inferred from the source (the behaviour was not run). 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.
modules/phone calls no WSAStartup, compares the unsigned SOCKET with zero and names no Winsock library, and its socket tests are compiled out on WIN32, so on Windows Open and SendAsync work only if something else initialised Winsock.
- Identifier
CNA-BUG-162- Category
- Bug
- Subsystem
- Networking & gamer services
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Medium (a triage suggestion, not a project priority)
- Evidence basis
- Inferred (strong): follows from the code, but the behaviour was not run
- Tests touching this area
- None
- Affected contract
- HttpNotificationChannel::Open() and RawPushNotificationMessage / ToastPushNotificationMessage::SendAsync on Windows
Expected behaviour
CNA builds the notification path for Windows on purpose: cmake/UnitTests.cmake (WINNATIVE-0014) says “The channel ITSELF is built on Windows ... this excludes the test's POSIX listener, not the feature”, and CNA's native-Windows plan records two compile fixes in these files. Winsock requires WSAStartup before socket or getaddrinfo; CNA's own Inspector socket layer calls it for exactly that reason.
Actual behaviour at TARGET
No file under modules/phone calls WSAStartup; among CNA's own sources only the Inspector's InternalSocket.cpp does (besides the vendored ENet's initialisation). In a process where neither ran, socket() fails with WSANOTINITIALISED. Because socket_t is the unsigned SOCKET, listener < 0 is never true: Open goes on to setsockopt and bind on INVALID_SOCKET, logs “could not listen for notifications” and returns with no URI, and SendAsync fails at getaddrinfo and returns false. Even with Winsock initialised, connection < 0 in Listen never detects a failed accept, so the worker passes INVALID_SOCKET to recv, send and closesocket before re-checking listening_; Post has the same comparison. modules/phone/CMakeLists.txt names no ws2_32; CNA's CMake links it only for cna_inspector and ENet.
Source locations
modules/phone/src/HttpNotificationChannel.cpp— Open (listener < 0 check), Listen (connection < 0 check); no WSAStartupmodules/phone/src/PushNotificationSender.cpp— Post (getaddrinfo, connection < 0 check); no WSAStartupmodules/phone/CMakeLists.txt— links no Winsock import librarymodules/inspector/src/InternalSocket.cpp— the one WSAStartup among CNA's own sources, for comparisoncmake/UnitTests.cmake— WINNATIVE-0014 exclusion of HttpNotificationChannelTests.cpp under WIN32
Evidence
Checked by reading the two phone sources, the module's CMake file and cmake/UnitTests.cmake at 009d40f5, and by searching CNA's sources and CMake files for WSAStartup and ws2_32; the two phone sources and the module's CMake file are unchanged since an earlier review revision, and cmake/UnitTests.cmake changed since then only outside its WINNATIVE-0014 exclusion. Not executed: no Windows host was used. The start-up failure rests on Winsock's documented initialisation rule. Whether an executable that links CNA::Phone without the Inspector or ENet links at all on Windows was not established.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
HttpNotificationChannelTests.cpp, which holds both the channel and the sender suites, is removed from the test sources under WIN32 because its test client uses POSIX socket headers. Only PhoneApplicationServiceTest runs in a Windows CnaTests; the Winsock path has no test on any host.
Regression test
A Windows test (a Winsock client, or a small cross-platform socket shim for the existing client) that opens a channel in a process that has not initialised Winsock and posts to it. The fix pairs a reference-counted WSAStartup/WSACleanup inside the module, as InternalSocket.cpp does, with == INVALID_SOCKET checks and an explicit ws2_32 link.
Blast radius
Windows builds (native, and MinGW under Wine) of phone ports that use push notifications. PhoneApplicationService and POSIX hosts are unaffected. A process that already initialised Winsock (CNA networking started, the Inspector enabled, or host code) avoids the start-up failure but keeps the INVALID_SOCKET handling defects.
Workaround
Call WSAStartup(MAKEWORD(2, 2), &data) in the host before opening a channel or sending, and link ws2_32 explicitly.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- Platform Support: Windows
- Known issues
- Bug index