Skip to content
/linux-syscalls

Réseau · Section 2

accept(2)

Récupère la prochaine connexion en attente sur la file d'une socket à l'écoute.

Signature

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr * addr, socklen_t * addrlen);
sockfd
Descripteur de socket à l'écoute (préalablement listen()ée).
addr
Si non-NULL, le noyau y écrit la sockaddr du pair. Caster selon la famille (sockaddr_in pour INET, sockaddr_in6, sockaddr_un, …).
addrlen
Pointeur sur socklen_t. En entrée : taille du tampon. En sortie : taille réelle de l'adresse (peut être plus grande — adresse tronquée alors).

Description

accept() extrait la première connexion en attente dans la file d'une socket à l'écoute et retourne une nouvelle socket connectée — un descripteur distinct utilisable comme n'importe quel autre. La sockfd à l'écoute reste inchangée et continue d'accepter d'autres connexions. Si la file est vide et la socket bloquante, accept() bloque ; non bloquante elle retourne -1/EAGAIN. L'adresse du pair est écrite dans *addr / *addrlen si non-NULL — addr peut être NULL si on s'en moque. Préférer accept4() à accept() en code neuf : il permet de positionner SOCK_CLOEXEC et SOCK_NONBLOCK atomiquement à l'accept, éliminant une fenêtre de course de fuite de fd à travers execve().

Numéros par architecture

ArchitectureNuméroABIPoint d'entrée
x64 (x86_64)43commonsys_accept
ARM64 (aarch64)202—sys_accept

Historique noyau

Introduit dans Linux 1.0.

  1. 1.0

    accept() est présent dans Linux depuis 1.0 avec la sémantique BSD.

  2. 2.6.28

    accept4() a été ajouté avec des flags explicites (SOCK_CLOEXEC, SOCK_NONBLOCK) afin que l'appelant les positionne atomiquement sur la nouvelle socket, supprimant la course qui imposait un fcntl() séparé.

seccomp & conteneurs

Docker default profile

Autorisé

Podman default profile

Autorisé

accept() / accept4() sont dans tous les profils par défaut. Comme pour les autres appels socket, pas de filtre d'arguments utile — les filtres amont socket() et bind() définissent la surface. Pour les charges qui ne devraient jamais être serveur (init containers, jobs batch), refuser accept() / accept4() côté seccomp est un petit ceinture-bretelles au-dessus du refus de listen().

libseccomp

seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept),  0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), 0);

Exemple strace

$ strace -e accept,accept4 nc -l 127.0.0.1 1234
accept4(3, {sa_family=AF_INET, sin_port=htons(57338), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_CLOEXEC) = 4

strace affiche l'adresse du pair décodée (sin_port, sin_addr). Pour un serveur récalcitrant, un accept() long sans retour est un motif coincé-sur-EAGAIN-sans-poll ; un taux ECONNABORTED élevé pointe vers des échecs de poignée TLS côté client. -e network filtre la famille.

Sécurité & observabilité

accept() retournant de nouvelles sockets connectées est le point d'entrée canonique de tout trafic réseau entrant. Le tracepoint eBPF sys_exit_accept se déclenche avec le nouveau fd ; corréler à la sockaddr du pair (du même appel) donne une attribution instantanée de chaque connexion — utilisé par Falco, Tracee et la plupart des EDR conteneurs. Les attaques par épuisement de fd (famille 'slowloris') affament la boucle accept ; surveiller le taux de retour EMFILE / ENFILE est le canari. La course double-close-on-accept des années 2000 sur les serveurs multi-threadés est atténuée en utilisant systématiquement accept4(SOCK_CLOEXEC).

Erreurs

EAGAIN
Socket non bloquante et aucune connexion en file. Attendre via poll/epoll POLLIN avant de réessayer.
EBADF
—
ECONNABORTED
Connexion en file annulée avant accept() (client RST ou timeout).
EINTR
Interrompu par un signal avant l'arrivée d'une connexion.
EINVAL
—
EMFILE
Limite par processus de fd atteinte — cause classique d'un 'serveur qui n'accepte plus' sur hôte chargé. Relever RLIMIT_NOFILE.
ENFILE
Limite système de fd atteinte.
ENOTSOCK
—
EOPNOTSUPP
—
EPERM
—
EPROTO
Erreur niveau protocole (ex. ratés type TLS quand un module d'offload noyau est impliqué).

Syscalls liés