The transport layer provides mechanisms for HTTP-over-tunnel communication in the webteleport/relay system. It consists of three main components: the RoundTripper function that creates http.Transport instances over tunnel.Session connections, the MetricsTransport wrapper that collects HTTP traffic statistics, and protocol-specific upgraders that establish initial connections.
This page documents how HTTP requests are tunneled through various network protocols (WebSocket, TCP, QUIC) using these transport mechanisms.
The transport layer bridges HTTP semantics and underlying network protocols through a layered architecture:
Transport Layer Component Stack
The RoundTripper function in transport.go12-24 creates the transport chain, MetricsTransport in metrics.go24-28 wraps it for observability, and protocol upgraders establish the underlying tunnel.Session connections that the transport layer uses.
Sources: transport.go1-25 metrics.go1-152 verbose.go1-28
The RoundTripper function creates an http.Transport configured to send HTTP requests over tunnel.Session connections.
RoundTripper Function Implementation
The function is defined in transport.go12-24 It accepts a tunnel.Session and returns an http.RoundTripper that uses that session for all HTTP connections.
Sources: transport.go12-24
The function creates a custom DialContext closure transport.go13-17 that:
expvars.WebteleportRelayStreamsSpawned countertssn.Open(ctx) to create a new stream over the tunnel sessionVerboseConn struct for debuggingnet.ConnThis allows the standard http.Transport to use tunnel streams as if they were regular network connections.
Sources: transport.go13-17
The http.Transport instance transport.go18-22 is configured with:
| Field | Value | Purpose |
|---|---|---|
DialContext | Custom closure | Opens streams via tssn.Open(ctx) |
MaxIdleConns | 100 | Limits connection pool size |
IdleConnTimeout | 90 seconds | Cleans up idle connections |
Sources: transport.go18-22
The VerboseConn struct verbose.go9-11 wraps net.Conn and optionally logs read/write operations when the VERBOSE_CONN environment variable is set.
VerboseConn Read/Write Methods
The Read method verbose.go13-19 and Write method verbose.go21-27 delegate to the underlying connection and log the byte count and data content when verbose logging is enabled.
Sources: verbose.go9-27 transport.go16
The final step wraps the transport in NewMetricsTransport transport.go23 which adds HTTP traffic statistics collection. See the Metrics Transport section below for details.
Sources: transport.go23
The MetricsTransport struct wraps an http.RoundTripper to collect HTTP traffic statistics.
MetricsTransport Structure
Sources: metrics.go10-28
The TransportStats struct metrics.go11-22 tracks:
| Field | Type | Description |
|---|---|---|
BytesSent | int64 | Total bytes sent in requests |
BytesReceived | int64 | Total bytes received in responses |
RequestCount | int64 | Number of requests initiated |
ResponseCount | int64 | Number of responses received |
FailedRequests | int64 | Number of failed requests |
ActiveRequests | int64 | Current number of active requests |
TotalRequestDuration | time.Duration | Cumulative request duration |
LastRequestTime | time.Time | Timestamp of most recent request |
MaxRequestDuration | time.Duration | Longest request duration observed |
MinRequestDuration | time.Duration | Shortest request duration observed |
Sources: metrics.go11-22
The NewMetricsTransport function metrics.go91-99 creates a new MetricsTransport instance. If the provided wrapped parameter is nil, it defaults to http.DefaultTransport.
Sources: metrics.go91-99
The RoundTrip method metrics.go102-141 implements the http.RoundTripper interface:
RoundTrip Execution Flow
Sources: metrics.go102-141
The wrapBody function metrics.go76-88 wraps request and response bodies to count transferred bytes. It handles both io.ReadCloser and io.ReadWriteCloser cases:
io.ReadWriteCloser: Returns metricsReadWriteCloser metrics.go65-73io.ReadCloser: Returns metricsReadCloser metrics.go55-62These wrappers use metricReader metrics.go31-40 and metricWriter metrics.go43-52 to increment byte counters during I/O operations.
Sources: metrics.go31-88
The MetricsTransport implements JSON marshaling methods:
MarshalJSON metrics.go144-146: Returns JSON representation of StatsMarshalJSONIndent metrics.go149-151: Returns indented JSONThese methods serialize the TransportStats object, not the entire transport, making metrics easy to expose via HTTP APIs.
Sources: metrics.go144-151
Protocol upgraders establish initial connections and create tunnel.Session instances. The relay server uses multiple upgrader types.
| Upgrader | Package | Function | Listen Type |
|---|---|---|---|
websocket.Upgrader | github.com/webteleport/webteleport/transport/websocket | newWebsocketUpgrader | webteleport.Listen |
tcp.Upgrader | github.com/webteleport/webteleport/transport/tcp | newTcpUpgrader | net.Listen |
The newWebsocketUpgrader function cmd/relay/ws.go12-23 creates a WebSocket upgrader:
WebSocket Upgrader Initialization
Implementation details cmd/relay/ws.go12-23:
webteleport.Listen(context.Background(), addr) to create a listenerwebsocket.Upgrader with RootPatterns set to the hosthttp.Serve in a goroutine to handle WebSocket upgradesSources: cmd/relay/ws.go12-23
The newTcpUpgrader function cmd/relay/tcp.go9-19 creates a TCP upgrader:
TCP Upgrader Initialization
Implementation details cmd/relay/tcp.go9-19:
net.Listen("tcp", ":"+port) to create a TCP listenertcp.Upgrader with the listener and RootPatterns set to the hostSources: cmd/relay/tcp.go9-19
Both upgraders are configured with RootPatterns fields:
RootPatterns []string: List of host patterns that the upgrader should acceptSources: cmd/relay/ws.go19 cmd/relay/tcp.go16
The transport layer includes comprehensive debugging capabilities through the VerboseConn wrapper and metrics collection.
VerboseConn Debugging Flow
The VerboseConn struct in verbose.go9-27 wraps any net.Conn and provides optional logging of all read and write operations. When the VERBOSE_CONN environment variable is set, it logs:
Key debugging features:
VERBOSE_CONN environment variable is setnet.Conn interface compatibilitySources: verbose.go9-27 transport.go14-16
The transport layer uses carefully tuned configuration parameters to optimize performance across different network conditions:
| Parameter | Value | Purpose |
|---|---|---|
MaxIdleConns | 100 | Connection pool size limit |
IdleConnTimeout | 90 seconds | Idle connection cleanup |
DialContext | Custom function | Stream-based dialing over tunnels |
These settings in transport.go18-22 balance connection reuse with resource management, ensuring efficient HTTP transport over tunnel sessions while preventing connection leaks.
Sources: transport.go18-22
Refresh this wiki