IP의 한계와 TCP·UDP, 3-Way Handshake
IP 프로토콜의 한계를 TCP가 어떻게 보완하는지와 TCP 플래그, 3-way handshake, SYN Flooding 대응 방법을 정리한다.
시리즈 · 네트워크5 / 12
- OSI 7 Layer와 계층별 역할, ARP
- IP 주소: IPv4와 IPv6, NAT, 체크섬
- 라우터: 경로 지정, 브로드캐스트 컨트롤, 라우팅과 스위칭
- DHCP 동작 방식과 UDP를 사용하는 이유
- IP의 한계와 TCP·UDP, 3-Way Handshake
- TCP 4-Way Handshake와 TIME_WAIT
- DNS 정리: 구조, 질의 방식, 레코드, 이중화와 위임
- 로드 밸런서: 구성 방식, 헬스 체크, L4와 L7
- HTTP 메서드와 상태 코드: 멱등성, POST와 PUT의 차이
- HTTP의 Stateless·Connectionless와 쿠키, 세션
- HTTP/1.1, HTTP/2, HTTP/3 비교
- 소켓과 포트, 그리고 웹소켓
IP (Internet Protocol)
IP는 지정한 IP 주소로 데이터를 전달하는 프로토콜이다. 데이터는 패킷(Packet)이라는 단위로 쪼개져, 출발지에서 목적지까지 여러 노드를 거쳐 전달된다.
IP 프로토콜의 한계
- 비연결성: 패킷을 받을 대상의 상태를 알 수 없다. 상대가 수신 불가능한 상태여도 패킷을 그대로 보낸다.
- 비신뢰성: 중간에 패킷이 사라질 수 있고, 패킷의 순서를 보장하지 않는다.
- 프로그램 구분 불가: 같은 IP를 쓰는 서버에서 통신하는 애플리케이션이 둘 이상이면 어느 쪽으로 가는 패킷인지 구분할 수 없다.
패킷마다 거쳐 가는 노드 경로가 일정하지 않기 때문에, 아래처럼 보낸 순서와 도착 순서가 달라질 수 있다.

TCP (Transmission Control Protocol)
TCP는 IP 위에서 위 한계를 보완하는 전송 계층 프로토콜이다. 동작은 크게 세 단계로 나뉜다.
- 연결 생성 (Connection establishment)
- 자료 전송 (Data transfer)
- 연결 종료 (Connection termination): 4-Way Handshake에서 따로 다룬다.
TCP 플래그
| 플래그 | 의미 | 설명 |
|---|---|---|
| SYN | 연결 요청 | 세션을 성립할 때 가장 먼저 보내는 패킷이다. 임의로 정한 초기 시퀀스 번호를 함께 보낸다. |
| ACK | 응답 | 상대방의 패킷을 받았음을 알린다. 받은 시퀀스 번호에 받은 데이터의 길이를 더한 값을 응답 번호로 보낸다(핸드셰이크에서는 +1). 송신 측은 ACK로 전송 성공 여부를 판단해 재전송하거나 다음 패킷을 보낸다. |
| FIN | 연결 종료 | 더 이상 전송할 데이터가 없음을 알리고 세션을 종료할 때 사용한다. |
| RST | 연결 재설정 | 비정상적인 세션 끊기에 해당한다. 보내는 쪽이 현재 연결을 즉시 끊고자 할 때 사용한다. |
| PSH | 밀어 넣기 | 버퍼가 채워지기를 기다리지 않고 받은 데이터를 즉시 응용 프로그램으로 전달하게 한다. TELNET처럼 빠른 응답이 중요한 대화형 트래픽에 쓰인다. |
| URG | 긴급 데이터 | Urgent pointer가 유효함을 나타낸다. 전송하는 데이터 중 다른 데이터보다 먼저 처리해야 할 긴급한 내용이 있을 때 사용한다. |
TCP는 ACK를 받을 때까지 데이터를 재전송하는 PAR(Positive Acknowledgement with Re-transmission) 방식으로 신뢰성을 확보한다.
연결 생성: 3-Way Handshake
데이터를 전송하기 전에 연결을 설정하는 과정이다. 양쪽 모두 데이터를 주고받을 준비가 되었음을 보장하고, 실제 전송을 시작하기 전에 서로 상대가 준비되었다는 것을 알 수 있게 한다.

- SYN (클라이언트 → 서버):
SYN = 1, ACK = 0으로 설정하고, 초기 시퀀스 번호(ISN)를 무작위 값 A로 정해 보낸다. - SYN-ACK (서버 → 클라이언트):
SYN = 1, ACK = 1로 설정한다. 응답 번호는 A + 1이고, 서버도 자신의 ISN을 무작위 값 B로 정해 보낸다. - ACK (클라이언트 → 서버):
SYN = 0, ACK = 1로 설정한다. 시퀀스 번호는 서버가 보낸 응답 번호(A + 1), 응답 번호는 B + 1이다.
이 과정을 거쳐 서버와 클라이언트가 논리적으로 연결되므로 IP의 비연결성을 보완할 수 있다. 다만 어디까지나 논리적인 연결이지, 물리적으로 전용 회선이 연결된 상태를 뜻하지는 않는다.
2-Way Handshake를 하지 않는 이유
두 번만 주고받으면 서버는 자신의 응답이 클라이언트에 도착했는지, 즉 연결이 실제로 맺어졌는지 알 수 없다. 다음 상황을 보자.
- 클라이언트 → 서버: SYN
- 서버 → 클라이언트: ACK (네트워크에서 지연됨)
- 클라이언트가 타임아웃되어 SYN을 다시 보낸다.
- 서버가 처음에 보낸 ACK가 그제야 도착한다.
2-way라면 서버는 SYN을 받을 때마다 연결이 맺어졌다고 판단하지만, 클라이언트는 어떤 요청에 대한 연결인지 확신할 수 없어 양쪽의 상태가 어긋난다. 마지막 ACK가 있어야 양쪽 모두 상대가 준비되었음을 확인할 수 있다.
두 호스트가 동시에 연결을 시도하면 연결이 가능한가
가능하다. 두 호스트가 서로의 80번 포트로 동시에 연결을 시도하는 경우를 보자. 이때 두 호스트 모두 80번 포트에서 수신 대기하는 서비스가 있어야 한다.
Connection 1: 192.168.1.5 sends SYN to 192.168.1.6 on port 80.
Connection 2: 192.168.1.6 sends SYN to 192.168.1.5 on port 80.
각 수신 서비스는 상대방도 SYN을 보냈는지 알 수 없으므로, SYN-ACK를 보내지 않을 이유가 없다.
Connection 1: 192.168.1.6 responds with SYN-ACK to 192.168.1.5
Connection 2: 192.168.1.5 responds with SYN-ACK to 192.168.1.6
SYN-ACK를 받은 발신 측은 TCP 프로토콜에 따라 ACK로 응답한다.
Connection 1: 192.168.1.5 sends ACK to 192.168.1.6 on port 80.
Connection 2: 192.168.1.6 sends ACK to 192.168.1.5 on port 80.
결과적으로 핸드셰이크가 완료된 두 개의 독립적인 연결이 만들어진다.
- 두 연결은 서로에 대해 알지 못한다.
- 둘 중 어떤 연결을 끊을지는 TCP의 관할이 아니라 응용 프로그램이 결정할 일이다.
참고: What happens when 2 hosts simultaneous establish a connection in a 3-way handshake
자료 전송
TCP 세그먼트는 IP 패킷 안에 캡슐화되어 전달된다.

TCP 세그먼트에는 PORT와 순서 정보가 들어 있다. 순서 정보로 비신뢰성을, PORT로 프로그램 구분 문제를 해결한다.
SYN Flooding
3-way handshake의 half-open 상태를 악용한 DoS 공격이다. 서버는 SYN을 받으면 SYN-ACK를 보내고, 마지막 ACK를 기다리는 동안 연결 정보를 백로그 큐에 보관한다.
- 공격자는 다량의 SYN 패킷만 보내고 이후 아무런 동작도 하지 않는다.
- 백로그 큐가 가득 차면 서버는 정상적인 연결 요청을 받지 못한다.
대응 1: SYN Cookie
방화벽이 서버 대신 SYN을 먼저 받고, SYN Cookie를 시퀀스 번호에 담은 SYN+ACK를 보내는 방법이다.

- SYN이 들어오면 방화벽이 syn_cookie가 포함된 SYN+ACK를 보낸다.
- syn_cookie에 맞는 정상적인 ACK가 들어오면 세션을 새로 연다. 일정 시간 동안 정상적인 응답이 없으면 방화벽에서 차단한다.
처음에 방화벽과 맺은 3-way handshake는 없던 셈 치고, 이후의 새로운 3-way handshake를 서버에 연결해 주는 방식이다. 따라서 클라이언트 입장에서는 첫 접속이 실패한 것처럼 보일 수 있지만, 재접속 요청이 순식간에 이루어지므로 사용자가 체감하기는 어렵다.
대응 2: SYN Proxy
방화벽에서 정상적인 3-way handshake가 이루어지면, 방화벽이 그 연결을 서버에게 그대로 재현해 주는 방식이다.

- 3-way handshake가 완료되지 않은 요청은 방화벽에서 차단한다.
- SYN Proxy도 syn_cookie를 이용해 정상적인 3-way handshake인지 확인한다.
- 클라이언트와 방화벽 사이에 맺은 핸드셰이크를 방화벽이 서버에 재현해 주므로, SYN Cookie 방식과 달리 클라이언트가 세션을 새로 맺을 필요가 없다.
UDP (User Datagram Protocol)
- 하얀 도화지에 비유될 정도로 기능이 거의 없다.
- IP에 PORT 정도만 추가된 형태이다. 연결 과정도, 순서 보장도 없다.
대부분의 통신은 TCP를 사용하지만, HTTP/3는 UDP 기반으로 설계되었다. 이 내용은 HTTP/1.1, HTTP/2, HTTP/3 비교에서 다룬다.
Reference
- 모든 개발자를 위한 HTTP 웹 기본 지식 - 김영한
- HTTP/3는 왜 UDP를 선택한 것일까?