Documentation
¶
Overview ¶
Package transport encapsulates how the agent reaches its edge server.
Two carriers, both terminating on the edge HTTPS port and demultiplexed there by SNI + ALPN:
- "raw" runs the wire protocol bytes directly inside a TLS stream. It has the lowest overhead and works through dumb firewalls.
- "ws" carries the same bytes inside binary WebSocket frames, which gets them through DPI and HTTPS-inspecting MITM proxies.
The data plane multiplexes over one HTTP/2 connection to avoid a dial-back per inbound visitor connection. It is NOT a third transport: it reuses whichever of the two above the control connection already established (so it survives the same firewalls), and is distinguished by its first frame (MuxBind), not by an ALPN of its own. See internal/tunnel/mux_session.go.
Index ¶
Constants ¶
const ( ALPNRaw = "localport-raw/1" ALPNWS = "localport-ws/1" )
ALPN identifiers must stay in sync with the edge's agent handler.
const DefaultPort = "443"
DefaultPort is used when an edge address omits an explicit port. The agent only ever speaks through the HTTPS-friendly port.
const DefaultWSPath = "/v1/control"
DefaultWSPath is the HTTP path used for the WebSocket upgrade.
Variables ¶
var ErrNoTransport = errors.New("no transport available: every candidate failed (check edge reachability and firewall)")
ErrNoTransport is returned by Probe when every configured transport failed within the probe budget.
Functions ¶
func SplitHostPort ¶
SplitHostPort splits an edge address into host and port. When the port is missing, DefaultPort is used.
Types ¶
type Dialer ¶
type Dialer interface {
Kind() Kind
Dial(ctx context.Context, host, port string) (net.Conn, error)
}
Dialer opens a new edge connection. Implementations carry transport state (TLS config, WS path) but no per-call mutable state, so Dial is safe to call concurrently for data connections.
func DefaultDialers ¶
DefaultDialers returns the priority-ordered set of dialers: raw first (lowest overhead), then ws (firewall-tolerant fallback).
func Probe ¶
func Probe( ctx context.Context, edgeAddr string, budget time.Duration, dialers []Dialer, logger *slog.Logger, ) (net.Conn, Dialer, error)
Probe walks dialers in priority order. The first one whose TLS handshake plus ALPN negotiation succeeds within the per-attempt budget wins; the caller caches that dialer and reuses it for data dial-backs in the same session.
Probing is single-attempt. Callers that need retries should drive them from a reconnect loop.
type Options ¶
type Options struct {
DialTimeout time.Duration
WSPath string
// ServerName sets the TLS SNI and verification name independently of
// the dial host: dials to a per-edge hostname present the zone's
// connect host instead. Empty derives the name from the dial host.
ServerName string
}
Options collects user-facing knobs for the default dialer set. We keep it deliberately small. There is no insecure-skip-verify and no root-CA override, so nobody can weaken the TLS posture through config.
type RawDialer ¶
type RawDialer struct {
DialTimeout time.Duration
ServerName string // SNI override; empty = derive from dial host
}
RawDialer establishes a TLS connection to the edge with ALPN localport-raw/1 and returns the TLS conn as-is, so wire protocol bytes write straight onto it. TLS 1.3 minimum, full server-cert verification, no insecure escape hatch.
type WSDialer ¶
type WSDialer struct {
DialTimeout time.Duration
Path string
ServerName string // SNI override; empty = derive from dial host
}
WSDialer establishes a WebSocket-over-TLS connection with ALPN localport-ws/1 and returns a net.Conn view of the resulting binary message stream. TLS 1.3 minimum, full server-cert verification.