linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
Index
Categories
All entries
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
home/linux/kb/Networking: L4 and above/tcp-handshake

kb/network-l4 ── Networking: L4 and above ── intermediate

TCP three-way handshake

TCP connection opens with three packets: SYN from the client, SYN-ACK from the server, ACK from the client. After that the connection is Established and data transfer can begin.

view as markdownaka: tcp-3wh, syn-synack-ack, tcp-3-way-handshake

What happens

When a client calls connect() to a server, the kernels exchange three packets:

Client                      Server
  |   ── SYN seq=X ──────►   |  (1)
  |                          |
  |   ◄── SYN-ACK            |  (2)
  |       seq=Y ack=X+1      |
  |                          |
  |   ── ACK ack=Y+1 ─────►  |  (3)
  |                          |
  | <════════════════════════> |  ESTABLISHED, ready to send data

What each packet contains

  • SYN - flag S in tcpdump. Client: "I want to open a connection, my ISN = X"
  • SYN-ACK - flags S+A. Server: "agreed, my ISN = Y, I acknowledge your X+1"
  • ACK - flag A. Client: "I acknowledge Y+1"

After the third packet both sides consider the connection Established. The kernel on the server side adds it to the accept-queue, from which the accept() syscall delivers it to the application.

ISN: Initial Sequence Number

Each side picks a random 32-bit ISN. This is not byte numbering starting from zero. The randomness protects against:

  • Sequence-prediction attacks (injecting packets into someone else's connection)
  • Confusion with stale packets after a crash

From there the sequence number increments by the payload size of each data packet.

Where to see it

In tcpdump each packet carries flags:

Flags [S],     seq 1000      ← SYN
Flags [S.],    seq 5000, ack 1001  ← SYN-ACK
Flags [.],     ack 5001      ← ACK
Flags [P.],    seq 1001:1041, ack 5001  ← data with PUSH (HTTP request)

A dot after a letter ([.]) means ACK.

When something goes wrong

  • Connection refused - port is closed. The server sends RST instead of SYN-ACK.
  • Connection timeout - packets are lost or a firewall drops them. The client retransmits SYN several times and gives up (about 3 minutes by default).
  • SYN but no ACK - half the handshake is stuck. On the server side this is the SYN_RECV state. Many such entries indicate a SYN-flood attack.
  • SYN cookies - defense against SYN-flood: the server does not allocate state until it receives ACK, encoding the ISN into a cookie instead.

What comes next

Immediately after the ACK the first data packet usually follows (HTTP GET, TLS ClientHello, etc.). On loopback this all takes microseconds. Over a WAN link you add at least RTT x 1.5 (handshake plus the first request).

§ команды

bash
tcpdump -i lo -nn 'tcp port 8080' -c 10

Capture the first 10 packets on port 8080. The handshake occupies the first three.

bash
ss -tn '( dport = 8080 or sport = 8080 )'

List TCP sessions associated with port 8080 and their state.

bash
ss -ti dst 1.2.3.4

-ti: extended TCP info including RTT, cwnd, MSS, retransmits, and congestion algorithm.

bash
sysctl net.ipv4.tcp_syncookies

1 = SYN cookies are enabled, protecting against SYN-flood without allocating state.

§ см. также

  • tcp-statesTCP states (LISTEN, ESTABLISHED, TIME_WAIT)A TCP session moves through 11 states from LISTEN to CLOSED. The most important in production: LISTEN, ESTABLISHED, TIME_WAIT, CLOSE_WAIT.
  • tcp-keepaliveTCP keepaliveKeepalive sends probes on an idle TCP connection to detect a dead peer (NAT timeout, crashed host). Linux defaults: 7200s idle, 75s between probes, 9 probes. Enabled via setsockopt(SO_KEEPALIVE).
  • tls-handshakeTLS HandshakeTLS is the encryption layer above TCP. Before data flows, both sides run a handshake: they exchange keys, verify the certificate, and agree on a cipher.
  • http-protocolHTTP/1.1, HTTP/2, HTTP/3HTTP/1.1 is a text-based protocol with keep-alive. HTTP/2 is binary with multiplexing over a single TCP connection. HTTP/3 carries HTTP/2 semantics over QUIC/UDP without TCP head-of-line blocking.
  • quic-http3QUIC: Modern Transport over UDPQUIC is a transport over UDP. TLS 1.3 is built in (1 RTT, 0-RTT for resume). Multiplexing without head-of-line blocking. Connection migration (Wi-Fi to 4G without drop). HTTP/3 = HTTP semantics over QUIC.

§ упоминается в уроках

  • ›advanced-03-tc-netem
  • ›advanced-04-tcp-tuning
  • ›advanced-05-bandwidth-iperf
  • ›intermediate-02-tcp-handshake
  • ›intermediate-09-tls-handshake
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies