4-way Handshake 란
4-way handshake
TCP/IP 네트워크에서 서버와 클라이언트의 연결을 해제(세션 종료)하는 프로세스이다.
4-way handshake 프로세스
STEP 1
클라이언트가 연결을 종료하겠다는 FIN 플래그를 전송한다. 이때 클라이언트는 FIN_WAIT_1 상태가 된다.
STEP 2
서버는 FIN 플래그를 받고 ACK 플래그를 전송한다. 이때 서버는 CLOSE_WAIT 상태가 되어 연결이 종료될 때까지 대기한다.
클라이언트는 서버에서 보낸 ACK 를 받고 FIN_WAIT_2 상태로 전환한다. 서버의 FIN 플래그를 대기하는 상태이다.
STEP 3
서버는 연결을 종료할 준비가 되면 클라이언트에 FIN 플래그를 전송한다. 그리고 클라이언트로 부터 ACK 를 기다리는 LAST_ACK 상태가 된다.
클라이언트는 서버의 FIN 플래그를 받으면 TIME_WAIT 상태로 전환하고, 서버에 ACK 를 전송한다. TIME_WAIT 은 FIN 패킷 이전에 서버에서 보낸 패킷이 있을 수 있으니 대기하는 상태이다. 일정 시간 패킷 수신 대기 후 CLOSE 상태로 전환한다.
STEP 4
클라이언트에서 전송한 ACK 를 서버에서 수신하면 CLOSE 상태로 전환하고 세션이 종료된다.
각 상태 별 추가 정보
- FIN_WAIT_1
Linux 환경에서 FIN_WAIT_1 의 타임아웃은 존재하지 않는다. ACK 플래그를 수신하고 FIN_WAIT_2 상태로 전환하거나, 커널이 저장하고 있는 전체 FIN_WAIT_1 상태의 개수가 특정 개수 이상이 되어 커널로부터 제거되기 전까지는 남아있게 된다. Linux 커널이 저장할 수 있는 상태의 개수는 "/proc/sys/net/ipv4/tcp_max_orphans" 이다.(기본값 16384)
- FIN_WAIT_2
FIN 플래그를 수신하고 TIME_WAIT 상태가 되거나, 커널에 설정된 FIN_WAIT_2 의 타임아웃 시간이 지날 때까지 유지된다. 타임아웃 설정값은 "/proc/sys/net/ipv4/tcp_fin_timeout"에 있다.(기본값 60초)
- TIME_WAIT
TCP 표준에는 TIME_WAIT 상태가 2MSL(2 * Maximum Segment Lifetime)만큼 유지되어야 한다고 정의되어있다. 즉 네트워크 상에서 종료된 세션관련 패킷이 완전히 제거될 때까지 대기하여, 이후에 생성되는 새로운 세션에 영향을 미치지 않기 위한 상태이다.
Linux 에서는 TIME_WAIT 은 60초 동안 지속되며, 코드에 설정되어 있기 때문에 변경할 수 없다. 또한 Linux 환경에서 소켓(포트)가 부족한 경우 TIME_WAIT 상태의 소켓을 재사용 할 수 있는 옵션을 제공하고 있다. ("/proc/sys/net/ipv4/tcp_tw_reues=1")