This page documents the core utility types and concurrency primitives that support the Firestack system. These components provide the foundational infrastructure for connection management, memory efficiency, and thread-safe operations across the networking stack.
Key areas covered include:
Firestack defines several interfaces to abstract network connections beyond the standard net.Conn.
| Interface | Definition | Purpose |
|---|---|---|
DuplexCloser | CloseRead(), CloseWrite() | Supports independent shutdown of read/write streams intra/core/closer.go146-154 |
DuplexConn | TCPConn, DuplexCloser, PoolableConn, KeepAliveConn | The primary abstraction for bidirectional stream sockets. |
RetrierConn | ReadRetrierConn, WriteRetrierConn | Optimized for transparent retry logic and zero-copy transfers intra/core/cp.go35-39 |
MinConn | SetDeadline, Close, LocalAddr | A minimal subset shared by net.Conn and net.PacketConn intra/core/connpool.go163-167 |
ConnMapper | Track, Get, Untrack, Clear | Interface for tracking connections by CID, UID, or PID intra/core/connmap.go32-49 |
The core package provides robust closing utilities in intra/core/closer.go that handle various concrete types (e.g., *net.TCPConn, *gonet.TCPConn from gVisor) using type switches to avoid expensive reflection intra/core/closer.go52-91
Data Flow: Connection Piping
The Pipe function intra/core/cp.go25-49 orchestrates data transfer between a source and destination, prioritizing optimized paths:
WriteRetrierConn or ReadRetrierConn (specific to Firestack's retry logic) intra/core/cp.go35-39io.WriterTo or io.ReaderFrom for zero-copy intra/core/cp.go43-47Stream, which uses a pooled 16KB buffer intra/core/cp.go54-66Sources: intra/core/closer.go1-178 intra/core/cp.go1-98 intra/core/connpool.go163-167 intra/core/connmap.go32-49
Firestack uses a standardized set of async primitives in intra/core/async.go to manage goroutine lifecycles and ensure that panics do not crash the entire process unless explicitly desired.
Go / Go1 / Go2: Runs a function in a goroutine with Recover(DontExit) to log panics but keep the process alive intra/core/async.go30-64Gx / Gx1: Runs a function in a goroutine but uses Recover(Exit11), causing the process to exit on panic—used for critical background workers intra/core/async.go79-101Race: Executes multiple WorkCtx functions concurrently and returns the first non-error result. Panicking functions are treated as errors intra/core/async.go191-237Grx: Runs a work function f in a goroutine, blocking until it returns or a timeout d is reached intra/core/async.go111-135ActiveWorkers: Returns a snapshot of all goroutines currently running inside these helpers for diagnostic purposes intra/core/async.go20-28Firestack integrates trace.FlightRecorder to capture execution traces before a panic. If a goroutine panics, Recover or RecoverFn can capture the recorder's output to a file for post-mortem analysis intra/core/dontpanic.go63-68 intra/core/dontpanic.go123-148
Sources: intra/core/async.go1-237 intra/core/dontpanic.go1-240
SigCond is a lightweight synchronization primitive for one-time state transitions. It transitions from false to true exactly once and cannot be reset. It is used in the retrier and splitter to track if an operation (like a first write) has occurred.
Signalable State Diagram
Sources: intra/core/sigcond.go1-77
The Barrier type intra/core/barrier.go78-94 implements the "single-flight" pattern with an added TTL for result caching. It ensures that only one execution of a specific unit of work (keyed by K) is in-flight at a time.
Do(key, work) simultaneously, the first caller triggers the work while subsequent callers block on a sync.WaitGroup intra/core/barrier.go233-245V struct intra/core/barrier.go47-53 and cached for a configurable ttl.neg duration intra/core/barrier.go112-121maybeScrubLocked to periodically remove expired entries intra/core/barrier.go157-184Natural Language to Code Entity: Barrier Logic
Sources: intra/core/barrier.go1-267
Firestack uses expiring data structures to manage short-lived state like DNS mappings and path MTU estimates.
ExpMap intra/core/expiringmap.go28-40 is a thread-safe map where entries have a TTL. A background reaper goroutine intra/core/expiringmap.go244-277 periodically cleans expired entries. It tracks read hits intra/core/expiringmap.go21-25 for each key.
Sieve wraps ExpMap to provide a simpler cache interface. Sieve2K provides a nested map structure (Map of Maps) where the inner maps are Sieves. This is used for tracking complex state like per-connection or per-UID metadata intra/core/expiringsieve.go1-217
Sources: intra/core/expiringmap.go1-277 intra/core/expiringsieve.go1-217
The ConnMapper interface intra/core/connmap.go32-49 provides a centralized registry for active connections, allowing subsystems to track and terminate connections based on Connection ID (cid), User ID (uid), or Process ID (pid).
Implementation Details:
Track(cid, uid, pid, conns): Associates one or more connections with the given identifiers intra/core/connmap.go108-117Untrack(cid): Closes and removes connections associated with a specific cid intra/core/connmap.go119-127GetAll(uidOrPid): Retrieves all connections belonging to a specific user or process intra/core/connmap.go290-305runtime.AddCleanup to deregister from global metrics when garbage collected intra/core/connmap.go89-90Sources: intra/core/connmap.go1-315
To minimize GC pressure during high-throughput proxying, Firestack implements a slab-based buffer pool in intra/core/buf.go.
The system maintains multiple slabs ranging from 2KB (B2048) to 512KB (B524288) intra/core/buf.go18-38
| Size Constant | Value | Usage |
|---|---|---|
B2048 | 2 KB | Small packets / DNS queries |
B4096 | 4 KB | Standard MTU-sized buffers |
B16384 | 16 KB | TLS Record size (standard for Stream) intra/core/cp.go60 |
B524288 | 512 KB | Large object buffers (LOB) intra/core/buf.go66 |
Allocation Flow:
AllocRegion(size) intra/core/buf.go45 determines the appropriate slabof(size) intra/core/buf.go106*[]byte) from a sync.Pool intra/core/buf.go128-135Recycle(b) intra/core/buf.go71 truncates the slice to zero length and returns it to the pool intra/core/buf.go80-85Sources: intra/core/buf.go1-148 intra/core/cp.go54-66
The Volatile[T] type intra/core/volatile.go13 provides a non-panicking, type-safe wrapper around atomic.Value.
Key Features:
safeLoad(): Returns the zero value of T if the internal value is nil, preventing panics intra/core/volatile.go30-39safeStore(): Ensures that only values of the same concrete type are stored intra/core/volatile.go63-80Tango(): Atomically retrieves the old value and loads in a new one non-atomically intra/core/volatile.go128-136Sources: intra/core/volatile.go1-137
The core package provides MultConnPool intra/core/connpool.go53-58 to manage pools of idle connections keyed by a generic type T.
ConnPool: Manages a channel of agingconn objects intra/core/connpool.go196-205scrub() method intra/core/connpool.go71-107 periodically closes connections that have been idle for more than poolmaxidle (8 minutes) intra/core/connpool.go32Get() verifies aconn.ok() (using syscall.RawConn to check for readability/errors) before returning a connection intra/core/connpool.go253-273Code Entity Mapping: Pooling System
Sources: intra/core/connpool.go1-285
The muxer intra/udpmux.go69-90 facilitates Endpoint-Independent Mapping (EIM) by multiplexing multiple logical connections over a single net.PacketConn.
demuxconn: Represents a virtualized UDP connection that writes to a remote address and reads from the muxer's internal dispatching logic intra/udpmux.go93-113route: Dynamically maps remote addresses to demuxconn instances, allowing incoming packets to be routed to the correct consumer intra/udpmux.go202-246vendor: A callback used to establish new routes in the network stack (e.g., gVisor) when a new remote address is encountered intra/udpmux.go66Sources: intra/udpmux.go1-260
The Scheduler intra/core/sched.go18-24 provides a mechanism for running recurring or delayed jobs with built-in retry logic.
Job: Defines a unit of work with a Run function, an Interval, and a Retry policy intra/core/sched.go26-34Schedule(job): Adds a job to the scheduler's internal loop intra/core/sched.go50-57Retry strategy (e.g., exponential backoff) before the next attempt intra/core/sched.go102-115Sources: intra/core/sched.go1-135
Refresh this wiki