네트워크 스터디 3주차 - TCP 3-way handshake 이후

Jiwon An·2021년 10월 27일
0

CS/네트워크

목록 보기
10/10

1. TCP(Transmission Control Protocol)

TCP는 신뢰성 있는 데이터 전송을 지원하는 연결 지향형 프로토콜이다. UDP와 동일하게 전송 계층에 위치하고 있다.

특징

  • 3-way handshake 과정을 통해 연결을 설정하고, 4-way handshake 과정을 통해 해제한다.
  • 데이터 흐름 제어(수신자 버퍼 오버플로우 방지) 및 혼잡 제어(네트워크 내 패킷 수가 과도하게 증가하는 현상 방지)가 가능하다.
  • 높은 신뢰성(Sequece Number, Ack Number를 통한 신뢰성)을 보장한다.
  • UDP 보다 속도가 느리다.
  • HTTP 웹 통신, 이메일, 파일 전송에 사용된다.

1.1 UDP(User Datagram Protocol)

UDP는 비연결형 프로토콜이다. 동일하게 전송 계층에 위치하고 있다.

특징

  • 비연결형 프로토콜로 데이터그램 방식을 제공한다.
  • 정보를 주고받을 때 정보를 보내거나 받는다는 handshake를 거치지 않는다.
  • UDP 헤더의 CheckSum 필드를 통해 최소한의 오류만 검출한다. 즉, 부하가 적다.
  • 패킷 손실이 발생할 수 있으며, 신뢰성이 낮다.
  • TCP보다 속도가 빠르다.
  • 신뢰성보다는 연속성이 중요한 서비스에서 많이 사용된다. (스트리밍 서비스, 브로드캐스팅 등)

3. TCP 3-way handshake

TCP/IP 프로토콜을 이용해서 통신을 하는 응용 프로그램이 데이터를 전송하기 전에 정확한 전송을 보장하기 위해 상대방과 사전에 세션을 수립하는 과정이다.(연결이 잘 되었는지 확인하는 과정이다.)
TCP가 연결지향적인 특성을 갖게 해준다.

3-way handshaking 역할

양쪽 모두 데이터를 전송할 준비가 되었다는 것을 보장한다.
양쪽 모두 상대방에 대한 초기 순차 일련번호를 얻을 수 있도록 한다.

3-way handshaking 과정

SYN : SYnchronize sequence Numbers
ACK : ACknowledgements

1. 클라이언트 -> 서버

  • 서버에 접속을 요청하는 SYN 패킷 전송한다.
  • 송신자가 최초로 데이터를 전송할 때 Sequence Number를 임의의 랜덤 숫자로 지정, SYN 플래그 비트를 1로 설정한 세그먼트 전송한다. -> SYN(seq=x)
  • 클라이언트는 SYN을 보냈으니 SYN/ACK 응답을 기다리는 SYN_SENT 상태가 된다.

2. 서버 -> 클라이언트

  • 서버는 클라이언트에게 요청을 수락(ACK)했으며 접속 요청 프로세스인 클라이언트도 포트를 열어달라(SYN)는 메시지를 전송한다.
  • 여기서 x값을 확인 후, x+1 값과 서버 측 Sequence Number인 y를 생성하여 포함하고, x+1와 y가 포함된 SYN+ACK 플래그 비트가 설정된 세그먼트를 전송한다. -> SYN+ACK(ack=x+1, seq=y)
  • 서버는 SYN 응답을 받은 상태이기 때문에 SYN_RECEIVED 상태가 된다.

3. 클라이언트 -> 서버

  • 클라이언트는 서버에게 ACK를 보내고 이후에는 연결이 완료된다.
  • 클라이언트는 서버의 응답을 받았다는 의미로, 서버측 y+1을 하여 다시 서버로 ACK 플래그가 설정된 세그먼트를 전송한다.
  • 이후 실제 데이터 전송을 할 수 있는 상태인 ESTABLISHED 상태가 된다. -> ACK(y+1)
  • 서버 역시 클라이언트로부터 ACK를 전달받고 ESTABLISHED 상태로 변한다.

4. 3-way handshake 이후 데이터 송수신 과정

  • 3-way handshake를 통해 TCP 연결이 수립된 이후, 데이터를 송수신할 때는 TCP 헤더의 일련번호(Sequence number)와 응답 번호(Acknowledgement number)를 사용한다.
  • 각 데이터는 몇 번째 데이터인지를 나타내는 정보를 포함함으로써, 중간에 결번발생 및 타임아웃을 통해 소멸데이터의 존재를 전송자가 인지할 수 있고 이에 한 번 더 전송할 수 있다.
  • ACK와 SEQ의 첫 수는 난수로 주어지고, 한 번 전송될 때마다 각자의 번호가 1씩 증가해서 연결되도록 설계되어있다.

일련번호

  • 송신 측 -> 수신 측 “이 데이터가 몇 번째 데이터인지" 알려주는 역할을 수행한다. (이 덕분에 TCP는 데이터를 송수신할 때 순서를 보장해 줄 수 있다.)
  • “난 n번째 데이터를 보낼거야”
  • 전송된 데이터에 일렵너호를 부여하면, 수신자는 원래 데이터의 “몇 번째 데이터”를 받았는지 알 수 있다.

응답번호

  • 수신 측이 몇 번째 데이터를 수신했는지 송신 측에 알려주는 역할을 수행한다.
  • “나 2000번째 데이터 방금 잘 받았어! 다음에는 2200번째 데이터를 줘!”
  • 다음 번호의 데이터를 요청하는데도 사용한다.
  • ex) 10번 데이터를 수신하면, 11번 데이터를 송신 측에 요청한다.

초기 일련번호 3001과 확인 응답번호 4001은 연결을 수립하는 3-way handshaking 과정에서 결정된다.
1. COM1은 COM2로 200 byte의 데이터를 전송한다.
2. COM2은 데이터를 수신하고, 다음에 수신하고자 하는 데이터 번호 3201을 확인응답번호에 넣는다.
3. COM1은 COM2로부터 3201번부터 200byte의 데이터를 전송한다.
4. COM2는 데이터를 수신하고, 다음에 수신하고자 하는 데이터 번호 3401을 확인응답번호에 넣는다.
5. 1~4 과정을 데이터 전송이 완료될 때까지 반복한다.

그러나 데이터가 항상 올바르게 전달되지는 않는다. -> 이 때, 일련번호와 확인응답번호를 사용해, 데이터가 손상되거나 유실된 경우 데이터를 재전송한다. (재전송 제어)

  • 재전송 제어 : 데이터 전송 도중 오류 발생 시 일정 기간 동안 대기한 후 재전송한다.

5. TCP 4-way handshake

세션을 종료하기 위해 수행되는 과정이다.

TCP 4-way handshake 과정

1. 클라이언트 -> 서버

  • 클라이언트가 접속을 끊기 위해 close()를 호출하면서 서버에게 연결을 종료하겠다는 FIN 플래그를 전송한다. 이때, FIN 패킷에 실질적으로는 ACK도 포함되어 있다. 그리고 클라이언트는 FIN_WAIT_1 상태로 들어간다.
  • 서버가 FIN 플래그로 응답하기 전까지 연결을 유지한다.

2. 서버 -> 클라이언트

  • 서버는 응답 메시지(ACK)를 보내고 CLOSE_WAIT 상태에 들어간다. 그리고 아직 남은 데이터가 있다면 마저 전송을 마친 후에 close()를 호출한다.

3. 클라이언트

  • 클라이언트에서는 서버에서 ACK를 받은 후에 서버가 남은 데이터 처리를 끝내고 FIN 패킷을 보낼 때까지 기다리게 되는 FIN_WAIT_2 상태에 들어간다.

4. 서버 -> 클라이언트

  • 서버가 모든 데이터 처리가 끝났다고 종료에 합의 한다는 뜻으로 클라이언트에게 FIN 플래그를 전송한 후 승인 번호를 보내줄 때까지 기다리는 LAST_ACK 상태로 들어간다.

5. 클라이언트 -> 서버

  • 클라이언트는 서버에서 FIN 패킷을 받고 다시 서버에게 ACK응답을 보낸 후에 TIME_WAIT 상태로 들어가며 실질적인 종료 과정(CLOSED)에 들어간다.
  • 이때 TIME_WAIT 상태는 의도치 않은 에러로 인해 연결이 데드락으로 빠지는 것을 방지하는데, 만약 에러로 인해 종료가 지연되다가 타임이 초과되면 CLOSED로 들어간다.

6. 서버

  • 서버는 ACK를 받고 CLOSED 상태로 들어가 종료하게 된다.

4. 그외 질문

Q. TCP 연결 설정 과정(3단계)과 연결 종료 과정(4단계)이 단계가 차이나는 이유는?

A. 클라이언트가 전송할 데이터가 없다고해도 서버에서 보내야하는 데이터가 아직 남아있을 수 있기 때문에 우선 FIN에 대한 ACK를 먼저 보내고 남은 데이터 전송 후에 FIN을 보낸다.

Q. 만약 서버에서 FIN 플래그를 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 상황이 발생하면 어떻게 될까?

A. 클라이언트에서 세션을 종료시킨 후 늦게 도착하는 패킷은 drop되고 데이터는 유실된다. 이런 상황에 대비하여 클라이언트는 서버로부터 FIN을 수신하고 일정시간(default 240sec)동안 세션을 남겨두고 잉여 패킷을 기다린다. (TIME_WAIT 과정)

Q. 초기 Sequence Number인 ISN을 0부터 시작하지 않고 난수를 생성해서 설정하는 이유?

초기 Sequence Number를 ISN(Initial Sequence Number)이라고 한다.

A1. Connection을 맺을 때 사용하는 Port는 유효한 범위 내에서 사용하고 시간이 지남에 따라 재사용한다.
-> 두 통신 호스트가 과거에 사용된 Port 번호 쌍을 사용하는 가능성이 존재한다.
서버에서는 SYN을 보고 패킷을 구분하고, 난수가 아닌 순차적 Number가 전송된다면 이전 Connection으로부터 오는 패킷으로 인식할 수 있다. 이런 문제의 가능성을 줄이기 위해 난수로 ISN을 설정한다.

A2. 0에서 시작하는 ISN은 이어지는 Seq를 쉽게 예측하게 만들어 공격에 취약해진다.


참고

https://velog.io/@arielgv829/CS-network-TCP-3-way-handshake-4-way-handshake
https://brunch.co.kr/@dreaminz/5
https://beenii.tistory.com/127
https://nays111.tistory.com/121

profile
아무것도 모르는 백엔드 3년차 개발자입니다 :)

0개의 댓글