agent

package
v0.23.1 Latest Latest
Warning

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

Go to latest
Published: Sep 12, 2026 License: AGPL-3.0 Imports: 37 Imported by: 0

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

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.

func Run

func Run(ctx context.Context, cfg Config) error

Run connects the agent to the relay fabric and blocks until ctx is canceled or the datapath fails: it bootstraps against the seed relay, starts the overlay router, and maintains MinConns concurrent relay sessions from the (optionally refreshed) relay pool.

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.

Jump to

Keyboard shortcuts

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