fix(traceroute): route over the default-keyed channel + add channel dropdowns for Traceroute & Node Info (#3696)#3723
Conversation
…slot 0 (#3696) Channel index 0 is only the PRIMARY slot; its PSK can be a private custom key. Hardcoding slot 0 reproduced the original #3696 bug for anyone who gave channel 0 a private key. Resolve the lowest channel whose PSK is the well-known default key (mesh-readable) instead. Also accept an explicit channel override on the traceroute and nodeinfo routes for the UI dropdown. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SJPe6J5vKrcbwzt6vCdtrt
…nfo (#3696) Mirror the existing Exchange Position split-button: a ▾ dropdown (shown when >1 channel exists) lets the user pick the channel for a traceroute or node-info exchange. Backend routes already accept an explicit channel override; this wires the UI through handleTraceroute/handleExchangeNodeInfo. Also add backend tests proving traceroute resolves the default-keyed channel by PSK (not hardcoded slot 0) and honors the dropdown override. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SJPe6J5vKrcbwzt6vCdtrt
|
Claude finished @Yeraze's task —— View job PR Review: fix(traceroute): route over the default-keyed channel + channel dropdowns
|
…ssumption, add edge tests (#3696) - /traceroute now resolves channel directly (valid explicit override wins, else resolveBroadcastChannel) instead of the double-call through resolveDestinationChannel — clearer and one fewer DB read. - Export isValidChannelIndex; document that NULL is the stored unencrypted PSK form ('' handled defensively); include channel count in the warning. - Add traceroute route tests for explicit channel 0 (falsy-trap guard) and out-of-range explicit channel falling back to the default-keyed channel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SJPe6J5vKrcbwzt6vCdtrt
|
Claude finished @Yeraze's task —— View job PR Review: fix(traceroute): route over the default-keyed channel + channel dropdownsTasks:
SummaryThis PR correctly fixes the core issue: traceroute traversability depends on the PSK value (default key), not the slot number. The implementation is clean and the previous review's substantive concerns were all addressed in Backend
The logic in Traceroute route handler — Cleaner than before // meshRequestRoutes.ts:31–33
const channel = isValidChannelIndex(req.body.channel)
? req.body.channel
: await resolveBroadcastChannel(traceManager, databaseService);This is a clear improvement over the original Minor: Extra parentheses (pre-existing, out of scope) Lines like
FrontendDropdown state is not reset when
Actions menu traceroute/nodeinfo don't show channel selection The compact actions menu (lines 1118–1171) calls Test CoverageStrongly improved from the previous version:
One remaining gap: The VerdictThe logic is correct, well-tested, and the core issue is properly solved. The debounce gap in |
|
Thanks for the thorough review — addressed the substantive items in Addressed
Declined (with reasoning)
Full suite green (7463 passed), CI was green on the prior commit; re-running now. |

Summary
Follow-up to #3699 (the original #3696 fix). That PR made traceroutes always use channel index 0, on the premise that "channel 0 is the only channel readable by all nodes." That premise is wrong: channel 0 is merely the PRIMARY slot — its PSK can be a private custom key. Anyone who reconfigured channel 0 with a private key would hit the exact same #3696 symptom (opaque payload → "Unknown" hops), just on slot 0 instead of a secondary slot.
What actually makes a traceroute traversable is the PSK, not the slot number: every intermediate node must be able to decrypt the packet to append itself to the route. The channel the whole mesh shares is the one using the well-known default key (
AQ==), which is what LongFast uses by default.Changes
Backend
resolveBroadcastChannel(manager, db)— resolves the lowest-numbered channel whose PSK is the well-known default key (AQ==) or is unencrypted, i.e. one every node can decrypt. Falls back to channel 0 (with a warning) when no channel is mesh-readable./traceroutenow resolves viaresolveBroadcastChannelinstead of hardcoding0, and accepts an explicitchanneloverride./nodeinfo/requestnow accepts an explicitchanneloverride (default behavior unchanged — still the node's stored channel, so key-repair routes over the shared PSK per project convention).Frontend
▾channel-selection dropdown (shown when more than one channel exists), mirroring the existing Exchange Position control.handleTraceroute/handleExchangeNodeInfotake an optionalchanneland forward it to the backend.Tests
resolveBroadcastChannel: picks the default-keyed channel even when it is not slot 0; treats unencrypted channels as readable; prefers the lowest index; ignores out-of-range indices; falls back to 0 when every channel is private./traceroute: resolves by PSK (not slot 0), honors the dropdown override, falls back to 0 when nothing is mesh-readable./nodeinfo/request: honors the dropdown override.Full suite: 7463 passed, 0 failed.
Closes #3696
🤖 Generated with Claude Code