Skip to content

Conversation

henrybarreto
Copy link
Member

No description provided.

@henrybarreto henrybarreto self-assigned this Sep 1, 2025
@henrybarreto henrybarreto requested review from a team as code owners September 1, 2025 20:20
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch 6 times, most recently from 1ac9dfc to 12f001d Compare September 2, 2025 14:22
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch 9 times, most recently from 4c17372 to d2d6431 Compare September 6, 2025 19:04
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch 3 times, most recently from 473e89b to dfb1470 Compare September 8, 2025 16:58
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch from 6df3f30 to 33e6e30 Compare September 9, 2025 11:50
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch 2 times, most recently from 2618c1b to a90cc47 Compare September 19, 2025 18:43
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch from c3d3f74 to ebefc5f Compare September 29, 2025 16:46
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch 2 times, most recently from b8ee206 to 29a42de Compare October 8, 2025 16:32
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch from 29a42de to 6f5aca6 Compare October 9, 2025 13:54
This change replaces the legacy per-connection HTTP/revdial
reverse-tunnel flow with a multiplexed, per-stream protocol (v2) based
on HashiCorp's yamux and multistream-select.

Yamux sessions allow a single agent websocket to host many logical
streams without repeating the HTTP reverse-listen handshake for each
session. Multistream-select provides explicit per-stream protocol
negotiation, making each logical stream's intent (SSH open/close, HTTP
proxy) explicit and versionable. The new approach reduces handshake
overhead and makes future protocol extensions easier and safer.

Over time the legacy reverse-tunnel implementation (per-request
HTTP/revdial) has become a maintenance burden and a performance limiter:
each logical session required a full HTTP handshake and a separate
reverse listener, which increased latency and duplicated logic across
server components. This change replaces that model with a single
multiplexed transport per agent using HashiCorp's yamux, and introduces
explicit per-stream protocol negotiation via multistream-select.

Practically, when an agent connects we now bind its websocket to a yamux
session (Manager.Bind) and keep that session alive with a light ping
loop. Individual logical operations—opening an SSH session, closing it,
or proxying HTTP—are created as yamux streams. Each stream negotiates
its intent using multistream identifiers (`/ssh/open/1.0.0`,
`/ssh/close/1.0.0`, `/http/proxy/1.0.0`) and then exchanges a small JSON
envelope for any parameters. The dialer package centralizes version
handling and prepares connections for callers via DialTo(ctx, tenant,
uid, target), while Target implementations encapsulate the
version-specific bootstrap (legacy HTTP v1 vs yamux+multistream v2).

We kept backward compatibility in mind: the Manager still recognizes
existing revdial-based connections and will return a v1 connection when
appropriate. That lets the system run both v1 and v2 agents concurrently
and supports staged rollouts. I also removed the duplicated tunnel
wiring and replaced it with a focused HTTP sidecar (http) that exposes
both the legacy endpoints and the new v2 bind endpoint; server and
session code now call into dialer.Dialer and Target helpers rather than
performing raw HTTP handshakes.
Updated the tunnel listening mechanism to utilize a configuration loaded
from authentication data instead of the default configuration. This
change enhances flexibility by allowing device-specific settings to be
applied dynamically. The NewConfigFromMap function was added to create a
new configuration from a map, ensuring that default values are used when
specific keys are missing. Additionally, improved error handling during
session creation to attempt a fallback to the default configuration if
the custom one fails.
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch from 6f5aca6 to db8435d Compare October 15, 2025 18:17
…v2 tunnels

This change refactors the agent to support multiple connection protocol
versions, introducing a new configuration option ConnectionVersion to
select between them. Version 1 uses an Echo-based tunnel with HTTP-like
handlers, while version 2 leverages a Yamux-based tunnel integrated with
the client. The agent’s Listen method now delegates to version-specific
listeners, and related handlers were updated accordingly. The tunnel
abstraction was also revised to adopt generics, renaming Handler to
HandlerFunc and splitting out implementations for v1 and v2.
Additionally, reverse listener creation was modernized in the API client
with explicit NewReverseListenerV1 and NewReverseListenerV2 methods,
each with their own configuration management. These changes simplify the
agent’s architecture while allowing incremental migration to the new
tunnel protocol.
@henrybarreto henrybarreto force-pushed the feat/use-multistream-as-mux branch from db8435d to dc25c91 Compare October 15, 2025 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants