Skip to content

Sockets

stachu edited this page Jun 7, 2018 · 7 revisions

Basics

TCP/UDP connection is identified by so called 5-tuple:
(protocol, source address, source port, destination address, destination port)
Protocol is set when socket() is called
Source address and source port is set when bind() is called
Destination address and destination prot is set when connect() is called (even for UDP)

In order to bind to any address, user can specify address 0.0.0.0 or ::. In practice it means: all IP addresses of all local interfaces. During the succeeding connect() call the OS will choose proper source IP based on destination address and contents of routing table.
In order to bind to any ephemeral port, user can specify port = 0, then the OS will choose the port
By default no two sockets can be bound to same (source address, source port), e.g., if any socket is bound to 0.0.0.0:21, then no other address can be bound to port 21

Syscalls

syscall info
socket(domain, type, protocol) returns socket file descriptor (fd)
bind(fd, *addr, addrlen) bind to address, returns error code
listen(fd, backlog) mark socket as passive (this is: as a socket accepting connections), backlog determines the maximum length to which the queue of pending connections for fd may grow

Socket options

SO_REUSEADDR

TCP socket states

Backlog states how many connections can be queued before handing over (via accept call) to the application. TCP three-way handshake has SYN RECEIVED (SYN received and SYN+ACK sent) intermediate state, which transits to ESTABLISHED after receiving the ACK from client. Thus backlog can be implemented in two ways:

  1. The implementation uses a single queue, the size of which is determined by the backlog argument of the listen syscall. When a SYN packet is received, it sends back a SYN/ACK packet and adds the connection to the queue. When the corresponding ACK is received, the connection changes its state to ESTABLISHED and becomes eligible for handover to the application. This means that the queue can contain connections in two different states: SYN RECEIVED and ESTABLISHED. Only connections in the latter state can be returned to the application by the accept syscall. In this approach if the queue is full then any consecutive three-way handshake will be unsuccessful (client syn will be dropped). Not used in linux
  2. The implementation uses two queues, a SYN queue (or incomplete connection queue) and an accept queue (or complete connection queue). Connections in state SYN RECEIVED are added to the SYN queue and later moved to the accept queue when their state changes to ESTABLISHED, i.e. when the ACK packet in the 3-way handshake is received. As the name implies, the accept call is then implemented simply to consume connections from the accept queue. In this case, the backlog argument of the listen syscall determines the size of the accept queue (second queue). Linux default.
    To set the max length of incomplete queue (first queue) use: /proc/sys/net/ipv4/tcp_max_syn_backlog. What happens when accept queue is full and client ACK arrives? Depends on /proc/sys/net/ipv4/tcp_abort_on_overflow it may clean the incomplete connection (drop)

References

  1. http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html
  2. https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_ipv4.c
  3. https://stackoverflow.com/questions/14388706/socket-options-so-reuseaddr-and-so-reuseport-how-do-they-differ-do-they-mean-t
Clone this wiki locally