transport

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

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

View Source
const (
	ALPNRaw = "localport-raw/1"
	ALPNWS  = "localport-ws/1"
)

ALPN identifiers must stay in sync with the edge's agent handler.

View Source
const DefaultPort = "443"

DefaultPort is used when an edge address omits an explicit port. The agent only ever speaks through the HTTPS-friendly port.

View Source
const DefaultWSPath = "/v1/control"

DefaultWSPath is the HTTP path used for the WebSocket upgrade.

Variables

View Source
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

func SplitHostPort(addr string) (host, port string)

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

func DefaultDialers(opts Options) []Dialer

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 Kind

type Kind string

Kind identifies one transport flavor.

const (
	KindRaw Kind = "raw"
	KindWS  Kind = "ws"
)

func (Kind) String

func (k Kind) String() string

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.

func (*RawDialer) Dial

func (d *RawDialer) Dial(ctx context.Context, host, port string) (net.Conn, error)

func (*RawDialer) Kind

func (d *RawDialer) Kind() Kind

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.

func (*WSDialer) Dial

func (d *WSDialer) Dial(ctx context.Context, host, port string) (net.Conn, error)

func (*WSDialer) Kind

func (d *WSDialer) Kind() Kind

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL