ipalloc

package
v0.21.0 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

Documentation

Overview

Package ipalloc holds the relay-side, in-process connection address allocators for the vpc.apoxy.dev relay (APO-825 §2.8). A relay leases a /80 block of a network's /72 (one block per relay × network), then sub-allocates per-connection /96 (IPv6) and /32 (IPv4) prefixes from that block with no apiserver round-trip on the connect path.

Conflict-freedom is structural, not lock-based: the /72 is partitioned into 256 disjoint /80 blocks, each leased to exactly one relay, so a relay is the sole allocator within its own block. The single coordination point is the BlockLeaser. Callers must pass the infra-assigned NetworkID; its uniqueness (and thus the disjointness of every /72) is the network provisioner's contract (§2.8), not something this package establishes or checks.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoBlocks is returned when a network's 256 /80 blocks are all leased.
	ErrNoBlocks = errors.New("no available blocks in network")
	// ErrBlockExhausted is returned when a block's 65536 connection /96s are
	// all in use; the caller should lease another block.
	ErrBlockExhausted = errors.New("connection block exhausted")
)

Functions

This section is empty.

Types

type Block

type Block struct {
	// Network is the infra-assigned 24-bit network identifier.
	Network tunnet.NetworkID
	// Index is the block index (0–255), equal to byte 9 of Prefix's address.
	Index uint8
	// Prefix is the /80 block, e.g. fd61:706f:7879:nnnn:nnII::/80.
	Prefix netip.Prefix
}

Block is a /80 child of a network's /72, identified by an 8-bit index that occupies byte 9 of the ULA (the reserved field between the /72 network and the /96 connection). Up to 256 blocks per network, i.e. 256 relays.

type BlockLeaser

type BlockLeaser interface {
	// Lease reserves and returns an unused /80 block of the network's /72, or
	// ErrNoBlocks if all 256 are taken.
	Lease(ctx context.Context, network tunnet.NetworkID) (Block, error)
	// Renew extends a held lease. OSS has no lease TTL, so this is a no-op
	// there; cloud renews the backing infra Endpoint.
	Renew(ctx context.Context, b Block) error
	// Release returns a block to the pool.
	Release(ctx context.Context, b Block) error
}

BlockLeaser hands out /80 blocks of a network /72. The relay holds one lease per (relay × network), renewed on the relay Lease cadence and released at drain (§5). OSS satisfies this from the local system ULA (LocalBlockLeaser); cloud satisfies it from infra-apiz Endpoints (step-4 ticket) — same seam.

type ConnAllocator

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

ConnAllocator sub-allocates per-connection addresses from a single leased /80 block, entirely in-process (§2.8). It is the sole allocator within its block, so no cross-process coordination is needed; a mutex guards the two bitmaps against concurrent connect/disconnect.

Each connection gets a /96 (IPv6, always) and a /32 (IPv4, best-effort). The v4 pool is smaller than the v6 pool by design: v4 is egress-only, so v4 exhaustion degrades a connection to v6-only rather than failing it. The v4 /18 is keyed on block index alone, so it intentionally overlaps across networks — safe because v4 never leaves its per-network forwarding domain and the shared zone is AAAA-only (§2.2/§2.4).

func NewConnAllocator

func NewConnAllocator(b Block) *ConnAllocator

NewConnAllocator returns an allocator over a leased block.

func (*ConnAllocator) Allocate

func (a *ConnAllocator) Allocate() (v6 netip.Prefix, v4 netip.Prefix, err error)

Allocate returns a connection's /96 and, best-effort, its /32. A zero-value (invalid) v4 prefix means the block's v4 pool is exhausted and the caller should run the connection v6-only. ErrBlockExhausted means the v6 pool is full; the caller should lease another block (see Full).

func (*ConnAllocator) Full

func (a *ConnAllocator) Full() bool

Full reports whether the v6 pool is exhausted, i.e. the caller must lease another block to accept more connections.

func (*ConnAllocator) Release

func (a *ConnAllocator) Release(v6, v4 netip.Prefix)

Release returns a connection's addresses to the block's pools. A zero-value prefix for either family is ignored (e.g. a v6-only connection).

type LocalBlockLeaser

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

LocalBlockLeaser is the OSS/single-tenant BlockLeaser. It leases /80 blocks from the standalone process's own view of each network's /72 ULA — there is no infra tier, so blocks are backed by an in-process go-ipam per network and leases have no TTL (Renew is a no-op). The API is identical to the cloud infra-apiz implementation so the relay wiring is the same in both modes.

func NewLocalBlockLeaser

func NewLocalBlockLeaser(ctx context.Context) *LocalBlockLeaser

NewLocalBlockLeaser returns a LocalBlockLeaser. ctx bounds the lifetime of the per-network go-ipam instances it lazily creates.

func (*LocalBlockLeaser) Lease

func (l *LocalBlockLeaser) Lease(_ context.Context, network tunnet.NetworkID) (Block, error)

Lease reserves an unused /80 block of the network's /72.

func (*LocalBlockLeaser) Release

func (l *LocalBlockLeaser) Release(_ context.Context, b Block) error

Release returns a block to the network's pool.

func (*LocalBlockLeaser) Renew

func (l *LocalBlockLeaser) Renew(_ context.Context, _ Block) error

Renew is a no-op: local leases have no TTL.

Jump to

Keyboard shortcuts

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