hafeez@unixshadow:~$ sudo tcpdump -i eth0 ‘tcp port 443’ # the 3-way handshake, live
TCP 3-Way Handshake
How Every Connection Begins
before a single byte of data moves, both sides synchronize sequence numbers — and prove each direction works.
# the handshake — three packets // 10:24:01
CLOSEDCLIENT
SYN
seq = x
LISTENSERVER
SYN_SENTCLIENT
SYN + ACK
seq = y · ack = x+1
SYN_RCVDSERVER
ESTABLISHEDCLIENT
ACK
ack = y+1
ESTABLISHEDSERVER
both sides proved they can send and receive — data flows now.
# on the wire // what tcpdump actually shows
10:24:01.102431 IP 192.168.1.10.54321 > 203.0.113.7.443: Flags [S], seq 1000, win 64240
10:24:01.143882 IP 203.0.113.7.443 > 192.168.1.10.54321: Flags [S.], seq 5000, ack 1001, win 65160
10:24:01.144005 IP 192.168.1.10.54321 > 203.0.113.7.443: Flags [.], ack 5001, win 502
10:24:01.143882 IP 203.0.113.7.443 > 192.168.1.10.54321: Flags [S.], seq 5000, ack 1001, win 65160
10:24:01.144005 IP 192.168.1.10.54321 > 203.0.113.7.443: Flags [.], ack 5001, win 502
# [S]=SYN [S.]=SYN+ACK [.]=ACK — 42ms round trip, connection ready.
# why three steps?
Two-way sequence sync. Each side picks its own ISN (x and y); both must be acknowledged — a SYN each way plus a final ACK.
Kills stale duplicates. A delayed old SYN can’t trick the server: no matching ACK, no connection.
Two steps leave one direction unverified; four are redundant. Three is the minimum that works.
# teardown — the 4-way goodbye // each direction closes alone
10:31:44.020311 client > server: Flags [F.] # i’m done sending
10:31:44.020709 server > client: Flags [.] # ack — server: CLOSE_WAIT
10:31:44.021105 server > client: Flags [F.] # i’m done too
10:31:44.021330 client > server: Flags [.] # ack — client: TIME_WAIT (2×MSL)
10:31:44.020709 server > client: Flags [.] # ack — server: CLOSE_WAIT
10:31:44.021105 server > client: Flags [F.] # i’m done too
10:31:44.021330 client > server: Flags [.] # ack — client: TIME_WAIT (2×MSL)
# TIME_WAIT lingers ~60s so stray duplicates can’t corrupt the next connection on the same port pair.
# see it live
# watch handshakes on your own box:
wireshark filter:
ss -tlnp — sockets and TCP states (SYN-SENT, ESTAB, TIME-WAIT)sudo tcpdump 'tcp[tcpflags] & tcp-syn != 0' — SYN / SYN-ACK packets onlywireshark filter:
tcp.flags.syn == 1, then follow the stream# field guide // man tcp, condensed
- SYN
- synchronize — “i want to talk; my initial sequence number is x”
- ACK
- acknowledgment — “got it; next i expect y+1 from you”
- FIN
- finish — “i’m done sending” (teardown)
- seq
- sequence number of this segment’s first byte
- ack
- the next sequence number i expect from you
- ISN
- initial sequence number — randomized per connection
unixshadow.com · VPS & hosting from the shadowshafeez@unixshadow:~$
