TCP는 재전송을 기반으로 다양한 오류를 제어하고, 흐름 제어
를 통해 처리할 수 있을 만큼의 데이터만을 주고받으며, 혼잡 제어
를 통해 네트워크가 혼잡한 정도에 따라 전송량을 조절한다.
TCP 세그먼트에 오류 검출을 위한 체크섬 필드가 있지만, 체크섬은 세그먼트의 훼손 여부만 나타내고 송신 호스트가 세그먼트 전송과정에 문제가 있다는 것을 인지할 수는 없다.
신뢰성을 보장하기 위해서는
세그먼트를 재전송하는 상황에는 크게 두 가지가 있다.
RTT (Round Trip Time)
메시지를 전송한 뒤 그에 대한 답변을 받는 데까지 걸리는 시간
수신 호스트 측이 받은 세그먼트의 순서 번호 중에서 일부가 누락되었다면 중복된 ACK 세그먼트를 전송하게 된다.
호스트 A의 n+1번 세그먼트가 잘못 전송되었고, 그에 따라 호스트 B가 n+1번 ACK 세그먼트를 반복해서 전송한다.
TCP 세그먼트를 송신하는 호스트는 모두 재전송 타이머
라는 값을 유지한다.
세그먼트를 전송할 때마다 재전송 타이머가 시작되고, 타이머의 카운트다운이 끝난 상황을 타임아웃
이라 한다.
타임아웃이 발생할 때까지 ACK 세그먼트를 받지 못하면 세그먼트가 상대 호스트에게 정상적으로 도착하지 않았다고 간주하여 세그먼트를 재전송한다.
신뢰성을 보장하면서 빠른 속도로 패킷을 전송할 수 있다.
전송 후 대기 프로토콜은 형편없은 송신자 이용률을 갖는다.
이러한 방식 대신, 확인응답을 기다리지 않고 여러 패킷을 전송하도록 한다.
만약 확인응답을 기다리기 전에 송신자가 3개의 패킷을 전송하도록 허용한다면 송신자 이용률은 3배가 된다.
많은 전송 중인 송신자-수신자 패킷을 파이프라인에 채워 넣음으로써 나타낼 수 있다.
이를 파이프라이닝
이라고 한다.
순서 번호의 범위가 커져야 한다.
각각의 전송 중인 패킷은 유일한 순서 번호를 가져야 하는데, 전송 중인 확인 응답이 안된 패킷이 여럿 있을지도 모르기 때문이다.
프로토콜의 송신 측과 수신 측은 패킷 하나 이상을 버퍼링해야 한다.
최소한 송신자는 전송되었으나 확인응답되지 않은 패킷을 버퍼링해야 한다.
필요한 순서 번호의 범위와 버퍼링 조건은 데이터 전송 프로토콜이 손실 패킷과 손상 패킷 그리고 상당히 지연된 패킷들에 대해 응답하는 방식에 달려있다.
파이프라인 오류 회복의 두 가지 기본적인 접근 방법으로 GBN(Go-Back-N)과 SR(Selective Repeat) 등이 있다.
수신 호스트의 ACK와 타임아웃 발생을 토대로 문제를 진단하고, 문제가 생긴 메시지를 재전송함으로써 신뢰성을 확보하는 방식을 ARQ(Automatic Repeat Request)
라고 한다.
대표적으로 3가지의 방식이 있다.
제대로 전달했음을 확인하기 전까지는 새로운 메시지를 보내지 않는 방식이다.
단순하며 높은 신뢰성을 보장한다.
하지만 확인 응답을 받기 전까지 다음 전송을 할 수 있어도 하지 못하기에 네트워크 이용 효율이 낮아지고 성능의 저하로 이어질 수 있다.
Stop-and-Wait ARQ를 보완할 수 있는 파이프라이닝
방식을 사용한다.
파이프라이닝은 연속해서 메시지를 전송할 수 있는 기술을 말한다.
오늘날 TCP는 이러한 파이프라이닝이 사용되는 Go-Back-N ARQ
와 Selective Repeat ARQ
를 기반으로 동작한다.
Go-Back-N ARQ는 파이프라이닝 방식을 활용해 여러 세그먼트를 전송하고, 도중에 잘못 전송된 세그먼트가 발생할 경우 해당 세그먼트부터 전부 다시 전송하는 방식이다.
이러한 점에서 Go-Back-N ARQ의 ACK 세그먼트를 누적 확인 응답
이라고 한다.
빠른 재전송에 대해 설명해주세요.
빠른 재전송은 TCP 프로토콜의 세그먼트 송수신 과정에서 재전송 타이머가 만료되기 전이라도 세 번의 동일한 ACK 세그먼트가 수신되었다면 해당 세그먼트를 곧바로 재전송하는 기능입니다.
타임아웃이 발생하기 전에 재전송하므로 타이머가 끝날 때까지 기다리는 시간을 줄일 수 있으며 빠르게 손실된 세그먼트를 재전송함으로써 성능을 높이는 기능입니다.
Go-Back-N ARQ의 ACK 세그먼트가 누적 확인 응답
이라면, Selective Repeat ARQ의 ACK 세그먼트는 개별 확인 응답
인 셈이다.
송신 호스트는 올바르게 수신받지 못한 ACK 세그먼트가 있는지 검사하고, 만일 응답받지 못한 세그먼트가 존재한다면 해당 세그먼트를 재전송한다.
특정 패킷만을 재전송한다는 점은 효율적으로 보이지만, 받은 패킷을 재정렬하는 로직이 추가로 필요하다.
MSS
라고 한다.MSS는 MTU와 달리 헤더를 포함하는 TCP 세그먼트의 최대 크기가 아니라, 세그먼트에 있는 애플리케이션 계층 데이터에 대한 최대 크기이다.
필드 이름 | 설명 |
---|---|
출발지와 목적지 포트 | TCP는 UDP처럼 상위 계층 애플리케이션으로부터 다중화와 역다중화를 하는데 사용된다. |
체크섬 필드 | 데이터 유효성을 판단한다. |
순서 번호 필드 | . |
확인응답 번호 필드 | . |
수신 윈도 | 흐름 제어에 사용된다. 이는 수신자가 받아들이려는 바이트의 크기를 나타내는데 사용된다. |
헤더 길이 필드 | TCP의 헤더는 가변적인 길이가 될 수 있다. |
ACK 플래그 비트 | 확인응답 필드에 있는 값이 유효함을 가리키는데 사용한다. |
RST, SYN, FIN 플래그 비트 | 연결 설정과 해제에 사용된다. |
PSH 플래그 비트 | 수신자가 데이터를 상위 계층에 즉시 전달해야 함을 나타낸다. |
URG 플래그 비트 | 이 세그먼트에서 송신 측 상위 계층 개체가 '긴급'으로 표시하는 데이터임을 가리킨다. |
TCP는 데이터를 구조화되어 있지 않고 단지 순서대로 정렬되어 있는 바이트 스트림으로 본다.
TCP의 순서 번호 사용은 순서 번호가 일련의 전송된 세그먼트에 대해서가 아니라, 전송된 바이트의 스트림에 대해서라는 관점을 반영한 것이다.
(즉, 바이트 기준으로 sequense number를 설정한다.)
세그먼트에 대한 순서 번호는 세그먼트에 있는 첫 번째 바이트의 바이트 스트림 번호다.
확인 응답 번호는 송신자가 수신자로부터 기대하는 다음 바이트의 순서 번호다.
TCP는 스트림에서 첫 번째 잃어버린 바이트까지의 바이트들까지만 확인응답하기 때문에, TCP는 누적 확인 응답
을 제공한다고 한다.
[ 중복된 데이터를 전달받았을 때 가능한 동작 ]
1. 수신자가 순서가 바뀐 세그먼트를 즉시 버린다.
2. 수신자는 순서가 바뀐 데이터를 보유하고, 빈 공간에 잃어버린 데이터를 채우기 위해 기다린다.
[ Receive buffer, Send buffer ]
수신 버퍼
는 수신된 세그먼트가 애플리케이션 프로세스에 의해 읽히기 전에 임시로 저장되는 공간이다.
애플리케이션 프로세스는 버퍼에서 데이터를 읽지만, 데이터가 도달한 시점에 읽을 필요는 없으며, 애플리케이션이 데이터를 읽는 속도가 비교적 느리다면, 송신자가 점점 더 많은 데이터를 빠르게 전송함으로써 연결의 수신 버퍼에 아주 쉽게 오버플로를 발생시킬 것이다.
이처럼 송신 호스트가 흐름 제어를 고려하지 않고 수신 버퍼의 크기보다 많은 데이터를 전송하면 일부 세그먼트가 처리되지 못할 수도 있다.
이런 버퍼가 넘치는 문제 상황을 버퍼 오버플로
라고 한다.
TCP의 흐름제어
란 이러한 문제 상황을 방지하고자 송신 호스트가 수신 호스트의 처리 속도를 고려하여 송수신 속도를 균일하게 유지하는 것을 의미한다.
오늘날 TCP에서는 흐름 제어로 슬라이딩 윈도우
를 사용한다.
윈도우
란 송신 호스트가 파이프라이닝할 수 있는 최대량을 의미한다.
윈도우의 크기만큼 확인 응답을 받지 않고도 한 번에 전송 가능하다는 의미이다.
만약 수신 호스트가 첫 번째 세그먼트를 올바르게 수신했다면, 수신 윈도우는 오른쪽으로 한 칸 이동한다. 또 그렇게 세그먼트를 올바르게 수신했다면 수신 윈도우는 다시 한 번 오른쪽으로 한 칸 이동한다.
이렇듯 파이프라이닝 과정에서 송수신 윈도우는 오른쪽으로 미끄러지듯 움직이게 되며 이를 표현하여 슬라이딩 윈도우
라고 부르는 것이다.
수신 호스트는 TCP 헤더의 윈도우 필드
를 통해 송신 호스트에게 자신이 받아들이고자 하는 데이터의 양을 알리며, 송신 호스트는 이 정보를 바탕으로 수신 호스트의 처리 속도에 맞춰 세그먼트를 전송한다.
이때 할당된 수신 버퍼의 크기를 RcvBuffer
라고 한다.
호스트는 전송하는 모든 세그먼트의 윈도 필드에 현재의 rwnd 값을 설정함으로써 연결 버퍼에 얼마만큼의 여유 공간이 있는지를 상태 호스트에게 알려준다.
rwnd의 값보다 작은 확인응답 안된 데이터의 양을 유지함으로써 호스트는 상대 호스트의 수신 버퍼에 오버플로가 발생하지 않는다는 것을 확신한다.
TCP는 호스트가 상대 호스트의 수신 윈도가 0일 때, 1바이트 데이터로 세그먼트를 계속해서 전송하도록 요구한다.
이는 rwnd가 0이 됐을 때 상대 호스트는 더 이상 데이터를 전송하지 않는 문제 때문이다.
여기서 애플리케이션이 receive buffer의 데이터를 읽게 되면 여유 공간이 남게 되지만, 송신 호스트에게 전송할 데이터도, 받을 데이터도 없을 때 상대 송신 호스트는 언제 데이터를 보내야 하는지 알 수 없게 된다.
그래서 수신 윈도가 0일 때, 1바이트 데이터로 세그먼트를 계속해서 전송하여 수신 윈도의 상태를 확인한다.
흐름제어에 대해 설명해주세요
TCP 프로토콜의 세그먼트 송수신 과정에서 발생하는 버퍼 오퍼플로 문제를 방지하기 위한 기능입니다.
송신 호스트가 수신 호스트의 세그먼트 처리 속도를 고려하여 송수신 속도를 균일하게 유지하는 것을 의미합니다.
오늘날은 흐름제어로 슬라이딩 윈도우를 사용합니다.
혼잡이란 많은 트래픽으로 인해 패킷의 처리 속도가 늦어지거나 유실될 우려가 있는 네트워크 상황을 의미한다.
혼잡이 발생하면 라우터에 과부하가 생겨 모든 정보를 한 번에 처리하지 못할 수 있다.
TCP의 혼자 제어
란 이와 같은 혼잡을 제어하기 위한 기능이다.
흐름 제어의 주체가 수신 호스트라면, 혼잡 제어의 주체는 송신 호스트이다.
혼잡 윈도우
는 혼잡 없이 전송할 수 있을 법한 데이터의 양이다.
혼잡 윈도우의 크기는 송신 호스트가 어느 정도의 세그먼트를 전송해야 혼잡을 방지할 수 있는지를 직접 계산하여 알아내야 한다.
혼잡 윈도우의 크기는 혼잡 제어 알고리즘
을 통해 결정할 수 있다.
네트워크가 받아들일 수 있는 데이터의 양을 의미한다.
receive window
값가 congestion window
의 값 중 작은 값으로 설정하여 보내는 데이터의 양을 결정한다.
cwnd
로 표시되는 혼잡 윈도는 TCP 송신자가 네트워크로 트래픽을 전송할 수 있는 속도에 제약을 가한다.
즉, cwnd의 값을 조절하여, 송신자는 링크에 데이터를 전송하는 속도를 조절할 수 있다.
손실 이벤트가 발생할 때까지 ACK가 도착함에 따라 전송률을 증가시키고, 손실 이벤트가 발생한 시점에서 전송률을 줄인다.
그러므로 TCP 송신자는 혼잡이 발생하는 시점까지 전송률을 증가시키고, 그 시점 이후부터는 줄인 후 다시 혼잡 시작이 발생했는지를 보기 위한 탐색을 시작한다.
합으로 증가, 곱으로 감소라는 의미이다.
혼잡이 감지되지 않는다면 혼잡 윈도우를 RTT마다 1씩 선형적으로 증가시키고, 혼잡이 감지되면 혼잡 윈도우를 절반으로 떨어뜨리는 동작을 반복하는 알고리즘이다.
기본적인 혼잡 제어 알고리즘이지만, 이것만으로는 혼잡 제어가 이루어지지 않는다.
이를 위해 더 정교하게 만든 혼잡 제어 알고리즘들이 있다.
느린 시작
혼잡 회피
빠른 회복
느린 시작 알고리즘
은 혼잡 윈도우를 1 MSS부터 시작해 문제없이 수신된 ACK 세그먼트 하나당 1 MSS씩 증가시키는 방식이다.
AIMD 방식은 선형적으로 혼잡 윈도우를 증가시키므로 초기 전송 속도가 확보되지 않는다. 하지만 느린 시작을 이용하면 혼잡 윈도우의 지수적인 증가를 활용해 초기 전송 속도를 확보할 수 있다.
혼잡 윈도우 값이 계속 증가하다가 느린 시작 임계치
이상이 되거나, 타임아웃이 발생하거나, 세번의 중복된 ACK 세그먼트가 발생하여 혼잡이 감지되면 다음 세 가지 방법 중 하나를 선택하게 된다.
상황 | 방법 |
---|---|
타임아웃 발생 | 혼잡 윈도우 값을 1 MSS로, 느린 시작 임계치를 혼잡이 감지되었을 시점의 혼잡 윈도우 값의 절반으로 초기화한 뒤 느린 시작 재개 |
혼잡 윈도우 >= 느린 시작 임계치 | 느린 시작 종료, 혼잡 회피 수행 |
세 번의 중복 ACK 발생 | (빠른 재전송 후) 빠른 회복 수행 |
3번의 중복 ACK는 특정 패킷이 운이 나빠 제대로 전송되지 않은 것이고, 이후 다른 패킷은 잘 전송되었다는 것을 알 수 있다.
하지만 타임아웃은 특정 패킷 이후로 데이터가 전송되지 않는다는 것을 의미하므로, 네트워크의 혼잡도는 타임아웃으로 인한 Loss일 때 더 높다는 것을 알 수 있다.
그렇기에 타임아웃으로 인한 loss일 때 cwnd를 1로 줄여서 다시 느린 시작을 시작하여 느린 시작 임계값인 ssthresh를 cwnd/2로 정한다.
cwnd 값이 ssthresh와 같아지면, 느린 시작은 종료되고, TCP는 혼잡 회피 모드로 들어가 cwnd 값이 linear하게 증가하게 된다.
3 duplicate ACK일 경우에는 cwnd를 절반으로 줄인 후 다시 시작한다. 즉, 빠른 재전송을 수행하여 빠른 회복 상태로 들어간다.
(TCP Reno의 경우 해당 시점의 절반 cwnd부터 다시 AIMD로 증가)
혼잡 회피 알고리즘
은 RTT마다 혼잡 윈도우를 1MSS씩 증가시키는 알고리즘이다.
느린 시작 임계치를 넘어선 시점부터는 혼잡이 발생할 우려가 있으니 조심해서 혼잡 윈도우를 증가시키는 방식이다.
혼잡 회피 도중 타임아웃이 발생하면 혼잡 윈도우 값은 1로, 느린 시작 임계치는 혼잡이 감지된 시점의 혼잡 윈도우 값의 절반으로 초기화한 뒤 다시 느린 시작을 수행한다.
혼잡 회피 도중 세 번의 중복 ACK 세그먼트
가 발생되었을 때는 빠른 회복 알고리즘을 수행한다.
세 번의 중복된 ACK 세그먼트를 수신하면 빠른 재전송과 더불어 빠른 회복 알고리즘이 수행된다.
빠른 회복 알고리즘은 세 번의 중복 ACK 세그먼트를 수신했을 때 느린 시작은 건너뛰고 혼잡 회피를 수행하는 알고리즘으로, 빠르게 전송률을 회복하기 위한 알고리즘이다.
윈도우 크기를 반으로 줄인 후 선형적으로 증가시키며 임계점을 줄어든 윈도우 값으로 설정한다.
단, 빠른 회복 도중 타임아웃이 발생하면 혼잡 윈도우 크기는 1로, 느린 시작 임계치는 혼잡이 감지된 시점의 절반으로 떨어뜨린 후 다시 느린 시작을 수행한다.
혼잡 제어에 대해 설명해주세요.
TCP 프로토콜의 세그먼트 전송 과정에서 발생하는 네트워크 혼잡을 처리하는 방식입니다.
네트워크의 혼잡도를 판단하고 혼잡한 정도에 따라 전송량을 조절합니다.
AIMD, 느린 시작, 혼잡 회피, 빠른 회복 등의 알고리즘이 사용될 수 있습니다.
TCP Tahoe
는 처음에는 느린 시작을 사용하다가 임계점에 도달하면 AIMD
방식을 사용한다.
그러다가 3 ACK Duplicated
또는 타임아웃
이 발생하면 혼잡이라고 판단하여 임계점은 혼잡이 발생한 윈도우 크기의 절반으로, 윈도우 크기는 1로 줄인 후 느린 시작을 시작한다.
이 방식은 혼잡 이후 slow start 구간에서 윈도우 크기를 키울 때 너무 오래 걸린다는 단점이 있다. 1부터 키워나가야 하기 때문이다.
그래서 나온 방식이 빠른 회복
방식을 활용한 TCP Reno
이다.
TCP Tahoe
와 마찬가지로 slow start로 시작하여 임계점을 넘어가면 AIMD
방식으로 변경한다.
TCP Tahoe
와의 차이점은 바로 3 ACK Duplicated
와 타임 아웃
을 구분한다는 점이다.
TCP Reno
는 3 ACK Duplicated
가 발생하면 빠른 회복
방식을 사용한다.
즉, 윈도우 크기를 1로 줄이는 것이 아니라 반으로 줄이고, 윈도우 크기를 선형적으로 증가시킨다.
그리고 임계점을 줄어든 윈도우 값으로 설정한다.
만약, 타임 아웃
이 발생하면 TCP Tahoe
와 마찬가지로 윈도우 크기를 1로 줄이고 slow start를 진행한다.
이때는 임계점을 변경하지 않는다.
전송 속도를 절반으로 줄인 다음 시간이 지남에 따라 천천히 증가시키는 것은 지나치게 신중한 일일 수 있다.
패킷 손실이 발생한 혼잡한 링크의 상태가 많이 변경되지 않은 경우, 전송 속도를 더 빠르게 높여 손실 전 전송 속도에 근접한 다음 대역폭을 신중하게 조사하는 것이 좋을 것이다.
이것이 TCP 큐빅의 특징이다.
큐빅은 손실 전 속도인 w에 가까워지도록 TCP의 전송 속도를 빠르게 증가시킨 다음, w에 가까워지면 대역폭을 조심스럽게 탐지한다.
congestion 상황은 짧은 시간내에 바뀌지 않기 때문에 해소된 후에 빠르게 다시 최대 데이터 전송 속도를 점유할 수 있는 방법이다.
이전엔 TCP 송신자가 네트워크에서 명시적인 혼잡 표시를 수신하지 않는 대신, 관찰된 패킷 손실을 통해 혼잡을 추론했다.
명시적 혼잡 알림
은 네트워크 계층에서 IP 데이터그램 헤더의 서비스 유형 필드에 있는 2비트가 ECN에 사용되어 라우터가 정체를 겪고 있음을 TCP 송-수신자에게 알려주는 것이다.
ECN 비트의 한 설정은 라우터가 정체를 겪고 있음을 나타내기 위해 라우터에서 사용된다.
이 혼잡 표시는 표시된 IP 데이터그램에서 목적지 호스트로 전달되어 송신 호스트에게 알린다.
수신 호스트의 TCP가 수신 데이터그램을 통해 ECN 혼잡 알림 표시를 수신하면, 수신 호스트의 TCP는 수신자-송신자 TCP ACK 세그먼트의 ECE(Explicit Congestion Notification Echo)비트를 설정하여 송신 호스트의 TCP에 혼잡 표시를 알린다.
TCP 송신자는 혼잡 윈도를 절반으로 줄여 혼잡 알림 표시가 있는 ACK에 반응하고 다음 전송되는 TCP 수신자 세그먼트 헤더에 CWR(Congestion Window Reduced) 비트를 1로 설정한다.
송신자는 이를 통해 패킷 손실 이전에 더 일찍 전송 속도를 줄일 수 있으므로 값비싼 패킷 손실 및 재전송을 피할 수 있게 된다.
NEXT. 응용 계층, DNS
도서
혼자 공부하는 네트워크