Repository navigation
Ignore reserved binary IDs 2-3 and honour psk_category (spec #289, #284) - #300
Merged
chrisuthe merged 2 commits intoOct 6, 2026
Merged
Conversation
The 1.0.0-rc1 spec lists only an orig_type of 1 as a malformed fragment sequence; ids 2 and 3 are "reserved for future use", and a receiver MUST ignore binary messages whose id it does not implement, fragmented or not. Drop them at dispatch so a top-level frame and a reassembled message are both ignored and the connection stays open.
Message 1 carries a psk_category (lt | pr | sn) alongside psk_id. Read it, treat a code outside the three as a malformed inner payload (silent failure), and resolve only among PSKs of the declared category, so a psk_id held under a different category is a lookup miss. The test servers now declare the category of the PSK they initiate with.
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation consistently enforces category-aware PSK lookup and reserved-ID handling with appropriate regression coverage.
Review effort: Balanced
Findings: None
What changed in this PR
Updates Noise transport handling to conform to Sendspin 1.0 reserved-message and PSK-category rules.
Changes:
- Ignores reserved binary IDs 2–3, including fragmented messages.
- Parses and enforces
psk_categoryduring PSK resolution. - Updates test servers and coverage for category mismatches and reserved IDs.
| File | Description |
|---|---|
src/Sendspin.SDK/Connection/Noise/NoiseWireFraming.cs |
Handles reserved IDs and PSK categories. |
src/Sendspin.SDK/Connection/Noise/NoisePsk.cs |
Extends resolver contract with category matching. |
src/Sendspin.SDK/Connection/Noise/PairingRecordStore.cs |
Filters PSK records by category. |
tests/Sendspin.SDK.Tests/Connection/TestNoiseServer.cs |
Emits configurable PSK categories. |
tests/Sendspin.SDK.Tests/Connection/NoiseWireFramingTests.cs |
Tests category validation and mismatches. |
tests/Sendspin.SDK.Tests/Connection/FragmentationConformanceTests.cs |
Tests ignored reserved IDs and fragments. |
tests/Sendspin.SDK.Tests/Connection/DisabledPairingMethodPskTests.cs |
Updates pairing-category test handshakes. |
tests/Sendspin.SDK.Tests/Client/FakeServer.cs |
Propagates PSK category in test connections. |
tests/Sendspin.SDK.Tests/Client/SendspinHostServiceArbitrationTests.cs |
Declares pairing credentials correctly. |
tests/Sendspin.SDK.Tests/Client/SendspinClientServicePairingTests.cs |
Updates resolver invocation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two "ignore, do not fail" rules from
Sendspin/specat1.0.0-rc1(671a34d). Both audit rows were re-read against the tag and the code before changing anything; both were real gaps.Reserved binary IDs 2 and 3 are ignored (Sendspin/spec#289)
dce5302and3033587(both in #294) closed the connection on a top-level ID 2/3 and on a fragment whoseorig_typeis 2/3. The tag asks for neither: IDs 2–3 are "reserved for future use", and the malformed list names onlyorig_type1.NoiseWireFraming.DispatchMessagenow drops types 2 and 3. Single frames and reassembled messages both go through it, so one check covers both, and nothing reachesBinaryMessageReceived.HandleFragmentrejects onlyorig_type1. A reservedorig_typereassembles under the existing size caps and is dropped at its last fragment, so the sequence is still tracked and the malformed-sequence rules still apply.psk_categoryis honoured (Sendspin/spec#284)The client read only
psk_id. It now readspsk_categorytoo, fails silently on a missing or unknown code, and passes the category toINoisePskResolver.Resolve, which matches only records of that category. A category miss takes the existing miss path: Sentinel Fallback on the initial handshake, fatal on a re-handshake.Breaking behaviour
psk_categoryfrom Noise message 1, or sends a code other thanlt/pr/sn, no longer completes a handshake.aiosendspin10.0.0 sends it (noise/driver.py), so the shipped server is unaffected.psk_idunder a non-sncategory now gets a miss (fallback on the initial handshake, fatal on a re-handshake) rather than a match.INoisePskResolveris internal; no public API changes.Notes
server/activate". The framing layer does not know about activation and drops IDs 2/3 at any point in transport mode; the server is not permitted to send them before activation anyway.orig_type's fragment data without buffering (a MAY). This buffers and drops, reusing the existing reassembly path and its caps.MIGRATION-10.0.0.mdstill says IDs 2 and 3 are "no longer sent or accepted". Left as is: they are still never surfaced.TestNoiseServer,FakeServer) now declare a category:snwhen naming the Sentinelpsk_id,ltotherwise, with an override the Pairing PSK tests set topr.Verification
dotnet build: 0 errors.The +3 are the new
psk_categorytests. The reserved-ID tests were rewritten in place (same count).Interop against
aiosendspin[server]==10.0.0(tools/interop/run.sh):unpaired,pairingandstatic-pinall PASS. Between them they coversn,pr, and theltre-handshake. They were run on ports other than the script's 8931, which another local run was holding.playerand the other scenarios were not run.