This document defines the interoperability contract for the POSIX UDS SEQPACKET baseline transport. All implementations (C, Rust, Go) must follow this contract to interoperate on the same socket.
AF_UNIX / SOCK_SEQPACKET — message-oriented, reliable, ordered,
connection-based Unix domain sockets with preserved message boundaries.
{run_dir}/{service_name}.sock
Example: /run/netdata/cgroups-snapshot.sock
run_diris caller-supplied (typically/run/netdataon Linux)service_nameis the service identity string- The path must not exceed the platform's
sun_pathlimit
UDS SEQPACKET is profile bit 0 (0x01), named UDS_SEQPACKET.
This is the baseline profile — always supported, always available as
fallback.
-
Server: creates and binds the socket, listens for connections. If a stale socket file exists from a dead process, the server unlinks it and recreates. If the socket is actively held by a live process, the server fails with address-in-use.
-
Client: connects to the socket path. The OS delivers a connected SEQPACKET file descriptor.
-
Handshake: immediately after connection, the client sends a HELLO control message and the server responds with HELLO_ACK, as defined in the wire envelope spec. The handshake determines the session profile, directional limits, packet size, and
session_id.The negotiated capacities are fixed for that session. If higher layers later reconnect with larger learned capacities, the next session gets a new
session_idand therefore a new per-session SHM file. -
Data plane: if the negotiated profile is UDS_SEQPACKET (bit 0), all subsequent messages travel over the same SEQPACKET connection. If a higher profile is negotiated (e.g., SHM), the data plane still uses the same UDS connection for control/lifecycle coordination, and successful HELLO_ACK guarantees the SHM resources for that session are already prepared on the server side. If the client later cannot attach SHM locally, it must close that session and reconnect without SHM. There is no same-session fallback.
SEQPACKET has a kernel-imposed maximum message size. The transport
determines its packet size from the socket's SO_SNDBUF option.
The effective packet size for the connection is negotiated during handshake:
agreed_packet_size = min(client_packet_size, server_packet_size)
Both sides use agreed_packet_size for chunking decisions.
If a complete message (32-byte header + payload) exceeds
agreed_packet_size, the sender chunks it:
- First packet: the original 32-byte outer header + as many payload
bytes as fit (up to
agreed_packet_size - 32payload bytes). - Continuation packets: 32-byte chunk continuation header + payload
bytes (up to
agreed_packet_size - 32payload bytes each). - Each packet is sent as one SEQPACKET message (preserved boundary).
- The receiver reads one SEQPACKET message per chunk.
If the complete message fits in one packet, no chunking occurs and no chunk header is used.
See the wire envelope spec for chunk header layout and validation rules.
When the handshake negotiates a SHM profile, the server creates a per-session shared memory region file:
{run_dir}/{service_name}-{session_id:016x}.ipcshm
Where session_id is the server-assigned session identifier from the
hello-ack, formatted as a zero-padded 16-character lowercase hex string.
Each session gets its own SHM region. See the POSIX SHM transport
contract for full region layout and lifecycle details.
The UDS connection remains open for the session lifetime (it carried
the handshake and is used for SHM lifecycle coordination). For SHM
profiles, successful HELLO_ACK means the shared memory region has already
been created for that session. If the client still cannot attach it, the
client must close that session and reconnect baseline-only. If a later reconnect learns
larger capacities, it establishes a new session with a new session_id
and therefore a different SHM file path.
- Server checks if the socket path exists before bind.
- If it exists: attempt to connect to it. If connection succeeds, a live server owns it — fail with address-in-use. If connection fails with ECONNREFUSED or ENOENT, the socket is stale — unlink and recreate. Other connect errors (EACCES, EPERM, etc.) are not treated as stale — the file is left in place and the server fails.
- Server checks the
.ipcshmfile for ownership metadata (PID and generation) stored in the SHM region header. - If the owner PID is alive and the generation matches, the region is active — fail with address-in-use.
- If the owner PID is dead or the region is invalid/undersized, the region is stale — unlink and recreate. If the file cannot be opened due to permission errors (EACCES, EPERM), it is left in place.
- Clients that open an undersized/unpopulated SHM file (server has created it but not yet initialized the header) treat it as a retryable protocol-not-ready condition.