Documentation
¶
Overview ¶
Package socket owns the daemon's Unix-domain-socket listener, the per-OS peer-credential capture, and the length-prefix message framing.
ADR-0010 specifies SOCK_SEQPACKET, but macOS does not support SEQPACKET on AF_UNIX (only SOCK_STREAM and SOCK_DGRAM). Phase 1 uses SOCK_STREAM uniformly on Linux and macOS with a 4-byte big-endian length prefix per frame. Peer credentials are still reliably retrievable on stream sockets via SO_PEERCRED (Linux) / LOCAL_PEERCRED + LOCAL_PEEREPID (macOS), so the transport simplification does not affect the trust model. A follow-up issue should amend ADR-0010 to record the per-OS transport types.
Index ¶
Constants ¶
const MaxFrameSize = 1 << 20
MaxFrameSize caps a single emitter frame at 1 MiB. Larger frames are rejected outright so a misbehaving emitter cannot exhaust the daemon's memory by claiming an arbitrary length prefix.
Variables ¶
This section is empty.
Functions ¶
func WriteFrame ¶
WriteFrame writes one length-prefixed frame to w. Exposed so the daemon's own integration tests (which dial the listener as if they were emitters) don't reimplement the wire encoding. This package is daemon-internal, so Phase 2 emitter SDKs in other modules cannot import it directly — they reimplement the same encoding (4-byte big-endian length prefix, MaxFrameSize cap), which is documented in daemon/README.md so the wire form stays canonical across implementations.
io.Writer's contract permits short writes with a nil error. A short write would corrupt framing for the receiver, so writes are looped until all bytes are sent or an error is returned.
Types ¶
type Frame ¶
Frame pairs the JSON payload an emitter sent with the OS-attested peer cred captured at accept time. Handler receives one Frame per emitter message.
type Handler ¶
Handler processes a single frame. Implementations MUST be safe for concurrent use (the listener invokes Handler from many connection goroutines). A returned error is logged via the listener's ErrorLog but is otherwise non-fatal — the connection stays open for subsequent frames.
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Listener wraps a net.UnixListener with peer-cred capture and length-prefix framing. Construct via Listen, drive via Serve, stop via Close.
func Listen ¶
Listen binds a SOCK_STREAM Unix-domain listener at opts.Path and returns it ready to Serve. The caller must call Close to release the socket file.
type Options ¶
type Options struct {
// Path is the socket path. Required. The parent directory is created with
// 0750 if missing. Any pre-existing socket file at Path is removed first
// (a stale socket from a previous run is the common case).
Path string
// Handler is called for each received frame. Required.
Handler Handler
// ErrorLog logs non-fatal errors (handler errors, malformed frames). When
// nil, errors are silently discarded.
ErrorLog func(format string, args ...any)
}
Options configure a Listener.
type PeerCred ¶
type PeerCred struct {
// Platform discriminates which fields are populated. One of
// "linux", "darwin". A future Windows port will introduce additional
// values and fields (user_sid, integrity_level).
Platform string
// PID is the connecting process's process id. Signed because POSIX pid_t
// is signed (and -1 is a valid sentinel).
PID int32
// UID, GID are POSIX credentials. uid_t and gid_t are unsigned 32-bit on
// every platform we support, so widen-and-format via uint64 to preserve
// the full range — narrowing into int32 here would wrap UIDs above
// 2^31 to negative values and corrupt the recorded peer.
UID uint32
GID uint32
// ExePath is the absolute path to the connecting process's executable,
// or "" when the daemon could not resolve it. On Linux this is read from
// /proc/<pid>/exe; on macOS via the SYS_PROC_INFO(PROC_PIDPATHINFO)
// syscall (the call libproc's proc_pidpath() wraps). Failure is
// non-fatal — the daemon still records pid/uid/gid.
ExePath string
}
PeerCred is the OS-attested identity of a connecting emitter, captured at accept() time before any frame is read. The agent's self-asserted identity in the frame body is untrusted; this is what makes the audit meaningful.