- Transport-layer services
- Multiplexing & demultiplexing
- Connectionless transport: UDP
- Principles of reliable data transfer
- Connection-oriented transport: TCP
5-1. segment structure
5-2. reliable data transfer
5-3. flow control
5-4. connection management- Principles of congestion control
- TCP congestion control
- Evolution of transport layer funcitonality
TCP segment Header
위 그림에서 처럼 syn, fin, sequence number, acknowledge number, window size 등이 활용되고 있음을 알 수 있다.
TCP는 신뢰성 있는 데이터 전송을 보장하기 위해 sequence number를 사용해 현재 segment의 data의 첫 byte가 byte stream에서 몇 번째에 위치하고 있는지 표시한다.
Acknowledgement도 마찬가지로 신뢰성을 보장하기 위해 sender가 보낸 segment가 receiver에서 제대로 받았음을 확인하기 위해 존재하며, receiver에서 다음에 받아야할 데이터의 sequence number를 뜻한다. TCP는 cumulative ACK 방식을 사용하여 receiver에서 ACK 번호를 보낼 때 해당 번호 이전에 존재하는 모든 데이터가 정상 수신되었음을 보장해준다.
Sender와 receiver는 각각 buffer를 가지고 있다. Sender는 buffer에 in flight 중인 segment들을 저장하고 혹시 retransmit이 필요하면 꺼내서 사용한다. Receiver는 buffer에 수신한 segment들을 저장하고 in-order가 완성되면 내보낸다.
Q. How receiver handles out-of-order segments?
A. TCP spec doesn't say. Up to implementor. (Discard or buffering)
이처럼 receiver의 ack은 sender의 seq + 1의 값이고, sender의 ack은 receiver의 seq값이다.
Q. How to set TCP timeout value?
Q. How to estimate RTT?
한 번에 하나의 segment만 주고받을 수도 있고, 여러 segment를 pipelining을 통해 주고받을 수도 있다. 그러나 이런 상황에 관계 없이 timer가 1개 뿐이기에 한 번에 RTT를 하나씩만 측정이 가능하다.
그래서, 두 번째 예시의 경우 1번 seg 전송 때 부터 시작된 timer가 2번까지 ack이 되고 나서 끝이나고, 두 번째 4번째 seg 전송 때 부터 시작된 timer가 3번째 ack이 들어오자마자 끝이난다. 즉, pipelining으로 인해 값 간의 격차가 커진다.
그래서 sampleRTT를 기록하면 굉장히 뒤죽박죽인 값이 나오게 된다. 이를 완화시키고자 EstimatedRTT를 도입해 부드럽게 만든 것을 볼 수 있다.
EstimatedRTT = (1 - ) X EstimatedRTT + X SampleRTT
Exponential Weighted Moving Average (EWMA) 알고리즘을 적용한 것.
timeout interval은 EstimatedRTT에 safety margin을 더한 개념이다.
TimeoutInterval = EstimatedRTT + 4 X DevRTT
DevRTT = (1 - ) X DevRTT + X |SampleRTT - EstimatedRTT|
Exponential backoff는 congestion control 매커니즘으로, congestion을 줄이고 network congestion collapse를 막기 위해 사용된다.
라우터나 스위치와 같은 네트워크 장치가 전송할 패킷을 처리할 속도보다 빨리 패킷을 받으면 혼잡해질 수 있습니다. 혼잡 붕괴를 방지하기 위해 장치는 패킷을 삭제하고 송신자에게 전송 속도를 줄이도록 신호를 보낼 것입니다. 이에 따라 송신자는 전송 속도를 줄이고 전송한 각 패킷에 대한 확인(ACK)을 수신 대기합니다.
송신자가 패킷에 대한 ACK를 수신하지 못하면 혼잡 때문에 패킷이 손실되었다고 가정하고 일정 시간 동안 기다린 후 패킷을 재전송합니다. 다시 전송한 패킷이 손실된 경우, 송신자는 패킷을 다시 전송하기 전에 대기 시간을 더 늘립니다. 이 대기 시간을 "백오프 시간"이라고 합니다.
지수 백오프는 패킷이 손실될 때마다 백오프 시간을 지수적으로 증가시켜 가면서 작동합니다. 예를 들어, 송신자는 1초의 백오프 시간으로 시작하고 패킷이 손실되면 백오프 시간을 2초, 4초, 8초 등으로 지수적으로 증가시킵니다. 이 과정을 반복하여 패킷이 성공적으로 전송될 때까지 계속됩니다.
이러한 메커니즘은 네트워크 혼잡이 감지될 때 패킷 전송 속도를 줄여 혼잡을 예방하는 데 도움이 됩니다. 백오프 시간을 지수적으로 증가시킴으로써 제어된 방식으로 네트워크 혼잡 붕괴를 방지하는 데도 도움이 됩니다.
첫 번째는 In-Sequence Segment Arrival 이벤트.
두 번째도 In-Sequence Segment Arrival 이벤트.
세 번째는 Out-of-Order Segment Arrival 이벤트.
네 번째도 Out-of-Order Segment Arrival 이벤트.
+) RFC 문서 내용
Specifically, an ACK should be generated for at least every second full-sized segment, and must be generated within 500ms of the arrival of the first unacknowledged packet.
TCP 송신자가 full-sized segment를 전송할 때마다 적어도 두 번째 전송된 Segment마다 ACK를 보내야 한다는 의미입니다. 이는 TCP 송신자가 데이터 전송의 효율성을 높이기 위해 가능한 많은 데이터를 전송할 수 있도록 하기 위한 조치입니다.
TCP 송신자가 ACK를 보내지 않은 첫 번째 패킷이 도착한 후 500ms 이내에 ACK를 보내야 한다는 것을 의미합니다. 이는 TCP 통신에서 패킷 손실을 탐지하고 재전송을 수행하기 위한 Timeout과 관련된 사항입니다. 만약 Timeout이 발생하면, 송신자는 재전송을 시작하여 데이터 전송의 완료를 보장합니다. 이러한 방식으로 TCP는 안정적이고 신뢰성 높은 데이터 전송을 지원합니다.
만약 sender가 같은 데이터에 대해 3개의 ACK을 추가적으로 수신하면 (three duplicate ACKs), unACKed된 segment들 중에 가장 작은 seq#를 가지는 것을 resend한다. 마치 해당 segment를 lost된 것처럼 처리해서 timeout이 발생할때까지 기다리지 않게 한다. (이 방식이 fast retransmit)
이 그림에서처럼 도중에 2번째 segment가 lost되며, ACK 100이 수신된 후 추가로 3개가 더 들어왔다. A 입장에선 timeout이 아직 되진 않았지만, fast retransmit에 의해 2번 segment가 lost라고 추측해 retransmit한다.
Application은 TCP socket buffer에서 데이터를 제거하고, network layer는 IP datagram payload를 전달한다. 만약 네트워크 레이어가 데이터를 전달하는 속도가 어플리케이션에서 빼가는 속도보다 빠르면 buffer overflow가 발생하게 된다.
이를 방지 하기 위해 TCP segment의 header에 포함된 receive window 정보를 이용해 receiver가 수용가능한 byte 수를 파악해 flow control을 수행하게 된다. Receiver가 sender를 control하여 sender가 너무 많이 전송해서 receiver의 buffer를 overflow하게 되지 않도록 방지한다.
+) Q. Window size는 주로 64K, 어떨 때는 128K도 가진다. 근데 receive window는 16bit밖에 안되는데 이게 어떻게 가능할까?
A. Option field에는 window scale factor가 존재하며, 이를 multiply하여 표현 가능 범위 이상의 크기를 가질 수 있게 된 것.
TCP는 데이터를 교환하기 전에 sender와 receiver 사이에 connection을 만드는 "handshake" 과정이 존재한다. 이때 서로가 connection을 만들기를 원해야 하며, 시작하는 sequence #와 같은 connection parameter에 합의를 봐야 한다.
+) HW 2 부분을 통해 TCP connection 과정에서 header 파악 부분 연습.
+) 합의가 있다는 부분에서 알 수 있듯이, sender와 receiver는 저마다 sequence number를 가지고 있다.
3-way handshake는 3번의 communicate로 connection이 setup된다는 것.
먼저, server에서 socket을 만들고 client로부터 connection request를 오기를 listen하며 기다린다 (LISTEN).
다음, client에서 socket을 만들며(LISTEN), 서버의 주소와 포트를 입력해 connect를 시도한다. (SYNSENT) 이때, synbit=1 표시로 synchronization 과정임을 알리고, seq #도 알린다.
이제 server에서 해당 request를 받으며 (SYN RCVD) 자신이 사용할 seq #도 정하고, SYN과 ACK 표시로 성공적으로 수신했음을 알린다.
Client는 해당 response를 받아 서버의 존재를 확인하고, SYNACK를 정상적으로 받았음을 알리는 ACK을 보낸다.(ESTAB)
마지막으로 server도 해당 ACK을 받아 클라이언트의 존재를 확인하고 connection을 종료한다. (ESTAB)