Expand description
Reverse tunnel: A (serve) listens for an external client’s traffic and
for B (connect) to dial in; once B is connected, A multiplexes every
external connection as a yamux stream over the single A<->B link, and B
dials the locally-configured target for each stream it receives.
Wire protocol over the TLS-wrapped control connection:
- B writes a length-prefixed token frame; A replies with one byte,
1(accepted) or0(rejected, connection then closes). - Both sides start yamux on the same connection: A as
Mode::Client(it is the side that opens new streams), B asMode::Server. - For every new external client, A opens a yamux stream and writes a
length-prefixed tunnel-name frame identifying which
[[connect.tunnel]]entry on B should receive it; B reads that frame, resolves the target, and dials it. - B replies with one byte,
1(target connected) or0(dial failed), and the rest of the stream is then piped unmodified. B must send this before any payload: it is what carries yamux’s stream ACK, and without it a target that waits for the client to speak first would leave streams unacknowledged and cap the tunnel at yamux’s 256-stream ack backlog.
Only A’s response direction waits for that byte, because it has to be consumed rather than delivered to the external client. A forwards the client’s request as soon as it arrives; gating that direction too would put a full A<->B round trip in front of every new connection.
Modules§
- connect
- enroll
- Client side of enrollment: trade a single-use code for the credentials of a new tenant.
- serve
- tenant_
serve - Multi-tenant
serve: manyconnectclients, each authenticated by its own token and reached through its own SNI host.