Network · Section 2
listen(2)
Mark a socket as passive — ready to accept incoming connections.
Signature
#include <sys/socket.h>
int listen(int sockfd, int backlog);- sockfd
- Socket descriptor, must be of type SOCK_STREAM or SOCK_SEQPACKET and previously bind()ed.
- backlog
- Maximum length of the accept queue. Clamped to net.core.somaxconn. Common values: 128 for small daemons, 1024+ for high-traffic servers.
Description
listen() marks the socket referred to by sockfd as a passive socket, that is, one that will be used to accept incoming connection requests via accept(). backlog defines the maximum length of the queue of pending connections that have completed the TCP three-way handshake but have not yet been accept()ed; if a connection request arrives when the queue is full, the client typically retries (or, with tcp_abort_on_overflow, receives a RST). Listening only makes sense on SOCK_STREAM or SOCK_SEQPACKET sockets. The kernel caps backlog at /proc/sys/net/core/somaxconn (default 4096 on modern kernels), silently. A separate queue of half-open (SYN_RECV) connections is sized by tcp_max_syn_backlog and gated by SYN cookies on overflow.
Architecture mapping
| Architecture | Number | ABI | Entry point |
|---|---|---|---|
| x86 (i386) | 363 | i386 | sys_listen |
| x64 (x86_64) | 50 | common | sys_listen |
| ARM64 (aarch64) | 201 | — | sys_listen |
Kernel history
Introduced in Linux 1.0.
1.0
listen() has been part of Linux since 1.0 with BSD-derived semantics.
4.4
TCP Fast Open (TFO) server support landed; setting TCP_FASTOPEN via setsockopt() makes listen() return a socket that will accept SYN+data in the same packet, saving an RTT on subsequent connections from the same client.
seccomp & containers
Docker default profile
Allowed
Podman default profile
Allowed
listen() is on every default profile. No useful argument-filter knob — backlog values are not security-sensitive. The seccomp filtering happens upstream at socket() (deny AF_PACKET / AF_NETLINK) and at bind() (cgroup BPF for port restrictions). Workloads that should never be a server (one-shot batch jobs, init containers) can deny listen() entirely as a sanity check.
libseccomp
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(listen), 0);strace example
$ strace -e listen nc -l 0
listen(3, 1) = 0listen() in isolation is one-line — its interest is as a phase marker. In a server startup trace you expect socket() → setsockopt(SO_REUSEADDR) → bind() → listen(); a daemon that skips any of these and goes straight to accept() is buggy. -e network captures the entire setup phase.
Security & observability
An unexpected listen() in a workload that should only be a client is a high-signal incident: many backdoor implants open a bind shell here. eBPF tracepoint sys_enter_listen plus correlating sockfd to the originating bind() (cached from sys_enter_bind) gives the listening IP+port immediately — no need to poll ss/netstat. Container runtimes (Falco, Tracee) commonly include 'unexpected listen' rules tied to workload labels. On hardened hosts, /proc/sys/net/core/somaxconn should be set explicitly (not left at distro default) to prevent silent backlog clipping under SYN floods.
Errors
- EADDRINUSE
- Another socket is already listening on the same port.
- EBADF
- sockfd is not a valid descriptor.
- ENOTSOCK
- sockfd does not refer to a socket.
- EOPNOTSUPP
- The socket type does not support listen() (e.g. UDP, raw).