protocols/rssi: clamp peer-advertised connection parameters#1246
protocols/rssi: clamp peer-advertised connection parameters#1246ruck314 wants to merge 1 commit into
Conversation
The RSSI SYN/SYN-ACK handshake adopted the peer's advertised parameters verbatim. An out-of-range peer value (zero outstanding segments, zero timeouts, a sub-header-size segment, or a window larger than the locally offered maximum) could drive the controller into illegal state -- for example curMaxBuffers == 0 makes the applicationRx outbound wait loop spin forever. Add Controller::clampPeerParams() and apply it in stateClosedWait() after the peer parameters are adopted, clamping to the locally legal range rather than rejecting the connection. This preserves backward/forward compatibility with conformant peers (including SLAC firmware, which never advertises invalid parameters) while hardening against a malformed SYN. Mirrors the firmware validPeerParams/clampWindowSize/clampBufferSize checks in surf protocols/rssi/v1/rtl/RssiConnFsm.vhd. Add a doctest covering the clamp helper (cpp-core, no-python), wired into the existing tests/cpp ctest suite.
There was a problem hiding this comment.
Pull request overview
Hardens the rogue RSSI controller by clamping peer-advertised connection parameters (maxBuffers, maxSegment, and the three timeouts) to the locally legal range during SYN/SYN-ACK handshake. This is defense-in-depth parity with surf#1427's firmware-side validation, preventing pathological states such as curMaxBuffers == 0 causing the applicationRx() wait loop to spin forever. The clamp logs a warning rather than tearing down the connection, preserving compatibility with conformant peers.
Changes:
- Add static
Controller::clampPeerParams()helper and invoke it fromstateClosedWait()between peer parameter adoption and timer conversion. - Add doctest-based unit tests covering the no-op path and each clamp branch (zero/oversized buffers, sub-header/oversized segment, zero timeouts, all-at-once).
- Wire the new test directory through
tests/cpp/protocols/CMakeLists.txt.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| include/rogue/protocols/rssi/Controller.h | Declares the new static clampPeerParams() helper with detailed doxygen. |
| src/rogue/protocols/rssi/Controller.cpp | Implements clampPeerParams() and calls it in stateClosedWait() after adopting peer SYN fields. |
| tests/cpp/protocols/rssi/test_param_clamp.cpp | New doctest suite exercising each clamp branch and the conformant no-op case. |
| tests/cpp/protocols/rssi/CMakeLists.txt | Registers the new test target with cpp-core/no-python labels. |
| tests/cpp/protocols/CMakeLists.txt | Adds the rssi subdirectory to the protocols test build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Closing this for now (reviewing whether the feature is needed before moving forward) |
Summary
Hardens the rogue RSSI endpoint by clamping peer-advertised connection parameters to the locally legal range during the SYN/SYN-ACK handshake. This is defense-in-depth parity with the firmware-side validation added in surf #1427 (
RssiConnFsm.vhdvalidPeerParams/clampWindowSize/clampBufferSize).Controller::stateClosedWait()previously adopted the peer's advertised parameters verbatim. An out-of-range peer value could drive the controller into illegal state — most concretely,curMaxBuffers == 0makes theapplicationRx()outbound wait loop (while (txListCount_ >= curMaxBuffers_)) spin forever. The newController::clampPeerParams()clamps in place:curMaxBuffers_[1, locMaxBuffers_]curMaxSegment_[HeaderSize(8), locMaxSegment_]curCumAckTout_,curRetranTout_,curNullTout_>= 1Clamp, not reject — the connection is never torn down, preserving backward/forward compatibility with conformant peers. SLAC firmware never advertises invalid parameters (and
surf#1427makes the FW self-clamp), so in practice this only engages against a malformed/buggy peer, where it now logs a warning instead of hanging.Testing
tests/cpp/protocols/rssi/test_param_clamp.cpp(doctest,cpp-core/no-python) exercises every clamp branch plus the no-op case for legal input. Auto-run by the existingctest -L cpp/-L no-pythonCI steps — no workflow changes needed.ctest -L cpp(13/13) andtests/integration/test_rssi_loopback.py(4/4) pass — the loopback negotiates legal parameters, so the clamp is a verified no-op on the happy path (behavior identical topre-release).cpplintclean on changed files.Context: audit of surf#1427
This change came out of an audit of surf#1427 (RSSI RTL fixes + cocotb regression suite). Findings:
RssiAxiLiteRegItf,RssiConnFsm,RssiCore,RssiMonitor,RssiRxFsm,RssiTxFsm) are valid by analysis and narrow. rogue's RSSI C++ is byte-identical topre-releaseand requires no functional change to interoperate — the new strict FW receiver plus rogue's existing out-of-order buffering recover from every gap scenario via retransmit.RssiRxFsmregistered-RAM payload length/timing rewrite in that PR is its highest-risk change and is worth confirming on hardware before merge.Deferred: Candidate 2 (NULL-while-data-outstanding suppression) — intentionally not done
surf#1427 also makes the FW suppress NULL while its transmit buffer is non-empty (
RssiTxFsm). A symmetric change in rogue (suppress NULL whiletxListCount_ > 0) was evaluated and deliberately deferred as high-risk / no-reward against currently deployed firmware:stateOpen()), which refreshestxTime_, so the ~333 ms NULL timer never fires anyway. Suppression changes nothing here.RssiRxFsmis strict (drops duplicate/out-of-order) and rogue's receiver buffers out-of-order correctly.Recommendation: revisit Candidate 2 once surf#1427 firmware is widespread in production. At that point the FW's periodic BUSY-ACK behavior (also added in #1427) makes the parity change low-risk to roll out.
Checklist