Skip to content

Follow-ups: MSVC /WX, no asserts on network input (fuzz-debug), 12 loopback suites onto the simulated network - #77

Open
Segfaultd wants to merge 6 commits into
masterfrom
chore/followups
Open

Segfaultd wants to merge 6 commits into
masterfrom
chore/followups

Conversation

@Segfaultd

@Segfaultd Segfaultd commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Follow-ups to #76. This covers three of the four open points; clang-format comes next as its own PR.

1. MSVC: zero /W4 warnings, /WX in CI

The Windows job already built with /W4 but treated warnings as non-fatal. The 25 warnings in MafiaNet's own code are fixed:

  • five 64→32-bit Time/TimeMS assignments in peer.cpp made explicit;
  • a local that shadowed a ReliabilityLayer member, renamed;
  • byte truncations in the tests made explicit.

C4251 (std::atomic members of exported classes) is disabled for our targets only. Windows now builds with MAFIANET_WARNINGS_AS_ERRORS, so every CI job except the oldest-toolchain Docker one treats warnings as errors.

2. Asserts reachable from the network

A new fuzz-debug preset builds the harnesses in Debug, so a RakAssert reached through crafted input is reported as a crash. The nightly workflow now runs both fuzz and fuzz-debug. Running it found three asserts that any connected peer could trigger against a Debug build. The first two inputs were already dropped in Release:

  • "Couldn't read all the data": a packet claims more data than its datagram carries.
  • "Hole count too high": a peer jumps its message numbering far ahead.

The third was also a bug in Release: an internal-only message id (ID_CONNECTION_ATTEMPT_FAILED) sent by a remote hit RakAssert(0) in Debug. In Release it leaked the message and stopped processing the rest of that peer's queue until the next update. Now it's freed and skipped.

All three are now dropped without asserting. They're covered by corpus reproducers and a SimulatedPeer test.

The libFuzzer targets now define _DEBUG the same way the library does. Without that, a Debug harness put a ReliabilityLayer with the wrong layout on its stack, and ASan reported a stack overflow on every input.

3. Loopback scenarios moved onto the simulated network

12 integration files that tested protocol behaviour only are now deterministic unit tests on SimulatedNetwork:

  • connect/disconnect, with and without canceled pending attempts;
  • the connection limit, dropped connections and the 8-peer mesh;
  • simultaneous cross-connects;
  • ReliableOrdered;
  • disconnect reasons;
  • MTU negotiation;
  • offline messages, ping, and the 24-test session-config suite.

Every old assertion is covered, and several are stronger:

  • ping statistics are exact (a fixed 20 ms link gives exactly 42 ms), replacing a latency threshold that flaked on loaded machines;
  • session-config gating is checked after every 1 ms update instead of being sampled from another thread;
  • "never connected" / "never delivered" checks cover the whole scenario, not just a window after a sleep;
  • new cases: MTU under a path ceiling, ReliableOrdered under loss and jitter, and the connection limit checked on every tick.

34 integration tests remain, for what genuinely needs real sockets or threads: the socket layer and batching, binding, local addresses, threaded dispatch, plugins over loopback, and stress. The unit suite has 323 tests and runs in under a second. SimulatedNetwork gains StartConnect.

One test-mode quirk is documented on SetManualUpdate. In manual-update mode, Shutdown() flushes with one update, and that update sends nothing if the clock hasn't moved since the previous one. A real clock always moves.

Verification

  • macOS Debug: 357/357.
  • macOS Release: the unit suite passes.
  • Linux GCC 13, Debug and Release, -Werror: 357/357 each.
  • Linux ASan+UBSan and TSan: unit and integration pass, with zero sanitizer reports in any attempt.
  • Windows with /WX: green on a workflow_dispatch run of this branch.
  • Migrated suites: pass 50 repeats.
  • One build-type dependence fixed: a migrated ping test also counted keep-alive pings in Release, because the default timeout is 30 s in Debug and 10 s in Release. The test now pins the timeout.

Summary by CodeRabbit

  • Bug Fixes

    • Connection processing now continues after an invalid connection-failure packet, so subsequent valid packets can still be handled.
    • Malformed or excessively delayed reliable-message packets are dropped without triggering debug assertions.
    • Session handshake timestamps are recorded with explicit time conversions.
  • Documentation

    • Clarified when shutdown’s final flush sends a notification and how to account for this when using a test clock.
    • Added guidance for the Debug fuzzing preset.
  • Tests

    • Expanded simulated-network coverage for connections, message delivery, session handshakes, ping statistics, and disconnect notifications.

The Windows job already compiled MafiaNet's targets with /W4 but non-fatal.
The 25 warnings in our own code are fixed:
- five 64-bit Time -> 32-bit TimeMS assignments in peer.cpp made explicit
  (the value is compared with GetTimeMS(), so 32-bit is intended);
- a local in ReliabilityLayer shadowing the splitPacketId member, renamed;
- test-side message-id-to-char truncations made explicit, and two
  shadowed names renamed.
C4251 (std::atomic members of exported classes have no DLL interface) is
disabled for our targets: expected for a C++ DLL used with the same
toolset. Warnings from fetched dependencies and samples are not ours and
stay at their own levels.
Connection lifecycle, reliability, MTU negotiation, ping, offline messages,
disconnect reasons and the session-config suite tested protocol behaviour
only, so they now run as deterministic unit tests on SimulatedNetwork
instead of real UDP with wall-clock waits. Every assertion of the old
integration files is covered, and several are stronger:
- ping statistics are exact (fixed link delay) instead of a latency
  threshold that flaked on loaded machines;
- session-config gating is checked after every 1 ms update instead of
  sampled racily from another thread;
- negative checks ("never connected", "never delivered") cover the whole
  scenario, not a window after a sleep;
- MTU negotiation is also tested under a path ceiling, ReliableOrdered
  under loss and jitter, and connection limits on every tick.

The 12 integration files are deleted; 34 integration tests remain for what
needs real sockets or threads (socket layer and batching, binding, local
addresses, threaded dispatch, plugins over loopback, stress). The unit
suite (322 tests) runs in under a second.

SimulatedNetwork gains StartConnect (start an attempt without stepping).
The manual-update Shutdown flush sends nothing when the clock has not moved
since the last update; documented on SetManualUpdate (test mode only). The
TSan suppression for the deleted loopback SlotInspector is gone.
The new fuzz-debug preset builds the harnesses in Debug, so a RakAssert a
remote can reach through crafted input aborts and is reported. Two did, in
ReliabilityLayer, reachable by any connected peer against a Debug build:
- "Couldn't read all the data": a packet claiming more data than its
  datagram carries;
- "Hole count too high": a peer jumping its message numbering far ahead.
Both inputs were already dropped in Release; now Debug drops them too.
Three reproducers join the peer_datagram corpus.

The libFuzzer targets now mirror the library's _DEBUG definition like the
replay targets do; without it, a Debug harness stack-allocated a
ReliabilityLayer with the wrong layout. The nightly fuzz workflow runs
both presets.
…king it

A connected peer sending ID_CONNECTION_ATTEMPT_FAILED (generated locally
only) hit RakAssert(0) in Debug. In Release the receive loop zeroed its
size and continued without freeing the message, leaking it and leaving the
rest of that peer's queue for the next update. It is now freed and the loop
moves on. Found by the peer_datagram fuzzer with asserts enabled; covered
by a SimulatedPeer test and a corpus reproducer.
- PingTests.OccasionalPingIsObservableAsPingTraffic counted keep-alive
  pings too in Release: the keep-alive fires every half timeout, and the
  default timeout is 30 s in Debug but 10 s in Release. Pin the timeout.
- Brace single-assertion if bodies: gtest macros expand to if/else, and
  GCC's -Wdangling-else (fatal under -Werror) flags them.
@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1a87fdb2-4253-426f-83b6-cbafdddf0eaa
📥 Commits

Reviewing files that changed from the base of the PR and between 006d369 and 1429ad9.

📒 Files selected for processing: 48
  • .github/workflows/build.yml
  • .github/workflows/fuzz.yml
  • CLAUDE.md
  • CMakePresets.json
  • Source/include/mafianet/peer.h
  • Source/src/peer.cpp
  • Source/src/reliability_layer.cpp
  • Tests/Fuzz/CMakeLists.txt
  • Tests/Fuzz/corpus/peer_datagram/regress-debug-assert-1
  • Tests/Fuzz/corpus/peer_datagram/regress-debug-assert-2
  • Tests/Fuzz/corpus/peer_datagram/regress-debug-assert-3
  • Tests/Fuzz/corpus/peer_datagram/regress-internal-id-from-remote
  • Tests/Integration/ComprehensiveConvertTests.cpp
  • Tests/Integration/CrossConnectionConvertTests.cpp
  • Tests/Integration/DirectoryDeltaTransferStreamingLiveTests.cpp
  • Tests/Integration/DisconnectReasonTests.cpp
  • Tests/Integration/DroppedConnectionConvertTests.cpp
  • Tests/Integration/EightPeerTests.cpp
  • Tests/Integration/LocalIsConnectedTests.cpp
  • Tests/Integration/MTUNegotiationTests.cpp
  • Tests/Integration/MaximumConnectTests.cpp
  • Tests/Integration/OfflineMessagesConvertTests.cpp
  • Tests/Integration/PacketAndLowLevelTests.cpp
  • Tests/Integration/PeerConnectDisconnectTests.cpp
  • Tests/Integration/PeerConnectDisconnectWithCancelPendingTests.cpp
  • Tests/Integration/PingTestsTests.cpp
  • Tests/Integration/ReliableOrderedConvertedTests.cpp
  • Tests/Integration/SessionConfigLiveTests.cpp
  • Tests/Support/SimulatedNetwork.cpp
  • Tests/Support/SimulatedNetwork.h
  • Tests/Support/TestHelpers.cpp
  • Tests/Unit/CrossConnectionConvertTests.cpp
  • Tests/Unit/DisconnectReasonTests.cpp
  • Tests/Unit/DroppedConnectionConvertTests.cpp
  • Tests/Unit/EightPeerTests.cpp
  • Tests/Unit/MTUNegotiationTests.cpp
  • Tests/Unit/MaximumConnectTests.cpp
  • Tests/Unit/OfflineMessagesConvertTests.cpp
  • Tests/Unit/PeerConnectDisconnectTests.cpp
  • Tests/Unit/PeerConnectDisconnectWithCancelPendingTests.cpp
  • Tests/Unit/PingTestsTests.cpp
  • Tests/Unit/RakVoiceRelayTests.cpp
  • Tests/Unit/ReliableOrderedConvertedTests.cpp
  • Tests/Unit/SessionConfigSimulatedTests.cpp
  • Tests/Unit/SimulatedPeerTests.cpp
  • ci/tsan.supp
  • cmake/MafiaNetHelpers.cmake
  • docs/getting-started/building.rst
💤 Files with no reviewable changes: 13
  • Tests/Integration/ReliableOrderedConvertedTests.cpp
  • Tests/Integration/DisconnectReasonTests.cpp
  • ci/tsan.supp
  • Tests/Integration/MTUNegotiationTests.cpp
  • Tests/Integration/CrossConnectionConvertTests.cpp
  • Tests/Integration/EightPeerTests.cpp
  • Tests/Integration/PeerConnectDisconnectWithCancelPendingTests.cpp
  • Tests/Integration/PingTestsTests.cpp
  • Tests/Integration/PeerConnectDisconnectTests.cpp
  • Tests/Integration/MaximumConnectTests.cpp
  • Tests/Integration/OfflineMessagesConvertTests.cpp
  • Tests/Integration/DroppedConnectionConvertTests.cpp
  • Tests/Integration/SessionConfigLiveTests.cpp

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The pull request changes peer receive handling, adds simulated-network test coverage, removes several live integration test files, and updates compiler-warning and fuzzing CI configuration.

Changes

Peer runtime handling

Layer / File(s) Summary
Peer packet handling and regression coverage
Source/include/mafianet/peer.h, Source/src/peer.cpp, Tests/Unit/SimulatedPeerTests.cpp
The receive loop skips ID_CONNECTION_ATTEMPT_FAILED packets and continues with queued packets. Session-handshake timestamps use explicit casts. A regression test checks that a forged identifier does not block a valid payload. The SetManualUpdate comment describes when shutdown’s final flush sends nothing.
Reliability receive and fragment handling
Source/src/reliability_layer.cpp
The receive path removes assertions for excessive message gaps and truncated payloads while retaining existing drop handling. Split-packet paths use a saved fragment ID for reassembly lookup.

Simulated-network test coverage

Layer / File(s) Summary
Simulated-network helpers and test setup
Tests/Support/SimulatedNetwork.*, Tests/Support/TestHelpers.cpp, Tests/Integration/ComprehensiveConvertTests.cpp, Tests/Integration/DirectoryDeltaTransferStreamingLiveTests.cpp, Tests/Integration/LocalIsConnectedTests.cpp, Tests/Integration/PacketAndLowLevelTests.cpp, Tests/Unit/RakVoiceRelayTests.cpp
SimulatedNetwork adds StartConnect, and Connect delegates to it. Several test packet and port assignments now use explicit conversions. A loop variable is renamed; one displayed test assignment is unchanged.
Connection establishment, limits, and churn
Tests/Integration/CrossConnectionConvertTests.cpp, Tests/Integration/DroppedConnectionConvertTests.cpp, Tests/Integration/EightPeerTests.cpp, Tests/Integration/MaximumConnectTests.cpp, Tests/Integration/PeerConnectDisconnect*.cpp, Tests/Unit/CrossConnectionConvertTests.cpp, Tests/Unit/DroppedConnectionConvertTests.cpp, Tests/Unit/EightPeerTests.cpp, Tests/Unit/MaximumConnectTests.cpp, Tests/Unit/PeerConnectDisconnect*.cpp
Simulated tests cover simultaneous connections, dropped connections, peer meshes, connection limits, repeated reconnects, and cancellation of pending attempts. The corresponding integration test files are removed.
Disconnect notifications, offline messages, and ping
Tests/Integration/DisconnectReasonTests.cpp, Tests/Integration/OfflineMessagesConvertTests.cpp, Tests/Integration/PingTestsTests.cpp, Tests/Unit/DisconnectReasonTests.cpp, Tests/Unit/OfflineMessagesConvertTests.cpp, Tests/Unit/PingTestsTests.cpp
Simulated tests check disconnect-reason payloads, offline advertisements and ping responses, and ping statistics and occasional-ping traffic. The corresponding integration test files are removed.
MTU negotiation and reliable-ordered delivery
Tests/Integration/MTUNegotiationTests.cpp, Tests/Integration/ReliableOrderedConvertedTests.cpp, Tests/Unit/MTUNegotiationTests.cpp, Tests/Unit/ReliableOrderedConvertedTests.cpp
Simulated tests cover MTU negotiation, fragmentation and reassembly, connection retries, and reliable-ordered delivery over clean and impaired links. The corresponding integration test files are removed.
Session handshake and lifecycle tests
Tests/Integration/SessionConfigLiveTests.cpp, Tests/Unit/SessionConfigSimulatedTests.cpp, ci/tsan.supp
Simulated tests cover session payloads, handshake decisions and timeouts, traffic gating, pending-session limits, status messages, reconnects, and abandonment. The live integration test file and a ThreadSanitizer suppression are removed.

Build and fuzz CI

Layer / File(s) Summary
Compiler warning configuration
.github/workflows/build.yml, cmake/MafiaNetHelpers.cmake, CLAUDE.md
The Windows build enables warnings-as-errors. MSVC warning C4251 is disabled alongside /W4. The documentation updates the stated CI scope and MSVC warning guidance.
Debug fuzz preset and nightly workflow
CMakePresets.json, .github/workflows/fuzz.yml, Tests/Fuzz/CMakeLists.txt, CLAUDE.md, docs/getting-started/building.rst
The fuzz-debug preset configures Debug builds. The fuzz workflow runs fuzz and fuzz-debug as separate matrix jobs with preset-specific corpus keys and crash artifact names. Debug fuzz targets define _DEBUG, and the documentation describes the preset.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 1429a

This change hardens the handling of malformed or hostile network input by dropping it instead of asserting. It moves protocol-behavior tests onto a deterministic simulated network, adds a Debug fuzzing job, and turns on warnings-as-errors for Windows builds. No concrete correctness, security or availability problem was found in the changed code, so the change looks ready to merge after normal CI.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 45.59% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 136 functions across 24 files. (7 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title accurately summarizes the three main changes: MSVC /WX handling, removing assertions for malformed network input, and migrating 12 loopback suites to SimulatedNetwork. The wording is concise…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title accurately summarizes the three main changes: MSVC /WX handling, removing assertions for malformed network input, and migrating 12 loopback suites to SimulatedNetwork. The wording is concise and specific.

Full details: Docstring Coverage

Explanation

Docstring coverage is 45.59% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 136 functions across 24 files. (7 skipped: 7 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

I’m a rabbit with a test-suite grin,
I hop through packets, out and in.
Debug fuzz seeds now take the stage,
Simulated peers test every page.
I thump my feet: the builds are green!
And nibble carrots in between.

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
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.

1 participant