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
| Architecture | Numéro | ABI | Point d'entrée |
|---|---|---|---|
| x64 (x86_64) | 43 | common | sys_accept |
| ARM64 (aarch64) | 202 | — | sys_accept |
Historique noyau
Introduit dans Linux 1.0.
1.0
accept() est présent dans Linux depuis 1.0 avec la sémantique BSD.
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) = 4strace 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é).