[TCP]3-way-handshake & 4-way-handshake

warning·2025년 4월 8일

네트워크

목록 보기
2/2

3-way-handshake

연결 성립(Connection Establishment)

3-way-handshake

1) 클라이언트는 서버에 접속을 요청하는 SYN(a) 패킷을 보낸다.
2) 서버는 클라이언트의 요청인 SYN(a) 패킷을 받고, 클라이언트에게 요청을 수락한다는 ACK(a+1)와 SYN(b)이 설정된 패킷을 보낸다.
3) 클라이언트는 서버의 ACK(a+1)와 SYN(b)패킷을 받고, ACK(b+1)를 서버로 보내면 연결이 성립된다.

4-way-handshake

연결종료(Connection Close)

1) 클라이언트가 연결을 종료하겠다는 FIN 플래그를 전송한다.
2) 서버는 클라이언트의 요청(FIN)을 받고 알겠다는 확인 메시지로 ACK를 보낸다.
2-1) 데이터를 모두 보낼때까지 잠깐 TIME_OUT이 된다.
3) 데이터를 모두 보내고 통신이 끝났으면 연결이 종료되었다고 클라이언트에게 FIN 플래그를 보낸다.
4) 클라이언트는 FIN 메세지를 확인했다는 ACK 을 보낸다.
5) 클라이언트의 ACK 메세지를 받은 서버는 소켓 연결을 종료한다.
6) 클라이언트는 아직 서버로부터 받지 못한 데이터가 있을것을 대비하여 일정 시간 동안 세션을 남겨놓고 잉여 패킷을 기다리는 과정을 거친다.(TIME WAIT)
4-way-handshake


SYN packet & ACK packet

SYN: synchronize seqeunce number
ACK: acknowledgement

TCP header에는 Code Bit(Flag bit)라는 부분이 존재한다. 대표적으로 6개의 비트가 있는데, 이 비트들은 1비트씩 켜지거나 꺼질 수 있는 스위치라고 보면 된다.

Urg-Ack-Psh-Rst-Syn-Fin 순서로 되어 있으며 해당 위치의 비트가 1이면 해당 패킷이 어떠한 내용을 담고 있는 패킷인지를 나타낸다. SYN 패킷일 경우엔 000010이 되고 ACK 패킷일 경우에는 010000이 되는 것이다.

이런 방식으로 비트를 쓰는 이유

  • 네트워크에서 헤더의 크기를 줄이기 위해서 이런식으로 플래그를 각각 1비트로 표현한다.
  • 1개의 바이트(8비트) 안에서 여러 기능을 동시에 표현할 수 있어서 효율적이다.
  • 예를 들어, 어떤 패킷이 SYN과 ACK 기능을 동시에 가진다면, 010010 이렇게 둘다 1로 켜주면 된다.

패킷이 두 종류인 이유

사실, 패킷의 종류가 두 가지 뿐인것은 아니다.
흔히 말하는 SYN, ACK 패킷은 주요한 목적에 따라 이름을 붙인 것이고, 실제로 TCP packet은 플래그 비트의 조합에 따라 다양하게 존재할 수 있다.
일단 큰 이유는 요청과 응답에 대한 패킷을 주고 받아야하기 때문에 보통 두 종류로 주고 받는다고 하는것이다.


3-way인 이유

요청 - 응답이면 2way이면 족할것같은데 왜 TCP 연결은 굳이 3번 왔다갔다하는 3-way-handshake를 쓰는가하면..
TCP가 왜 만들어졌는지, 무엇을 보장하려고 하는지부터 짚고 가야한다.

TCP는 신뢰성있는 연결을 위해 만들어졌다.

TCP는 단순히 데이터를 보내는게 아니라,

  • 순서 보장
  • 손실 없이 도착
  • 중복 없이 도착
  • 상대방이 준비됐는지 확인

이 부분을 다 신경써야하는데에 반해

2-way-handshake를 생각해보면

1) 클라이언트 -> 서버: SYN 보내서 연결 요청
2) 서버 -> 클라이언트: SYN + ACK 로 수락하면서 응답

이렇게 봤을때는 연결된 것 처럼 보이지만, 실제로 서버입장에서는 클라이언트가 살아있는지, 이 응답을 제대로 받았는지 알 수 없다.

즉, 클라이언트가 응답을 못받았을 수도 있고, 서버는 연결되었다고 믿고 기다리는데 클라이언트는 연결안된 줄 알고 멈춰버리는 상황이 생길 수 있는것이다.

이런 문제를 막기 위해선 서버도 자신의 SYN+ACK을 받았는지 확인을 해야한다.

그래서 등장한 3-way-handshake로, 상단에서 순서를 다시 확인해보도록 한다.

[1] 클라이언트 → 서버 : SYN (나 연결하고 싶어)
[2] 서버 → 클라이언트 : SYN + ACK (좋아, 나도 연결할게. 너도 살아있니?)
[3] 클라이언트 → 서버 : ACK (응! 나 살아있고, 너 응답 잘 받았어!)

왜 TCP는 Sequence Number를 랜덤하게 시작할까

이는 기술적인 편의 때문이 아니라, 보안과 신뢰성과 관련되어있다.

Sequence Number란?

TCP는 바이트 단위로 데이터를 주고받는다. 그래서, "이 바이트부터 보낸 다음에 이 바이트부터 받을게" 하면서 일련번호(Sequence Number)를 사용한다. 즉, Sequence Number는 데이터 흐름의 순서를 관리하기 위한 번호이다.

왜 랜덤하게 시작할까

1) 보안문제 (예측 가능성 차단)
TCP연결에서 시퀀트 넘버가 예측 가능한 숫자라면 누군가 TCP 세션 하이재킹을 하여 데이터 탈취가 가능하게 된다.
따라서 이때 랜덤으로 시작해서 예측을 어렵게 만드는 것이다.

2) 중복된 연결 충돌 방지
TCP 연결이 끊어지고 나서도 네트워크 상에 이전 패킷이 남아있는 경우가 있다.(ex. 딜레이된 패킷)
만약 다음 연결도 시퀀스 넘버가 똑같다면, 이전 연결의 패킷과 구분이 안 될 수 있다.
따라서 매번 랜덤한 시퀀스 넘버로 시작함으로써 이전 연결과 새 연결을 명확하게 구분할 수 있게 된다.

지식출처

profile
개발 찾기

0개의 댓글