Documentation
¶
Overview ¶
Package wss implements pkg/daemon/transport.Transport over a WebSocket Secure connection to a Pilot beacon. Used in "compat mode" by daemons running in environments where UDP is impractical (Docker on Render/Railway/Vercel/Lambda, restrictive corp networks).
Wire model:
- The daemon opens ONE long-lived wss:// connection to the beacon.
- TLS is verified against the embedded Pilot root CA (or the OS trust store if -tls-trust=system).
- After upgrade, the daemon completes an Ed25519 challenge so the beacon can authenticate it against the registry's stored pubkey.
- Every Pilot UDP packet the daemon would send becomes one binary WS frame; every inbound binary WS frame becomes one Pilot UDP packet returned by Recv. The beacon transparently relays between UDP peers and WSS peers — see docs/SPEC-compat-mode.md §"Transport matrix".
What this transport intentionally does NOT do:
- No NAT traversal. Compat-mode peers are unreachable for direct UDP by definition; they register with relay_only=true.
- No per-peer flow control. The wssTransport is a pipe to the beacon; Pilot's own L3 reliability layer handles retransmits/ordering on top, identical to today's UDP path.
- No reconnect during graceful shutdown. Close() is final; the read goroutine exits cleanly and the next Recv returns ErrClosed.
Index ¶
Constants ¶
const DefaultDialTimeout = 20 * time.Second
DefaultDialTimeout caps the time we spend on a single dial attempt (DNS + TCP + TLS + WS upgrade + auth challenge). Beyond this we fail fast and let the reconnect loop try again.
const DefaultIdlePingInterval = 30 * time.Second
DefaultIdlePingInterval is how often the daemon pings the beacon to keep the WS connection alive through proxy idle timeouts. 30s is short enough for most corporate proxies (which cull at 60-300s) and long enough not to flood the link.
const DefaultRecvBuffer = 256
DefaultRecvBuffer is the buffered channel size for inbound frames. Sized at 256 to absorb modest bursts without backpressure into the WS read goroutine; the daemon's dispatcher (single Recv consumer) drains it.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// URL is the beacon's WSS endpoint, e.g.
// "wss://beacon-us.pilotprotocol.network/v1/compat".
URL string
// TLSConfig pins the trust store. Production builds use a config
// with RootCAs set to compat.PinnedRoots(); -tls-trust=system uses
// a config with RootCAs=nil so Go falls back to the OS trust
// store. Always non-nil — the caller picks the policy.
TLSConfig *tls.Config
// Identity provides the Ed25519 keypair used for the auth challenge.
Identity *crypto.Identity
// NodeID is the daemon's registered node ID. The auth challenge
// binds the signature to this nodeID so the beacon can look up the
// expected pubkey in the registry.
NodeID uint32
// IdlePingInterval overrides DefaultIdlePingInterval.
IdlePingInterval time.Duration
// DialTimeout overrides DefaultDialTimeout.
DialTimeout time.Duration
// RecvBuffer overrides DefaultRecvBuffer.
RecvBuffer int
}
Config configures a Transport.
type Transport ¶
type Transport struct {
// contains filtered or unexported fields
}
Transport is the daemon-side WSS implementation of transport.Transport. One Transport == one long-lived WSS connection to one beacon.
The Transport is safe for one concurrent reader (Recv) and one concurrent writer (Send), matching the contract today's UDP socket provides to pkg/daemon/tunnel.go.
func Dial ¶
Dial opens a WSS connection to the beacon, completes the Ed25519 auth challenge, and returns a live Transport. Returns a wrapped error if any step fails. Caller is responsible for Close().
func (*Transport) Close ¶
Close shuts down the WSS connection. Idempotent. After Close, the read goroutine exits and subsequent Recv calls return ErrClosed.
func (*Transport) LocalAddr ¶
LocalAddr returns a synthetic local address. Used only in log messages by upper layers. Never nil.