TCP 3-Way Handshake는 TCP 연결을 수립할 때 클라이언트와 서버가 세 단계의 패킷을 교환하는 과정입니다.
TCP는 양방향 연결입니다. 각 방향에 대해 "보낼 준비가 됐는가?"와 "준비됐다는 것을 확인했는가?" 두 가지를 확인해야 합니다. 이를 최소한의 메시지 교환으로 처리하면 3단계가 됩니다.
클라이언트 서버
│ │
│──── SYN (seq=x) ────────────→ │ 1단계: 연결 요청
│ │
│ ←── SYN-ACK (seq=y, ack=x+1) │ 2단계: 요청 수락 + 서버 연결 요청
│ │
│──── ACK (ack=y+1) ──────────→ │ 3단계: 수락 확인
│ │
│ [연결 수립] │
SYN (Synchronize): 연결 요청 패킷으로, 클라이언트의 초기 시퀀스 번호를 담고 있음
클라이언트가 임의의 시퀀스 번호(ISN, Initial Sequence Number)를 생성하여 서버에 전송합니다.
서버는 클라이언트의 SYN을 확인(ACK)하는 동시에, 서버 자신의 ISN을 포함한 SYN을 보냅니다.
ACK = 클라이언트 seq + 1: "클라이언트 seq까지 받았으니 다음 seq를 보내라"는 의미클라이언트가 서버의 SYN을 확인합니다. 이 단계부터 데이터 전송이 가능합니다.
초기 시퀀스 번호(ISN)를 임의로 생성하는 이유는 보안과 이전 연결 패킷과의 혼동 방지를 위해서입니다. 연결마다 다른 ISN을 사용하면 이전 연결의 지연 패킷이 새 연결과 섞이는 문제를 방지합니다.
공격자가 응답 없이 SYN 패킷만 계속 보내면, 서버는 SYN-ACK를 보낸 후 ACK를 기다리는 반개방 연결을 많이 쌓아둡니다. 결국 새 연결 요청을 처리할 수 없게 됩니다.
대응책으로 SYN Cookie를 사용합니다. 서버가 연결 정보를 저장하지 않고 쿠키 형태의 시퀀스 번호를 생성합니다. ACK를 받아야만 연결 정보를 생성하여 메모리 낭비를 방지합니다.
TCP 연결 수립에 1.5 RTT(Round Trip Time)가 소요됩니다. TLS까지 포함하면 추가 RTT가 필요합니다. HTTP/3(QUIC)은 이 지연을 줄이기 위해 UDP를 기반으로 설계되었습니다.