Connection-oriented transport: TCP

KVV·2024년 12월 3일

TCP는 오류 검출, 재전송, 누적 확인응답, 타이머, 순서 번호, 확인응답 번호를 위한 헤더 필드를 가지고 있다.

A) TCP Connection

Connection-oriented: TCP Application process끼리 데이터를 주고받기 전에, 두 process가 서로 Handshake를 해야 한다.

TCP Connection: 두 End system의 TCP에 존재하는 상태를 공유하는 논리적인 것으로, End system간의 TCP 연결만 유지되며 중간의 Network core들은 TCP 연결 상태를 유지하지 않는다.

TCP 특징

  1. Full-duplex service: Application layer message는 Host A에서 Host B로 흐르는 동시에 A에서 B로도 흐를 수 있다.

  2. Point-to-point: 항상 단일 송신자에서 단일 수신자로만 데이터 전송이 가능하다.

    • Multicasting의 정반대

TCP 연결 설정 (Three-way handshake)

한 Host에서 동작하는 프로세스가 다른 Host와의 연결을 초기화하기를 원한다고 가정하자.

Client process: 연결을 초기화하는 process
Server process: 다른 process

  1. Client process는 Server process와 연결을 설정하기를 원한다고 TCP client에게 먼저 알린다.

    • Client의 Transport layer에서 특별한 TCP segment를 전송한다.
  2. Server는 두 번째 특별한 TCP Segment로 응답한다.

  3. Client가 세 번째 특별한 Segment로 다시 응답한다.

(1), (2)의 segment에는 payload (즉, Application layer message) 가 없다.
(3)의 Segment는 payload를 포함할 수 있다.

TCP 데이터 전송

Three-way handshake가 이루어지면, 두 application process는 서로 데이터를 보낼 수 있다.

  1. Client process는 socket을 통해 데이터 스트림을 전달하고 TCP는 데이터를 Send buffer로 보낸다.

    • 이 과정에서 TCP는 Segment로 데이터를 묶어 보낼 수 있다.
    • TCP Segment: TCP Header + client data
    • 최대 데이터의 양은 MSS(Maximum Segment Size)로 제한된다.
  2. Segment 처리 이후, Network layer에 전달되며, Network layer IP datagram안에 캡슐화된다.

  3. Datagram은 Network로 송신되며, TCP가 상대에게세 Segment를 수신한다면 해당 Segment는 TCP Receive buffer에 위치한다.

  4. Application은 Receive buffer로부터 데이터 스트림을 읽는다.

B) TCP Segment structure

TCP Segment는 Header field, Data field 로 구성되어 있다.

1. Data field

  • Application data의 일정량을 담는다.
  • MSS에 의해 data field의 크기가 제한될 수 있다.

2. Header field

  • Source / Destination port number
    • Multiplexing / Demultiplexing에 사용한다.
  • Checksum field
    • 오류 검출에 사용한다.
  • 32 bit sqeunce number field & 32 bit acknowledgment number field
    • Reliable data transmission에 사용한다.
  • 16 bit receive window field
    • Congestion control에 사용한다.
  • 4 bit header length field
    • 이 field로 표현하는 것은 실제로 32 bit (4 byte) 단위이다.
    • 4 bit header length: 1 이라면 실제 길이는 4 byte이다.
    • option field로 인해 가변적인 길이가 될 수 있다.
  • Option field
    • MSS 협상, window 확장 등에 사용한다.
  • 6 bit flag field
    • ACK bit: Acknowledgment number field의 값이 유용함을 가리킨다.
    • RST / SYN / FIN bit: 연결 설정과 해제에 사용한다.
    • PSH bit: 수신자가 데이터를 상위 계층에 즉시 전달해야함을 가리킨다.
    • URG bit: 송신 측 상위 계층 개체가 ""Urgent""로 표시하는 데이터임을 가리킨다.
      • 이때, 데이터의 마지막 byte의 위치는 16 bit urgent data pointer field에 의해 가리켜진다.

Sequence number & Acknowledgment number

TCP의 Reliable data transfer에 가장 중요한 field이다.

TCP가 Sequence number field를 채우는 방법

전제: TCP는 데이터를 구조화되지 않고 단지 순서대로 정렬되어 있는 바이트 스트림으로 본다.

  1. 송신 Host는 데이트 스트림의 총 Byte를 MSS의 크기로 나누어 segment를 구성한다.
  2. 각 Segment마다 Sequence number는 해당 Segment에존재하는 첫 번째 바이트의 바이트 스트림 번호이다.

위의 그림에서 두 번째 segment의 sequence number는 1000이다.

TCP가 Acknowledgment number field를 채우는 방법

전제: TCP는 Full-duplex service이다.

  1. 수신 Host는 송신 Host로부터 기대하는다음 바이트의 Sequence number를 Acknowledgment number field에 삽입한다.

Cumulative acknowledgment: TCP는 스트림에서 잃어버린 바이트까지의 바이트들까지만 확인 응답한다.

  • EX) 수신 호스트가 0~555 까지의 바이트와 900~1000의 바이트를 수신했을 때, Acknowledgment number는 556이다.
  • 이 경우, 수신자는 순서가 바뀐 segment를 즉시 버리거나, buffer에 중간 바이트가 도착할 때까지 저장할 수도 있다.
  • Cumulative acknowledgment number - 1 byte까지는 수신했다는 의미를 내포한다.

C) RTT expectation & Timeout

Timeout은 데이터를 보내고 acknowledgment packet을 받는 RTT보다 조금 더 커야 한다.

RTT expectation

SampleRTT: Segment가 송신된 시간으로부터 그 Segment에 대한 긍정 응답이 도착한 시간 길이

  • TCP는 송신 후 아직 확인 응답이 없는 Segment 중 한 번에 하나의 Segment의 SampleRTT 측정만을 시행한다.
  • 재전송한 segment에 대한 SampleRTT는 계산하지 않는다.
  • 불안정성으로 인해 Segment 마다 값의 차이가 발생한다.

EsimatedRTT: 불규칙적인 SampleRTT 대신 RTT를 추정하기 위해 사용하는 SampleRTT의 평균값

  • 새로운 SampleRTT를 획득하자마자 EstimatedRTT를 갱신한다.
  • EstimatedRTT = (1 - α\alpha) \cdot EstimatedRTT + α\alpha \cdot SampleRTT
  • α\alpha = 0.125 가 권장되는 값이다.
  • SampleRTT 값의 Weighted average이다.

DevRTT: RTT의 변화율

  • SampleRT가 EstimatedRTT로부터 얼마나 많이 벗어나는지에 대한 예측
  • DevRTT = (1 - β\beta) \cdot DevRTT + β\beta \cdot |SampleRTT - EstimatedRTT|
    • β\beta = 0.25 가 권장되는 값이다.

Exponential weighted moving average: Estimated에서의 SampleRTT와 DevRTT에서의 |SampleRTT - EstimatedRTT|

  • 두 값은 값이 갱신될 수록 가중치가 빠르게 지수적으로 감소한다.

재전송 타임아웃 주기의 설정과 관리

Timeout은 EstimatedRTT에 약간의 여윳값을 더한 값으로 설정하는 것이 좋다.

  • Timeout은 EstimatedRTT보다 반드시 크거나 같아야 한다.
  • 너무 크다면 즉각적인 재전송이 불가능하기 때문에 안 된다.
  • SampleRTT의 변동이 많다면 여윳값을 크게 하고, 아니라면 여윳값을 작게 한다.

TimeoutInterval = EstimatedRTT + 4 \cdot DevRTT

  • EstimatedRTT가 수정되면 TimeoutInterval을 위 공식에 따라 다시 계산한다.
  • 초기 TimeoutInterval은 1초가 권장된다.

D) Reliable Data Transfer

TCP는 Reliable data transfer service를 제공한다.

  • Receive buffer로부터 읽은 byte stream이 손상되지 않았으며 손실이나 중복이 없고, 순서가 유지된다는 것을 보장한다.
  • TCP protocol은 확인 응답되지 않은 Segment 중 하나에만 동작하는 단일 재전송 타이머를 사용한다.

TCP의 Reliable data transfer service 과정

TCP 송신자 측은 세 가지의 주요 Event를 가지고 있다.

  1. 상위 Application으로부터 데이터 수신

    • 데이터를 받고, Segment로 캡슐화한 후 IP에게 전달한다.
    • Timer가 다른 Segment에 대해 실행 중이 아니면, TCP는 Timer를 시작한다.
  2. Timer timeout

    • Timeout event가 발생하면 송신자는 Timeout을 일으킨 Segment를 재전송하고 TCP의 Timer를 다시 시작한다.
  3. ACK 수신

    • SendBase(수신 확인응답이 확인되지 않은 가장 오래된 바이트의 Sequence number) 와 ACK의 값을 (y라고 하자) 비교한다.
    • y > SendBase: ACK는 이전에 확인 응답이 되지 않은 하나 이상의 Segment를 확인하고 송신자는 자신의 SendBase의 값을 갱신한다.

TCP Data transfer의 세 가지 가능성

  1. ACK Packet loss
  • ACK Paket이 손실되면, Host A는 Data를 재전송할 것이다.
  • Host B가 재전송 Segment를 수신했을 때, Host B는 이미 수신된 데이터임을 확인하고 버릴 것이다.
  1. 두 개의 Data packet에 대한 어떠한 ACK도 받지 못한 경우
  • Timeout 이전에 Sequence number 92에 대한 ACK를 받지 못하였기 때문에 Sequence number 92 packet을 재전송하고 타이머를 다시 시작한다.
  • 재전송된 Segment에 대해 Host B는 이미 모든 데이터를 수신했으므로 ACK = 120 을 전송한다.
  1. 첫 번째 Segment에 대한 Timer 동안 두 번째 Segment에 대한 ACK가 도착한 경우
  • 첫 번째 ACK Packet은 손실됬지만 두 번째 ACK Packet은 시간 내에 도착했다.
  • TCP는 로이기 때문에 두 번째 ACK Packet만으로도 첫 번째 Data를 수신했음을 확인할 수 있다.

TCP 구현에서 사용하는 몇 가지 수정사항

1. Timeout Interval

  • TCP는 Timeout이 발생할 때, 아직 확인 응답이 되지 않은 가장 작은 Sequence number를 가진 Segment를 재전송한다.
  • 이때, TCP는 단순하게 Timeout Interval을 2배 증가시킨다.
  • 재전송이 아닌 다른 Event인 경우에는 DevRTT, EstimatedRTT로 부터 TimeInterval을 계산하여 사용한다.

2. Fast Retransmit

  • 재전송 시 Timeout Interval을 2배씩 증가시키기 때문에, Timeout Inteval이 너무 커져 빠른 재전송이 불가능할 수 있다.
  • Duplicate ACK: 송신자가 이미 이전에 받은 확인 응답에 대한 재확인응답 Segment ACK
    • 수신자가 여러 개의 Data를 전송하였을 때, 중간에 하나의 Packet이 손실되었다면 같은 ACK가 여러개 수신될 수 있다.

  • 2번째 packet이 손실되어 3개의 Duplicate ACK가 수신되었다.
  • Fast Retransmit: 송신자는 Timeout 이전에 손실 Segment를 재전송하였다.

Q) TCP는 GBN인가 SR인가?

TCP는 GBN과 SR protocol의 혼합이다.

GBN과 유사하다?

  • TCP는 순서가 잘못된 segment는 개별적으로 ACK를 받지 않는다.
  • 송신자는 SendBase 와 NextSeqNum을 유지해야한다는 점에서 GBN과 유사해 보인다.

GBN과의 차이점
송신자가 1, 2, ..., N Segment를 전송하고, 1, ... , n Segment만이 ACK되었다고 가정하자.

  • GBN: n, n+1, ..., N 의 모든 Segment를 재전송한다.
  • TCP: n Segment만을 재전송하고, 만약 Timeout 이전에 n+1 ACK가 도착한다면 재전송조차 하지 않는다.

Selective acknowledgment: 수신자가 마지막으로 올바르게 수신된 Segment에 대해 Cumulative acknowledgment을 하기 보다는 순서가 틀린 segment에 대해 선택적으로 확인 응답을 하게 한다.

  • 이것은 오히려 SR protocol과 유사하다.
  • 이 관점에서, TCP는 GBN과 SR protocol의 혼합이라고 할 수 있다.

E) Flow Control

Receive buffer에 저장된 data를 Application이 바로 읽지 않으면 데이터가 쌓여 Receive buffer에 overflow가 발생할 수 있다.

해결책: TCP Flow-control service

송신자의 데이터 전송 속도 = 수신자의 데이터 리딩 속도을 유지하도록 하는 서비스

  • 송신자가 수신자의 Buffer를 Overflow시키는 것을 방지하기 위해 사용한다.
  • IP Network에서의 혼잡을 제어하는 Congestion control과는 다른 것이다.

TCP 수신자가 순서가 바뀐 Segment는 버린다고 가정하자.

Flow control 세팅

할당된 Receive buffer size를 RcvBuffer라고 하자

  1. 송신자는 수신 측에서 가용한 Buffer space가 얼마나 되는지 송신자에게 알려주는 Receive window라는 변수를 유지한다.

    • TCP는 Full-duplex이므로 각 측의 송신자는 별개의 Receive window를 유지한다.
  2. 수신자의 Application process는 Buffer로부터 데이터를 읽으며 LastByteRead와 LastBtyeRcvd 변수를 세팅한다.

    • LastByteRead: Host B의 Application process에 의해 Buffer로부터 읽힌 데이터 스트림의 마지막 byte number
    • LastBtyeRcvd: Host B의 Receive Buffer에 저장된 데이터 스트림의 마지막 byte number
    • TCP는 할당된 Buffer의 Overflow를 허용하지 않는다.
    • RcvBuffer \ge LastByteRcvd - LastByteRead
  3. rwnd라는 변수를 Update되는 다른 변수에 맞게 변경한다.

    • rwnd: Buffer의 여유 공간
    • rwnd = RcvBuffer - {LastByteRcvd - LastByteRead}

Flow control 방법

  1. Host B는 Host A에 전송하는 모든 Segment의 Window field에 현재의 rwnd 값을 설정한다.

    • 초기에는 rwnd = RcvBeffer
  2. Host A는 LastByteSent와 LastByteAcked를 유지한다.

    • {LastByteSent - LastByteAcked}는 Host A가 해당 연결에 전송 확인 응답이 되지 않은 데이터의 양이다.
  3. (1), (2)의 과정에서 전송 확인 응답이 되지 않은 데이터의 양이 rwnd보다 작다면 Overflow가 발생하지 않음을 확신할 수 있다.

    • rwnd \ge LastByteSent - LastByteAcked

문제점

Host B의 rwnd = 0이고 Host A에게 전송할 것이 없다고 가정하자.

  1. Host B의 Buffer가 비워지더라도 TCP는 Host A에게 새로운 rwnd로 segment를 전송하지 않는다.

  2. Host A는 Host B의 buffer에 여유 공간이 있다는 것을 알 수 없기 때문에 데이터를 더 이상 전송될 수 없다.

이런 문제를 해결하기 위해, TCP는 Host A와 Host B의 receive window가 0일 때, 1 byte data로 segment를 계속하여 전송하도록 요구한다.

  • 1 byte segment는 수신자에 의해 긍정 확인 응답되고, 이 긍정 확인 응답은 0이 아닌 rwnd 값을 포함한다.

F) TCP connection 관리

TCP conncetion setting - Three-way handshake

  1. Client TCP는 Server TCP에게 Application data를 포함하지 않지만 SYN bit (flag bit) = 1인 Segment를 전송한다.

    • 이 Segment를 SYN segment라고 한다.
    • 클라이언트는 최소 순서 번호(client_isn)를 임의로 선택하고, 최초의 TCP SYN 세그먼트의 순서 번호 필드에 이 번호를 넣는다.
  2. SYN segment가 Server host에 도착하면 Server는 SYN segment를 추출하고 TCP buffer와 변수를 할당한다. 이후, 연결 승인 segment를 송신한다.

    • 연결 승인 segment에는 Application data를 포함하지 않고, SYN bit = 1, Acknowledgment field = client_isn + 1로 설정한다.
    • Server는 자신의 최초의 server_isn (순서 번호)를 선택하고 Header의 Sequence number field에 이 값을 넣는다.
    • SYNACK segment라고 불린다.
  3. SYNACK segment를 수신하면, Client는 TCP buffer와 변수를 할당하고, SYNACK segment를 확인하는 또 다른 Segment를 송신한다.

    • Acknowledgment field = server_isn + 1 값을 넣음으로써 SYNACK segment를 확인한다.
    • 이 단계에서는 Application data를 Segment payload에 포함할 수 있다.
    • 이 Segment부터 시작하여, 이후 전송되는 Segment의 SYN bit = 0이다.

TCP Connection Close

TCP Connection이 종료될 때, Host의 자원 (Buffer, Variable)은 회수된다.
Client가 연결 종료를 결정한다고 가정하자.

  1. Client process는 종료 명령을 내리고, Server process에 FIN bit = 1을 header에 포함하는 특별한 TCP Segment를 보내도록 한다.

  2. Server가 이 Segment를 수신하면, Server는 Client에게 Acknowledgment Segment를 보낸다.

  3. 이후 Server는 FIN bit = 1로 설정된 자신의 종료 Segment를 송신한다.

  4. Client는 Server의 종료 Segment의 Acknowledgment Segment를 보낸다.

(4)의 시점에서, 두 Host의 모든 자원을 할당 해제된다.

TCP Connection State

Client와 Server로 나누어 살펴보자.

TCP Client

TCP Connection Setting
1. Closed: Closed 상태에서 시작한다.
2. SYN_SENT: SYN segment를 전송하며 TCP Connection을 시작한다.
3. ESTABLISHED: Server로부터 SYN, ACK segment를 수신한 후의 상태

TCP Connection Close
4. FIN_WAIT_1: FIN bit = 1을 포함하는 TCP segment를 송신한 상태
5. FIN_WAIT_2: Server로부터 확인응답을 포함하는 Segment를 받은 상태
6. TIME_WAIT: Server로부터 FIN bit = 1을 포함하는 Segment를 받고, Server에 확인 응답으 전송한 후에 상태

- 대기 시간이 종료되면 연결이 정식으로 종료되고, Client 측의 모든 자원이 해제된다.

TCP Server

TCP Connection Setting
1. Closed: Closed 상태에서 시작한다.
2. LISTEN: Client로부터 SYN segment를 수신하고, SYN과 ACK segment를 송신한다.
3. ESTABLISHED: Client로부터 ACK segment를 수신한 후의 상태

TCP Connection Close
4. ESTABLISHED: Client로부터 FIN segment를 받고, ACK Segment를 송신한다.
5. CLOSE_WAIT: FIN bit = 1 segment를 송신한다.
6. LAST_ACK: Client로부터 ACK Segment를 받고, 연결을 종료한다.

Q) 만약 어떠한 Socket과 관계없는 Port number와 IP address를 가진 TCP segment를 수신한다면?

수신 Host는 송신 Host로 RST Flag bit = 1로 설정된 Reset segment를 보낸다.

0개의 댓글