Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

unix-seqpacket and unix-seqpacket-listen

A local socket that keeps message boundaries and still has a connection and an end of stream. What the peer sent as three messages arrives as three messages, in order, and closing the connection is visible on the other side.

$ tocat - unix-seqpacket:/run/app/app.sock
$ tocat unix-seqpacket-listen:/tmp/tocat.sock,fork,unlink,mode=660 tcp:localhost:8080
$ tocat unix-seqpacket-listen:@tocat 'frame,format=lv32' tcp:collector:9000
OptionDescription
fork, max-connections=NAs tcp-listen. unix-seqpacket-listen only
unlinkRemove a stale socket before binding. unix-seqpacket-listen only
mode=NNNOctal permissions applied after binding, explicitly, so umask does not mask them. unix-seqpacket-listen only
backlog=NKernel accept queue depth. Default is 1024. unix-seqpacket-listen only
name=TEXTLabel for logs and dumps. Default unix-seqpacket://path

Both forms take linger, recv-buffer and send-buffer from the shared socket options, and on the listening form they apply to every accepted connection. The TCP options are refused: a unix socket has no Nagle’s algorithm, no keepalive and no address to hold in TIME_WAIT.

unix-seqpacket also takes the resilience options. reconnect=keep is refused here: it needs an endpoint that opens a two-way byte stream, and this one carries messages.

The scheme is also spelled unix-seqpkt, uds-seqpacket and seqpacket, with -listen on the end for the listening form.

Choosing it over unix

Both are local sockets between processes on one machine, and the difference is what a read gives you back.

unix is a byte stream: what arrives is whatever the kernel had ready, so a protocol carried over it needs framing of its own, and tocat’s frame plugin exists for that. unix-seqpacket carries the boundaries for you. If the peer speaks a message protocol, this is the endpoint that stops you inventing a framing layer to recover what the sender already knew.

That also changes what a pipeline may do. A seqpacket endpoint is a message endpoint, so the same rules apply to it as to udp: a stage that does not preserve boundaries draws a warning when the destination on its path is one of these, and a stage that needs boundaries arriving is satisfied by one. See Datagrams.

The buffer is the message ceiling

One receive is one message, and a message longer than the copy buffer is truncated, with the rest lost. Unlike UDP the kernel says so, and tocat warns once per connection:

$ tocat -b 1KiB unix-seqpacket:/run/app/app.sock -
WARN a message did not fit the buffer and the rest of it is lost; raise -b past
the largest message the peer sends

Further truncations on the same connection are logged at debug, so a flood does not bury the rest of the log. The default buffer is 256 KiB.

Ending

A seqpacket connection has a real end of stream, which is what separates it from unix-dgram and from UDP. When tocat has nothing further to send it half closes the connection, so a peer waiting for that before it replies gets what it is waiting for, and one-way transfers finish on their own:

$ tocat file:messages.bin unix-seqpacket:/run/app/app.sock

The reverse arrives as an ordinary end of stream too, so hash digests, rate summaries and compress epilogues are all produced.

One consequence worth knowing: a zero-length message and a peer shutdown look the same at the receiving end, so sending an empty message ends the path.

Peers under fork

A connected unix socket has no address, so accepted connections are all labelled unnamed, the same as a unix-listen client that never bound. Each one still gets its own plugin instances and its own dialled peer.

Addresses

Paths and abstract names both work, and the rules for unlink, mode and cleanup are the same as for unix.