Network · Section 2
connect(2)
Initiate a connection on a socket — TCP handshake, UDP destination set, or AF_UNIX rendezvous.
Signature
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr * addr, socklen_t addrlen);- sockfd
- Socket descriptor (any type that supports connect()).
- addr
- Pointer to a sockaddr_* struct describing the destination.
- addrlen
- Size of the struct (sizeof(struct sockaddr_in) etc.).
Description
connect() initiates a connection on the socket referred to by sockfd to the address specified by addr. For SOCK_STREAM (TCP), this triggers the three-way handshake; the call returns 0 when ESTABLISHED, or -1/EINPROGRESS immediately on a non-blocking socket (with the actual outcome later observable via getsockopt(SO_ERROR) after the socket becomes writable). For SOCK_DGRAM, connect() doesn't generate traffic — it just remembers the remote address so that subsequent send()/recv() calls (without explicit destination) use it, and incoming datagrams from other peers are filtered out. For AF_UNIX, connect() rendezvous with a listening peer at the given path. Clients usually call socket() → (optional bind for source-port pinning) → connect(); skipping bind lets the kernel pick an ephemeral source port.
Architecture mapping
| Architecture | Number | ABI | Entry point |
|---|---|---|---|
| x86 (i386) | 362 | i386 | sys_connect |
| x64 (x86_64) | 42 | common | sys_connect |
| ARM64 (aarch64) | 203 | — | sys_connect |
Kernel history
Introduced in Linux 1.0.
1.0
connect() has been part of Linux since 1.0 with BSD semantics.
4.11
TCP Fast Open client support landed; with TCP_FASTOPEN_CONNECT socket option, connect() can carry application data in the SYN, eliminating one RTT for HTTPS connections to a server that previously sent a TFO cookie.
seccomp & containers
Docker default profile
Allowed
Podman default profile
Allowed
connect() is on every default profile. The most useful hardening is at the destination level: cgroup BPF (BPF_CGROUP_INET4_CONNECT / INET6_CONNECT) can deny connections to specific IPs / ports / sets — used by Cilium and Kubernetes NetworkPolicy to enforce egress rules without iptables. seccomp argument filtering on sockaddr* is technically possible but awkward because the address is read by the kernel from user memory; the cgroup-BPF path is cleaner.
libseccomp
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(connect), 0);strace example
$ strace -e socket,connect curl -s https://example.com -o /dev/null
socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_TCP) = 5
connect(5, {sa_family=AF_INET6, sin6_port=htons(443), sin6_addr=…}, 28) = -1 EINPROGRESSstrace decodes sockaddr fully. EINPROGRESS is benign on non-blocking sockets — chase the subsequent poll/epoll_wait for the real outcome. A connect() that immediately returns ECONNREFUSED is the host-is-up-port-is-not signature; ETIMEDOUT after ~127 s is the firewalled/dropped pattern. Combine with -e network for the full conversation.
Security & observability
connect() is the canonical primitive of data exfiltration and C2 callouts. eBPF tracepoint sys_enter_connect with the decoded sockaddr is the right observation point; pair with /proc/<pid>/exe to attribute. Container EDRs (Falco rule: 'Outbound Connection to C2 Server') match destination IPs against threat-intel feeds at this hook. AF_UNIX connect() to /var/run/docker.sock from a non-root container is the classic 'Docker socket escape' indicator. Reverse-shell payloads typically call socket(AF_INET) → connect() → dup2 to stdin/stdout/stderr → execve('/bin/sh') — the connect to a non-RFC1918 IP from a workload that should only talk to its sidecars is a strong signal.
Errors
- EACCES
- An iptables/nftables rule rejected the outgoing connection; or AF_UNIX path permission denial.
- EADDRINUSE
- —
- EAFNOSUPPORT
- —
- EAGAIN
- —
- EALREADY
- A previous non-blocking connect() is still in progress.
- EBADF
- —
- ECONNREFUSED
- Active reset from the destination — TCP RST in response to SYN, or UDP port unreachable ICMP. The remote host is up but nothing is listening (or a firewall is sending RSTs).
- EINPROGRESS
- Non-blocking socket and the handshake is in flight. Wait for POLLOUT on the fd and check SO_ERROR.
- EINTR
- —
- EISCONN
- Socket is already connected.
- ENETUNREACH
- No route to the destination network. Routing-table problem.
- ENOTSOCK
- —
- ETIMEDOUT
- No response within the kernel's connect timeout (tcp_syn_retries — ~127 s on default Linux). The host is unreachable or filtered.