Uh oh!
There was an error while loading. Please reload this page.
Send a stable host id to the relay on host connections - #679
Open
Juan Pablo Acosta (jpablo2002) wants to merge 3 commits into
Open
Send a stable host id to the relay on host connections#679Juan Pablo Acosta (jpablo2002) wants to merge 3 commits into
Juan Pablo Acosta (jpablo2002) wants to merge 3 commits into
Conversation
… tell a host reconnecting to its own tunnel from a different host taking it over.
Matches the C# and TypeScript SDKs so the relay can identify a reconnecting host process.
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Juan Pablo Acosta (jpablo2002)
commented
Sep 4, 2026
ContributorAuthor
/azp run |
|
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command. |
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 freeto 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.
Host connections now send an
X-Tunnels-Host-Process-Idrequest header identifying the host process. The relay uses it to tell a host reconnecting to a tunnel it already holds from a genuinely different host taking that tunnel over.Why
When two hosts race for the same tunnel, each connect evicts the incumbent with
TooManyConnections; the evicted host reconnects, evicts the challenger, and the loop sustains itself, tearing down every live client bridge each time.We need an identity that is stable across a host's own reconnects. Host connections authenticate as
ClientNone, so there is no SSH key on the wire, and the request correlation id is per-connection — a host redialling after sleep/wake or a dropped network would fail to recognize itself. The SDK is the only place that knows the answer, so it sends it explicitly.MultiModeTunnelHost.HostIdis minted once per process and already reported onTunnelEndpoint.HostId, so it's a proven-stable identity.What changed
TunnelRelayStreamFactory.cs) — sets the header fromMultiModeTunnelHost.HostIdwhen the sub-protocol list contains a host sub-protocol. The header name is a new public const,TunnelRelayConnection.HostIdHeaderName.defaultTunnelRelayStreamFactory.ts) — same, fromMultiModeTunnelHost.hostId, on the Node path.relay_tunnel_host.rs) — adds the header to the relay host's WebSocket request, from thehost_idthe host already generates and reports on its endpoint.Only host connections send it; clients are untouched.
Notes
TunnelHeaderNames. That file is the generated contract surface, and generating this into Go/Java would produce a constant nothing can use. It lives next to the three host implementations that actually send it.RelayTunnelHost, not per-process. It's stable across the reconnects the host performs internally, which is the case that matters. A caller that constructs a freshRelayTunnelHoston reconnect gets a new id and is arbitrated as a new host — the same as today's behavior, never worse.Compatibility
Fully backward compatible in both directions. The relay ignores the header when it's absent and treats an unidentified host exactly as it does today, so old SDKs against a new service are unchanged and a new SDK against an older service is a no-op — the header is simply dropped. It's also stripped at web forwarding, so it never reaches a customer's app.
Testing
C# builds clean and the existing suite passes; TypeScript compiles and lints clean. No new unit tests — both suites substitute a mock stream factory, so the default factory this change touches isn't reachable from them.