sync

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package sync maintains the agent's single persistent stream to the control plane and applies versioned desired-state updates in order (ADR-0002, ADR-0015). Every stream starts with Hello and receives a snapshot; deltas follow on the same stream. Each update is applied atomically through the enforce.PolicyStore and acknowledged; a failed apply leaves the last good policy installed and is acknowledged FAILED, after which the control plane sends a fresh snapshot. Reconnects use exponential backoff with full jitter. Persistence of the last applied policy to disk, which makes the agent fail static across restarts (ADR-0011), lands with enforcement behind the same store interface.

Index

Constants

This section is empty.

Variables

View Source
var ErrReconnectDirected = errors.New("sync: reconnect directed")

ErrReconnectDirected is returned when the control plane directs the agent to reconnect immediately.

View Source
var ErrReenrollRequired = errors.New("sync: control plane directed re-enrollment; enroll again with a new provisioning token")

ErrReenrollRequired is returned by Run when the control plane directs the workload to re-enroll. The daemon cannot do that itself: enrollment needs a provisioning token delivered out of band (ADR-0016).

Functions

func Backoff

func Backoff(attempt int, base, limit time.Duration, rng *rand.Rand) time.Duration

Backoff returns the wait before reconnect attempt number attempt (1 for the first retry): a random duration in [0, min(cap, base × 2^attempt)], so that a control-plane restart produces a smooth trickle of handshakes rather than a synchronized wave (ADR-0002).

func DialGRPC

DialGRPC is the production dialer: mutual TLS with the holder's current credential, refreshed at each handshake. The flow reporter dials with it too, on its own connection.

Types

type Config

type Config struct {
	// Server is the control-plane address, host:port.
	Server string
	// Holder presents the workload credential.
	Holder *credential.Holder
	// Store receives each complete policy.
	Store enforce.PolicyStore
	// AgentVersion and Capabilities are reported in Hello.
	AgentVersion string
	Capabilities []string
	// Facts and ListeningServices are collected for Hello and for every
	// inventory report. Either may be nil.
	Facts             func() *innerwallv1.HostFacts
	ListeningServices func() []*innerwallv1.ListeningService
	Log               *slog.Logger
	// BackoffBase and BackoffCap bound the reconnect wait: one second and
	// five minutes when zero.
	BackoffBase time.Duration
	BackoffCap  time.Duration
	// HelloTimeout bounds the wait for HelloAck; 30 seconds when zero.
	HelloTimeout time.Duration
	// Dial replaces the default dialer.
	Dial Dialer
	// Uptime reports the daemon's uptime for heartbeats; measured from
	// New when nil.
	Uptime func() time.Duration
	// DroppedFlowRecords reports the flow records the collection loop has
	// dropped to buffer pressure, carried on every heartbeat. Zero when nil.
	DroppedFlowRecords func() uint64
	// SourceOverruns reports the kernel-side overruns of the flow sources
	// since the agent started, carried on every heartbeat. Zero when nil.
	SourceOverruns func() uint64
	// RenewalError reports the reason the last automatic credential
	// renewal failed, or empty, carried on every heartbeat. Empty when nil.
	RenewalError func() string
	// OwnedTable reads whether the owned firewall table is in the kernel,
	// carried on every heartbeat, so a table removed behind the daemon's
	// back (the local kill switch) is reported within one heartbeat.
	// Unspecified when nil.
	OwnedTable func(ctx context.Context) innerwallv1.OwnedTableState
	// OnSyncConfig is called with the configuration in every HelloAck, so
	// the other loops adopt the control plane's parameters.
	OnSyncConfig func(*innerwallv1.SyncConfig)
	// OnReconnect reports reconnect attempts and their scheduled wait; nil
	// when unused.
	OnReconnect func(attempt int, wait time.Duration)
}

Config configures a Daemon.

type Daemon

type Daemon struct {
	// contains filtered or unexported fields
}

Daemon is the agent's sync loop.

func New

func New(cfg Config) *Daemon

New builds a daemon.

func (*Daemon) Run

func (d *Daemon) Run(ctx context.Context) error

Run maintains the stream until ctx ends, reconnecting with backoff after failures, and immediately upon directed reconnects. Every reconnect is a fresh Hello and snapshot. It returns ErrReenrollRequired when the control plane says so; every other stream error is a reason to reconnect, not to stop.

type Dialer

type Dialer func(ctx context.Context, server string, holder *credential.Holder) (innerwallv1.AgentServiceClient, io.Closer, error)

Dialer opens a connection to the control plane. The default dials gRPC over the holder's TLS configuration; tests substitute a loopback.

Jump to

Keyboard shortcuts

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