리팩토링

리팩토링 4주차 TCP

idea5021 2024. 8. 9. 13:39
목차

1. TCP란


2. TCP 헤더 구조


3. TCP 연결 3-way HandShaking


4. TCP 연결 해제(4-way-HandShaking)


5. TCP Retransmission(재전송)



 

 

1. TCP란

  • Transmission Control Protocol의 약자로, OSI 7계층 중 전송 계층에서 사용되고 있는 프로토콜로, 장비들 간의 통신 과정에서 정보를 안정적으로, 순서대로, 에러없이 교환할 수 있도록 하는 것에 목적을 둔 프로토콜이다.

   1)주요특징

  • 신뢰성 : TCP는 데이터의 분실, 중복 또는 오류가 발생할경우 재전송을 수행함
  • 연결 지향적 : 통신을 시작하기 전에 송수신자간에 연결을 설정
  • 흐름 제어 : 네트워크의 혼잡도를 감지하고 데이터 전송 속도를 조절하여 효율적인 통신을 유지함
  • 혼잡 제어 : 네트워크 혼잡에 대처
  • 순서 보장 : 데이터는 전송 순서대로 목적지에 도착함
  • 전이중 : 두 대의 모뎀이 동시에 데이터를 전송 및 수신할 수 있음    

 

2. TCP 헤더구조

TCP Header 구조

 

 

  • Sourse(발신지) / Destination(목적지) Port Number ( 각 16비트)
    • IP 주소 + 포트 번호 => 소켓 주소
    • 소켓 주소를 가지고 양쪽 호스트 내 종단 프로세스 식별 
  • Sequence Number (32비트)
    • 바이트 단위로 구분되어 순서화되는 번호 => TCP에서는 신뢰성 및 흐름제어 기능 제공
    • 순서의 시작은 임의 값으로 시작하여 최대(4,294,967,295) 이후에는 '0'으로 시작
    • 송신 데이터에 번호를 새김으로서 수신자는 쪼개진 세그먼트의 순서를 파악하여 올바른 순서로 데이터를 재조립 할수있음
  • Acknowledgement Number (확인응답 번호 / 승인 번호) (32비트)
    • (마지막 수신 성공 순서번호 + 1) => 수신자가 받을 다음 바이트 번호

확인 응답

 

  • Header length, HLEN (헤더 길이 필드) (4비트)
    • TCP 헤더 길이를 4바이트(32비트)로 표시
    • 최소 20byte, 최대 60byte까지
  • 예약 (6비트)
    • 추후 사용을 위한 예약된 필드
  • Flag bits (9비트) 각 플래그마다 1비트 사용 ,실제로 사용되는 것은 6개로 (URG,ACK,PSH,RST,SYN,FIN)
    • URG
      • Urgent Pointer 필드에 값이 채워져있음을 알림
      • 송신측 상위 계층이 긴급 데이터라고 알려주면, 긴급비트 URG를 1로 설정하고 순서에 상관없이 먼저 송신
      • 긴급 데이터의 마지막 바이트 위치가 Urgent Pointer로 가리켜짐 
      • 평상시에는 사용안함
    • ACK
      • 확인응답 필드에 확인응답번호( Acknowledgement Number ) 값이 셋팅됐음을 알림
      • 1로 세팅 => 확인응답번호 유효
      • 0로 셋팅 =>  확인응번호 미포함 ( 즉, 32비트 크기의 ACK필드 무시)
    • PSH
      • 버퍼링된 데이터를 가능한 빨리 상위 계층에 즉시 전달
      • 수신측은 버퍼가 찰 때까지 기다리지 않고 수신 즉시 버퍼링된 데이터를 응용프로그램에 전달
      • 플래그 0 => 수신측은 자신의 버퍼가 다 채워질 때까지 기다림
      • 플래그 1 => 이 세그먼트 이후에 더 이상 연결된 세그먼트가 없음을 의미 
    • RST
      • 연결확립된 회선에 강제 리셋 요청
      • RST=1  => 강제 리셋
      • 공격자들이 패킷을 가로채기위해서 많이 사용
    • SYN
      • 상대방과 연결을 생성할 때, 시퀀스 번호의 동기화를 맞추기 위한 세그먼트
      • 연결 요청 : SYN=1, ACK=0 (SYN 세그먼트)
      • 연결 허락 : SYN=1, ACK=1 (SYN+ACK 세그먼트)
      • 연결 설정 : ACK=1              (ACK 세그먼트)
    • FIN
      • 송신기가 데이터 보내기를 끝마침
      • 종결 요청 : FIN=1  (FIN 세그먼트)
      • 종결 응답 : FIN=1, ACK=1  (FIN+ACK 세그먼트)
    • 명시적 혼잡통보(Explicit Congestion Notification, ECN)
      • 송신자와 수신자에게 네트워크의 혼잡 상황을 명시적으로 알리기 위한 특별한 매커니즘
      • CWR, ECE, ECT, CE플래그를 사용하여 상대방에게 혼잡 상태를 알려줄 수 있는데, 이 중 CWR, ECE는 TCP헤더에 존재하고 ECT, CE는 IP헤더에 존재
      • NS : ECN에서 사용하는 CWR, ECE 필드가 실수나 악의적으로 은폐되는 경우를 방어하기 위해 RFC 3540에 추가된 필드
      • ECE : ECN Echo 플래그, 해당 필드가 1이면서, SYN 플래그가 1일 때는 ECN을 사용한다고 상대방에게 알리는 의미이다. SYN 플래그가 0이라면 네트워크가 혼잡하니 세그먼트 위도우의 크기를 줄여달라는 요청의 의미
      • CWR : 이미 ECE 플래그를 받아서, 전송하는 세그먼트 윈도우의 크기를 줄였다는 의미
  • Window size (16비트)
    • 흐름제어를 위해 사용되는 16비트 필드 (65,535 byte까지 가능)
    • TCP 흐름제어를 위해 송신자에게 자신의 수신 버퍼 여유용량 크기를 지속적으로 통보
    • TCP 연결은 양방향이므로, 매 TCP 세그먼트를 보낼때마다 이 필드에 자신의 수신 버퍼 용량 값을 채워 보내게 됨
    • 결국 양방향 각각의 수신측에 의해 능동적으로 흐름제어를 수행하게 됨
  • Cheksum (16비트)
    • 데이터를 송신하는 중에 발생할 수 있는 데이터의 변조나 깨지는것을 확인하기 위해 사용
    • 송신측에서 전송할 모든 데이터를 16비트 단위로 구분하고 2진수로 변환 후 
    • 1의 보수를 취하고, 그 합에 대한 결과를 전송하면 수신측에서 같은 합을 계산해 오류를 검출하는 방식
  • Urgent pointer (16비트)
    • URG 플래그가 1이라면 수신 측은 이 포인터가 가리키고 있는 데이터를 우선 처리한다. 
  • Options
    • TCP의 기능을 확장할 때 사용하는 필드
    • 최대 40byte까지 옵션 데이터 포함 가능
    • 윈도우 사이즈의 최대 값 표현을 확장하는 WSCALE
    • Select Repeat 방식을 사용하기 위한 SACK 등이 있음

 

3. TCP 3-way HandShaking

  • TCP 프로토콜을 이용해서 통신하는 응용프로그램은 데이터를 주고받기 전에 연결을 진행한다.

TCP 3-way HandShaking

 

1) 클라이언트 --------(SYN)----------> 서버

  • 클라이언트가 서버에게 연결을 요청하는 SYN Segment를 보낸다.
  • Segment Header의 SYN bit를 1로 설정한다.
  • Sequence Number는 클라이언트의 최초 순서 번호 ISN으로 설정한다. 그림에서는 J
  • 확인응답 번호, 윈도우 크기 필드는 미 정의되고 응용계층의 데이터를 포함하지 않는다.
  • 클라이언트는 SYN Segment를 전송한 후 SYN-SENT 상태로 서버의 ACK Segment를 기다린다.
  • 서버는 LISTEN상태가 된다.

2) 클라이언트 <--------(ACK + SYN)----------서버

  • 서버가 클라이언트의 SYN Segment에 대한 ACK Segment를 전송한다.
    • Acknowledge Number(승인번호)는 클라이언트의 ISN+1로 설정한다. 그림에서는 J+1
    • 윈도우 크기 필드 정의됨
    • Sequence Number는 서버의 최초 순서번호 ISN으로 설정한다.
  •  동시에 서버가 클라이언트에게연결을 요청하는 SYN Segment를 전송한다.
    • SYN bit를 1로 설정한다.
    • 서버는 SYN/ACK Segment를 전송하고 SYN-RECEIVED의 상태로 클라이언트의 ACK를 기다린다.
  • 클라이언트는 서버의 ACK + SYN을 받고 ESTABLISHED 상태로 들어감

 

3) 클라이언트-------(ACK)------->서버

  • 클라이언트는 서버의 SYN Segment에 대한 ACK Segment를 전송한다.
  • 연결 요청이아니기 때문에 SYN bit는 0이고 ACK bit는 1로 설정
  • 서버는 ACK Segment를 받고 연결이 완료된 ESTABLISHED 상태가 되면서 데이터 송수신이 이루어진다.

 

*최초 순서 번호(ISN)

  • 랜덤 수를 선택한 후 상대에게 전송
  • 순서번호 초기화 직후 상대와의 순서번호 동기화 목적
  • TCP는 양방향이므로 각 방향 마다 다른 ISN 번호가 사용 

 


 

4. TCP 연결 해제(4-way-HandShaking)

 

TCP 연결해제 과정

 

1) 클라이언트 ------------(FIN)-----------> 서버

  • 클라이언트가 서버에게 연결 종료를 요청하는 FIN 세그먼트를 보냄
    • FIN 비트를 1로 설정 + 순서번호
  • 클라이언트는 전송 후 FIN_WAIT_1 상태가됨
  • 서버는 자신의 소켓 프로세스에게 종료를 요청하며 기다리는 CLOSE-WAIT 상태가 됨

 

2) 클라이언트 <----------------(ACK)----------서버

  • 서버는 FIN을 받고 확인했다는 ACK를 클라이언트에게 보내고 자신의 소켓이 종료될때까지 기다린다.
  • 아직 남은 데이터가 있다면 마저 전송을 마친 후에  자신의 종료를 호출한다.
  • 클라이언트는 ACK를 받은 후에 서버가 남은 데이터 처리를 끝내고 FIN 패킷을 보낼 때까지 FIN_WAIT_2 상태로 기다린다.

3) 클라이언트 <------------------(FIN)-------------서버

  • 서버가 소켓을 정상적으로 종료했다는 의미로 FIN 패킷을 클라이언트에게 보낸다.
  • 서버는 ACK를 받을때까지 LAST_ACK상태가 된다.
  • 클라이언트는 종료됬다는 신호를 전달받고 확인했다는 의미로 ACK를 보내게 되는데 이때 ACK가 유실되어 요청 수신 측에서 소켓이 제거되지 않는 문제점이 발생할 수 있다. 그러므로 일정 시간 동안 대기하는 TIME_WAIT상태가 된다. 
  • 일정 시간이 지난후 클라이언트는 Closed 상태가 된다. 

4) 클라이언트 -------(ACK)-----------> 서버

  • 클라이언트는 FIN을 받고 응답 ACK를 서버에게 보낸다.
  • 서버는 ACK를 받은 이후 Closed상태가 된다. 

 


 

5. TCP Retransmission(재전송)

 

  • TCP는 송신에 대한 응답이 오지않는 경우 일정시간을 대기 후에 다시 재전송을 한다.
  • 송신자는 패킷을 송신하고 나면 별도로 정의된 Timer를 시작한다. 그리고 Timer의 시간이 만료되면 다시 패킷을 전송한다. => 기본적인 재전송 과정

 

재전송이 발생할 수 있는 상황

  • Packet lost
    • 송신자는 패킷을 보냈지만, 어떤 이유에서인지 중간에 패킷이 유실되어 수신측에 도달하지 못했다.
    • 수신측은 당연히 패킷이 도착하지 않았으므로 ACK를보내줄리가 없고 송신자의 Timer는 만료된다. 
  • ACK lost
    • 송신자가 패킷을 보냈고, 수신 측 또한 응답으로 ACK를 보냄
    • 중간에 ACK가 유실되어 송신자에게 도착하지 못하고 송신자의 Timer는 만료된다. 
  • Early Timeout
    • 송신자가 패킷을 보냈고, 수신 측에서 응답으로 ACK를 보냈다. 그러나 네트워크 지연이 발생해서 송신자의 Timer가 만료되어버린 후에 ACK가 송신자에게 도착한다.
  • 도착한 패킷의 순서가 틀릴경우

위의 3가지 상황에서 공통점은 Timeout 시간 안에 ACK를 받지 못한 것으로 이것을 해결하기 위해 할 수 있는 최선은 바로 최선의 Timeout 시간을 정의하는 것이다.

하지만 Timeout 시간이 지나치게 짧으면 재전송 패킷의 낭비가, 지나치게 길면 패킷이 손실되었을 때 기다려야하는 시간이 너무 길어진다.

따라서 어떤 기준을 통해서 정의된 시간을 통해서 재전송하는 과정을  RTO(Retransmission Time out)라는 개념이다.

 

RTO는 운영체제 커널에 정의가 되어있다.

운영체제 별로 초기값을 갖고 있지만, 모든 네트워크 상황이 다르므로 RTO는 동적으로 변한다.

RTO는 RTT에 의해서 변하는데, RTT는 호스트 간 송신에 대한 응답을 받기까지 걸리는 시간을 의미한다.

 

측정된 RTT를 SampleRTT라고 할 때

단점으로는 재전송이 발생했을 경우, 응답해온 ACK가 Original에 대한 응답인지 재전송에 대한 응답인지 구분하기가 어렵다는 단점이 있다.

 

재전송에는 Timeout이 최선인 것 같지만 다른 대안이 있다.

 

Triple-Duplicate-ACK

  • 3개의 중복된 ACK를 받으면 재전송하는 방법
  • 불필요한 시간 지연이 발생하지 않고, 수신자의 ACK를 일종의 타이머 처럼 사용하기 때문에 최대한 빠른 재전송을 시작할 수 있음