Skip to content
/linux-syscalls

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

ArchitectureNumberABIEntry point
x86 (i386)363i386sys_listen
x64 (x86_64)50commonsys_listen
ARM64 (aarch64)201sys_listen

Kernel history

Introduced in Linux 1.0.

  1. 1.0

    listen() has been part of Linux since 1.0 with BSD-derived semantics.

  2. 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)                            = 0

listen() 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).

Related syscalls