tcp connection lifecycle - establishment and termination

on this page

learning objectives

after this guide, you will understand:

  • the three-way handshake process
  • tcp connection states and transitions
  • option negotiation during connection setup
  • graceful connection termination
  • abnormal termination scenarios
  • time-wait state purpose

connection establishment

three-way handshake

tcp uses a three-way handshake to establish connections, synchronize sequence numbers, and negotiate parameters:

TCP Three-Way Handshake
Rendering diagram...

Connection establishment process showing state transitions and segment exchange between client and server.

detailed steps

step 1: syn (client → server)

  • client chooses initial sequence number (isn)
  • sends syn segment with isn
  • includes tcp options for negotiation
  • transitions to syn-sent state

step 2: syn-ack (server → client)

  • server acknowledges client’s syn (ack = client_isn + 1)
  • chooses its own isn
  • sends syn with its isn
  • includes tcp options response
  • transitions to syn-received state

step 3: ack (client → server)

  • client acknowledges server’s syn (ack = server_isn + 1)
  • transitions to established state
  • may include data in this segment
  • server transitions to established upon receipt

sequence number selection

initial sequence numbers (isn) should be:

  • unpredictable - security against spoofing
  • monotonic - increasing over time
  • unique - avoid confusion with old connections

modern systems use:

ISN = M + F(localhost, localport, remotehost, remoteport, secret)
# M = 4-microsecond timer
# F = cryptographic hash function

option negotiation

during the handshake, tcp endpoints negotiate capabilities:

common tcp options

tl;dr

OptionPurposeWhen SentSize
MSSMaximum Segment SizeSYN only4 bytes
Window ScaleExtend window > 64KBSYN only3 bytes
SACK PermittedEnable selective ackSYN only2 bytes
TimestampsRTT measurementAll segments10 bytes
TFO CookieFast Open dataSYN6-18 bytes

option negotiation rules

  1. syn-only options - must be in syn segments only
  2. mutual agreement - both sides must support
  3. no renegotiation - options fixed after handshake
  4. fallback behavior - graceful degradation if not supported

example option exchange

TCP Option Negotiation
Rendering diagram...

Shows how TCP options are negotiated during the three-way handshake, with each side proposing capabilities.

connection states

tcp connections progress through well-defined states:

state transition diagram

TCP Connection State Transitions
Rendering diagram...

Complete state machine showing all TCP states and transitions during connection establishment, data transfer, and termination.

state descriptions

tl;dr

StateDescriptionCan SendCan Receive
CLOSEDNo connection existsNoNo
LISTENWaiting for connection requestNoSYN only
SYN-SENTWaiting for matching SYNSYNSYN, SYN-ACK
SYN-RECEIVEDWaiting for confirming ACKSYN-ACKACK
ESTABLISHEDConnection openDataData
FIN-WAIT-1Waiting for FIN ACKFINData, ACK, FIN
FIN-WAIT-2Waiting for FINNoData, FIN
CLOSE-WAITWaiting for close from appDataNo
LAST-ACKWaiting for final ACKFINACK
TIME-WAITWaiting for network to clearACKRetransmitted FIN
CLOSINGSimultaneous closeFINACK

connection termination

graceful close (four-way handshake)

tcp connections close gracefully with a four-way handshake:

TCP Connection Termination (Four-Way Handshake)
Rendering diagram...

Graceful connection close showing the four-step process and TIME-WAIT state to ensure reliable termination.

termination steps

step 1: initiator sends fin

  • application calls close()
  • tcp sends fin segment
  • transitions to fin-wait-1
  • can still receive data

step 2: receiver acknowledges fin

  • sends ack for fin
  • transitions to close-wait
  • notifies application of eof
  • can still send data

step 3: receiver sends fin

  • application calls close()
  • tcp sends fin segment
  • transitions to last-ack
  • no more data transfer

step 4: initiator acknowledges fin

  • sends ack for fin
  • enters time-wait state
  • waits 2*msl before closing
  • ensures final ack received

half-close

tcp supports half-close where one direction closes while other remains open:

# shutdown for writing but keep reading
shutdown(socket, SHUT_WR)

# useful for:
# - request/response protocols
# - signaling end of data
# - maintaining control channel

time-wait state

purpose

time-wait serves two critical functions:

  1. reliable termination - ensures final ack reaches peer
  2. connection incarnation protection - prevents old segments from new connections

duration

time-wait lasts 2*msl (maximum segment lifetime):

  • typical msl = 30-120 seconds
  • total wait = 60-240 seconds
  • configurable via tcp_fin_timeout (linux)

implications

Key Highlights

  • port exhaustion - rapid connection cycling can exhaust ports
  • memory usage - each time-wait connection uses memory
  • cannot reuse socket - must wait for timeout
  • so_reuseaddr - allows bind to time-wait port (server)

avoiding time-wait

strategies to minimize time-wait accumulation:

  1. connection pooling - reuse long-lived connections
  2. let client close first - server avoids time-wait
  3. so_reuseaddr - allows immediate rebind
  4. tcp_tw_reuse - linux option for client connections

abnormal termination

reset (rst) scenarios

tcp uses rst flag for immediate termination:

tl;dr

ScenarioCauseResult
Port unreachableNo listener on portRST sent immediately
Abort connectionSO_LINGER with timeout=0RST instead of FIN
Half-open detectionPeer crashed/rebootedRST on unexpected segment
Security violationInvalid sequence numbersRST to terminate
Buffer overflowNo room for dataRST if cannot recover

handling resets

# detect reset in application
try:
    data = socket.recv(1024)
except ConnectionResetError:
    print("Connection reset by peer")
    
# common causes to investigate:
# - application crash
# - firewall intervention
# - timeout/keepalive failure
# - explicit abort

simultaneous operations

simultaneous open

rare but possible - both ends initiate simultaneously:

Simultaneous Open
Rendering diagram...

Both endpoints actively initiate connection at the same time, resulting in a modified handshake sequence.

simultaneous close

both ends initiate close simultaneously:

Simultaneous Close
Rendering diagram...

Both endpoints initiate connection termination at the same time, leading to the CLOSING state.

connection establishment optimizations

tcp fast open (tfo)

allows data in syn packets to reduce latency:

TCP Fast Open (TFO) Comparison
Rendering diagram...

Compares traditional three-way handshake with TCP Fast Open, showing how TFO reduces latency by including data in the SYN packet.

benefits:

  • reduces latency by 1 rtt
  • especially useful for short flows
  • http requests can be sent with syn

limitations:

  • requires application changes
  • security considerations (replay attacks)
  • limited deployment support

syn cookies

protects against syn flood attacks:

  1. don’t allocate state for syn-received
  2. encode state in isn
  3. reconstruct state from ack
# syn cookie generation
cookie = hash(client_ip, client_port, server_ip, server_port, secret) + 
         encoded_mss + timestamp

# validation on ack
if validate_cookie(ack_number - 1):
    create_connection()

practical considerations

tuning parameters

# linux tcp connection parameters

# syn retries (default: 6)
net.ipv4.tcp_syn_retries = 3

# syn-ack retries (default: 5)  
net.ipv4.tcp_synack_retries = 3

# fin timeout (default: 60)
net.ipv4.tcp_fin_timeout = 30

# time-wait reuse (careful!)
net.ipv4.tcp_tw_reuse = 1

# syn backlog size
net.ipv4.tcp_max_syn_backlog = 4096

monitoring connection states

# count connections by state
ss -ant | awk '{print $1}' | sort | uniq -c

# find time-wait connections
ss -ant state time-wait

# monitor syn_recv (possible syn flood)
watch -n 1 'ss -ant | grep SYN_RECV | wc -l'

# connection state distribution
netstat -ant | awk '/^tcp/ {print $6}' | sort | uniq -c

common issues and solutions

issue: connection timeout

symptoms: connection attempts fail after delay

causes:

  • firewall dropping syn
  • routing issues
  • server not listening
  • syn queue full

debugging:

# check if syn packets leaving
tcpdump -i any 'tcp[tcpflags] & tcp-syn != 0'

# verify route
traceroute -T -p 80 target.host

# check firewall
iptables -L -n -v

issue: time-wait accumulation

symptoms: cannot bind to port, port exhaustion

solutions:

  1. use connection pooling
  2. enable so_reuseaddr
  3. adjust tcp_tw_reuse (client)
  4. reduce tcp_fin_timeout

issue: half-open connections

symptoms: connections hang, resources leak

causes:

  • peer crash without fin
  • network partition
  • firewall timeout

solutions:

  • enable tcp keepalive
  • application-level heartbeat
  • monitor connection states

key takeaways

  • three-way handshake establishes connection and synchronizes state
  • option negotiation happens only during handshake
  • connection states follow well-defined transitions
  • graceful termination uses four-way handshake
  • time-wait prevents connection confusion
  • resets provide immediate termination
  • various optimizations improve connection performance

next steps

on this page