Documentation
¶
Overview ¶
Package agent implements the tunnel agent: the client side of the vpc.apoxy.dev relay stack. It owns the shared UDP packet plane (Geneve data + QUIC control on one socket), the overlay datapath (in-process netstack with a SOCKS listener, or a kernel TUN device), and the relay session lifecycle (bootstrap, connection slots, key rotation, watchdog).
It is consumed by the `apoxy alpha tunnel run` command and embedded in-process by services that need a foot in the overlay themselves (e.g. the backplane's VTEP peer, which runs the agent in TUN mode so Envoy can reach overlay destinations by kernel route).
Index ¶
- func DiscoverRelays(ctx context.Context, vpc vpcclient.VpcV1alpha1Interface, ...) (sets.Set[string], error)
- func LivenessHandler(w http.ResponseWriter, _ *http.Request)
- func MatchingRelays(relays []vpcv1alpha1.Relay, network *vpcv1alpha1.VPCNetwork) []*vpcv1alpha1.Relay
- func NewRelayLister(vpc vpcclient.VpcV1alpha1Interface, networkName string) func(context.Context) (sets.Set[string], error)
- func Run(ctx context.Context, cfg Config) error
- type Config
- type ConnectionState
- type ConnectionStatus
- type ConnectionTracker
- func (t *ConnectionTracker) ActiveConnections() int
- func (t *ConnectionTracker) ConnectionClosed()
- func (t *ConnectionTracker) ConnectionOpened()
- func (t *ConnectionTracker) ReadinessHandler(w http.ResponseWriter, _ *http.Request)
- func (t *ConnectionTracker) Ready() bool
- func (t *ConnectionTracker) RequiredConnections() int
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DiscoverRelays ¶
func DiscoverRelays(ctx context.Context, vpc vpcclient.VpcV1alpha1Interface, network *vpcv1alpha1.VPCNetwork) (sets.Set[string], error)
DiscoverRelays lists ready relays whose network selector matches the given network and returns their dialable underlay addresses.
func LivenessHandler ¶ added in v0.23.0
func LivenessHandler(w http.ResponseWriter, _ *http.Request)
LivenessHandler reports that the agent process and admin server are live. The server stops with the agent, so an active handler is sufficient for process liveness and does not depend on relay availability.
func MatchingRelays ¶
func MatchingRelays(relays []vpcv1alpha1.Relay, network *vpcv1alpha1.VPCNetwork) []*vpcv1alpha1.Relay
MatchingRelays filters relays to the ready ones whose network selector matches the given network. A relay with a nil selector serves all networks (per RelaySpec). This is THE definition of "which relays serve a network" — both agent-side discovery (DiscoverRelays) and in-shard consumers that dial relays by other addresses (e.g. the backplane VTEP resolving underlay endpoints) must go through it so their views never diverge.
func NewRelayLister ¶
func NewRelayLister(vpc vpcclient.VpcV1alpha1Interface, networkName string) func(context.Context) (sets.Set[string], error)
NewRelayLister returns a Config.RelayLister that re-fetches the VPCNetwork on every refresh, so relabeling it (which changes which relay selectors match) is picked up without an agent restart.
Types ¶
type Config ¶
type Config struct {
Agent string // agent identifier
Network string // VPC network name
Token string // tunnel auth token
Labels map[string]string // agent-declared labels for VPCService selection
AdvertisedRoutes []string // CIDRs reachable behind this agent, advertised to the relay
Instance string // stable per-process instance UUID
// SeedRelayAddr is the relay dialed for the bootstrap session (host:port).
// Empty means Run picks one at random from SeedRelays; set it only for the
// static single-relay case.
SeedRelayAddr string
// SeedRelays is the initial relay pool. Empty means just SeedRelayAddr.
SeedRelays sets.Set[string]
// RelayLister, when set, is polled to keep the relay pool current; relays
// coming and going are picked up without a restart. Nil = static pool.
RelayLister func(context.Context) (sets.Set[string], error)
// MinConns is the number of concurrent relay connection slots. Values
// below 1 are treated as 1. Ignored when ConnectAll is set.
MinConns int
// ConnectionTracker receives live-session changes from this agent. Run
// creates one when it is nil. Callers that expose readiness must provide a
// tracker and use the same value in their admin handlers.
ConnectionTracker *ConnectionTracker
// ConnectAll maintains one session per relay in the pool instead of
// MinConns slots, tracking pool refreshes. Relay consumers (backplane
// VTEP sessions) need this: relays do not federate routes, so reaching
// agents homed on any relay requires a session to every relay.
ConnectAll bool
// ConnectionObserver receives lifecycle and traffic snapshots for each
// MinConns slot. It is intended for interactive clients and is unused by
// ConnectAll consumers. The callback must return promptly.
ConnectionObserver func(ConnectionStatus)
// SessionObserver receives the same snapshots keyed by relay instead of
// slot. It fires for every session under every connection policy. This
// includes ConnectAll, where ConnectionObserver never fires. Embedding
// consumers such as backplane VTEP sessions use it to track per-relay
// RTT and installed prefixes. The callback must return promptly. Run
// waits for every session goroutine before it returns, so the observer
// never fires after Run returns. Consumers rely on this contract to
// order callbacks across successive runs.
SessionObserver func(ConnectionStatus)
// TLSConfig is used for the QUIC control sessions. Nil means defaults.
TLSConfig *tls.Config
// SocksListenAddr is the SOCKS5 listen address for the netstack datapath.
// Ignored in TUN mode.
SocksListenAddr string
// PcapPath writes a packet capture of the netstack datapath. Not
// supported in TUN mode.
PcapPath string
// TunMode selects the kernel TUN datapath over the in-process netstack:
// the agent creates a TUN device (TunIfaceName) and programs overlay
// addresses/routes on it, so any process in the netns reaches the overlay
// by kernel route. Linux only; requires NET_ADMIN and /dev/net/tun.
TunMode bool
// TunIfaceName names the TUN device created in TUN mode.
TunIfaceName string
// TunNetns, when non-empty, places the TUN device inside this named
// network namespace (created and bind-mounted under /var/run/netns if
// missing). Only sockets created in that namespace reach the overlay,
// giving kernel-level isolation between tenants sharing the process.
// Requires CAP_SYS_ADMIN. Ignored outside TUN mode.
TunNetns string
// AdminPort is denied to traffic that enters through the overlay. This
// keeps an underlay admin listener private even when it binds a wildcard
// address. Zero means that no admin port is reserved.
AdminPort uint16
}
Config holds the agent identity, credential, and datapath configuration for one Run. Agent, Network, Token, and a relay source (SeedRelayAddr or a non-empty SeedRelays) are required.
type ConnectionState ¶ added in v0.22.0
type ConnectionState string
ConnectionState is the client-observed lifecycle state of one desired relay connection. It deliberately carries no primary or failover role: every live relay connection is equivalent at the API layer.
const ( ConnectionStateConnecting ConnectionState = "connecting" ConnectionStateConnected ConnectionState = "connected" ConnectionStateDraining ConnectionState = "draining" ConnectionStateEnded ConnectionState = "ended" )
type ConnectionStatus ¶ added in v0.22.0
type ConnectionStatus struct {
Slot int
Relay string
State ConnectionState
Latency time.Duration
ConnectedAt time.Time
RXBytes uint64
TXBytes uint64
Prefixes []netip.Prefix
Err error
}
ConnectionStatus is a point-in-time view of one relay session. Under the MinConns policy, Slot identifies the connection slot. The slot is stable for the process lifetime. Relay can change when the slot reconnects. Under ConnectAll there are no slots and Slot is -1. RXBytes and TXBytes count from the agent's side. Prefixes is the set of transit prefixes with installed routes for this session. It fills in on the periodic snapshots after the initial route exchange completes.
type ConnectionTracker ¶ added in v0.23.0
type ConnectionTracker struct {
// contains filtered or unexported fields
}
ConnectionTracker records the live relay sessions for one agent process. The required count is immutable so readiness uses the same target as the connection manager for the lifetime of the process.
func NewConnectionTracker ¶ added in v0.23.0
func NewConnectionTracker(required int) *ConnectionTracker
NewConnectionTracker creates a tracker for the requested connection count.
func (*ConnectionTracker) ActiveConnections ¶ added in v0.23.0
func (t *ConnectionTracker) ActiveConnections() int
ActiveConnections returns the current number of live relay sessions.
func (*ConnectionTracker) ConnectionClosed ¶ added in v0.23.0
func (t *ConnectionTracker) ConnectionClosed()
ConnectionClosed records the end of one live relay session.
func (*ConnectionTracker) ConnectionOpened ¶ added in v0.23.0
func (t *ConnectionTracker) ConnectionOpened()
ConnectionOpened records one live relay session.
func (*ConnectionTracker) ReadinessHandler ¶ added in v0.23.0
func (t *ConnectionTracker) ReadinessHandler(w http.ResponseWriter, _ *http.Request)
ReadinessHandler reports whether all requested relay sessions are live.
func (*ConnectionTracker) Ready ¶ added in v0.23.0
func (t *ConnectionTracker) Ready() bool
Ready reports whether the agent meets its configured connection target.
func (*ConnectionTracker) RequiredConnections ¶ added in v0.23.0
func (t *ConnectionTracker) RequiredConnections() int
RequiredConnections returns the connection count required for readiness.