Draft
Cap header-obfuscation ingress de-mux CPU: source-endpoint fast path + per-drain full-scan budget#177
Conversation
…scan budget (issue #174)
Copilot
AI
changed the title
[WIP] Fix header obfuscation issue in select ingress peer
Cap header-obfuscation ingress de-mux CPU: source-endpoint fast path + per-drain full-scan budget
Jul 10, 2026
This branch has not been deployed
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.
With
obfuscate=on(default), inbound peer selection trialed every configured peer's rx link key (one keyed-Blake2b each) per datagram before dropping unclaimed junk — an off-path attacker sending 36-byte spoofed UDP could amplify each packet intoMAX_PEERSkeyed hashes on the single-threaded reactor (~343 ns/peer, ~1000× the cleartext selector; #174). This implements mitigation options 1+2 from the issue, combined.Changes
src/reactor.zig):selectIngressPeernow takes the datagram's UDP source and trials the peer whose current (learned) endpoint matches it first — address comparisons plus one keyed hash. All steady-state traffic, including previously-roamed peers, resolves in O(1).OBFS_SCAN_BUDGET = 8scans perpumpUdpIngressdrain (refilled per drain). Worst-case unauthenticated CPU is now8 × MAX_PEERSkeyed hashes per drain regardless of flood rate; junk past the budget costs only address comparisons. A roaming peer locked out by a concurrent flood retries next drain, wins a slot, authenticates, and its endpoint is learned back onto the fast path.drop_udp_scan_budgetcounter instats.Counters(auto-reflected into status JSON / Prometheus).docs/PROTOCOL.md§3.4 "Selection under obfuscation" and the §5 obfuscation note now specify the two-stage selection;tools/forward-bench.zigcomments updated (its junk-sweep measurement is now the metered fallback's worst case, i.e. one budget slot).unknown_peer× 8 +scan_budget× overflow), and per-drain refill.Iron-law compliant: zero allocation (one
u32of reactor state), single-threaded lock-free, no handshake. The AEAD gate is unchanged — selection remains a pre-filter hint only.