알아볼 내용
- TCP 오류 제어
- TCP 흐름 제어
- TCP 혼잡 제어
오류 제어: 재전송 기법
- 신뢰성을 보장하려면 오류 제어가 필요 → TCP는 잘못된 세그먼트를 재전송
- 체크섬은 세그먼트 훼손 여부만 나타내고 바로 폐기하기 때문에 송신 호스트가 문제 생겼다는 것을 인지할 수 없음
오류 검출과 재전송
- TCP가 신뢰성 보장하려면 다음이 필요
- 송신 호스트가 송신한 세그먼트에 문제가 생겼음을 인지
- 오류 감지하면 해당 세그먼트 재전송
세그먼트 문제 감지하는 방법
-
중복된 ACK 세그먼트 수신
- 정상적인 상황
호스트 A -> 호스트 B : n번 세그먼트 전송 호스트 B -> 호스트 A : n+1번 세그먼트 요청 (ACK) 호스트 A -> 호스트 B : n+1번 세그먼트 전송 호스트 B -> 호스트 A : n+2번 세그먼트 요청 (ACK) ...
- 문제 상황 : 수신 호스트가 못 받은 세그먼트에 대한 ACK 세그먼트를 계속 전송
호스트 A -> 호스트 B : n번 세그먼트 전송 호스트 B -> 호스트 A : n+1번 세그먼트 요청 (ACK) 호스트 A -> 호스트 B : n+1번 세그먼트 전송 실패 호스트 B -> 호스트 A : n+1번 세그먼트 요청 (ACK) <- 반복 요청 ...
RTT (Rount Trip Time)
- 메시지를 전송한 후 답변 받기까지 걸리는 시간
- 호스트 A가 호스트 B에 n번 세그먼트를 전송하고 호스트 B로부터 ACK 세그먼트를 받기까지 걸리는 시간
- 정상적인 상황
-
타임아웃 발생
- 송신 호스트는 ‘재전송 타이머’ 값을 유지하며 세그먼트를 전송할 때마다 재전송 타이머를 시작
- 이 타이머의 카운트다운이 끝난 상황을 타임 아웃이라고 함
- 타임 아웃이 발생할 때까지 ACK 세그먼트 못 받은 경우 송신에 문제 생겼다고 판단
- 송신 호스트는 ‘재전송 타이머’ 값을 유지하며 세그먼트를 전송할 때마다 재전송 타이머를 시작
재전송 기법 (ARQ, Automatic Repeat Request)
-
Stop-and-Wait ARQ : 제대로 전달했음을 확인하기 전까지 새로운 메시지 보내지 않음
- 단순하지만 높은 신뢰성 보장
- 많이 사용하지는 않음
- 단점 : ACK 세그먼트를 받아야 다음 송신을 하기 때문에 네트워크 이용 효율 낮아지고 성능 저하
-
Go-Back-N ARQ : 파이프라이닝 방식으로 여러 세그먼트 전송하고 문제 발생하면 해당 세그먼트부터 재전송
- 파이프라이닝 : ACK 세그먼트 도착 전이어도 여러 메시지 전송할 수 있는 기술
- n~n+5 번 세그먼트를 보냈는데, n+2 번 세그먼트에 대한 ACK 세그먼트를 못 받은 경우
- 수신 호스트 : n+3 번 세그먼트부터 폐기하고 다시 수신 & n+1번 세그먼트에 대한 ACK 세그먼트 계속 송신
- 송신 호스트 : n+2 번 세그먼트에 대한 타임아웃 발생하면 n+2 번 세그먼트부터 재전송
- 이 방식에서 ‘n 번에 대한’ ACK 세그먼트는 ‘n 번까지의’ 확인 응답의 의미 → ACK 세그먼트를 CACK (Cumulative Acknowledgement) 로도 표현
- ‘빠른 재전송1’을 사용해서 시간 낭비 줄일 수 있음
- 단점 : 한 세그먼트에 문제가 생겨도 그 이후 모든 세그먼트 재전송
-
Selective Repeat ARQ : 수신 호스트 측에서 제대로 전송받은 각각의 패킷들에 대해 ACK 세그먼트 전송해서 문제 생긴 세그먼트만 재전송
- 오늘날 대부분의 호스트가 지원하는 방식이고 지원안할 경우 Go-Back-N ARQ 사용
- TCP 세그먼트의 옵션 필드 내에 ‘SACK 허용’ 필드 값으로 지원 여부 판단 가능
- 오늘날 대부분의 호스트가 지원하는 방식이고 지원안할 경우 Go-Back-N ARQ 사용
흐름 제어: 슬라이딩 윈도우
- 호스트가 한 번에 받아서 처리할 수 있는 세그먼트 양은 한계가 있어서 흐름 제어 필수
- Go-Back-N, Selective Repeat ARQ 에서 중요함
- 버퍼 오버플로 : 수신 호스트가 갖는 수신 버퍼2 보다 더 많은 데이터를 전송할 경우 발생
- 따라서 처리 속도를 고려하여 송수신 속도 균일하게 유지할 필요가 있음
슬라이딩 윈도우
- 윈도우 : 송신 호스트가 파이프라이닝 할 수 있는 바이트의 최대량으로 ACK 응답 없이 보낼 수 있는 양
- TCP 세그먼트 헤더의 윈도우 필드에 명시
- 수신 호스트는 TCP 헤더를 통해 자신의 윈도우를 알리고, 송신 호스트 이를 바탕으로 적당한 양의 세그먼트를 한 번에 송신
- 동작 방식 (윈도우 크기 4)
- 연결 수립 과정에서 수신 호스트가 윈도우 크기 알려줌
- 송신 호스트가 세그먼트 1, 2, 3, 4 모두 전송
- 수신 호스트가 도착하는 대로 ACK 세그먼트 보냄
- 송신 호스트가 세그먼트 1에 대한 ACK 받으면 윈도우는 2, 3, 4, 5로 이동해서 다음 세그먼트 전송
- 즉 윈도우는 “이미 보냈지만 아직 미확인된 데이터 + 새롭게 보낼 수 있게 된 데이터” 포함
혼잡 제어
- 혼잡 : 많은 트래픽으로 인해 패킷의 처리 속도가 늦어지거나 유실될 유려가 있는 네트워크 상황
- 라우터 1개에 여려 호스트가 연결되어 있는 상황에서 각 호스트가 전송 가능한 최대 양으로 세그먼트 전송하면 라우터에 과부하 발생 → 오류 검출 → 재전송 → 혼잡 악화
- 혼잡 윈도우 : 혼잡 없이 전송할 수 있을 법한 데이터양
- 송신 호스트가 직접 계산해서 알아내야 함
혼잡 제어 알고리즘 : 혼잡 윈도우 크기를 결정하는 방법
AIMD (Additive Increase/Multiplicative Decrease) : 혼잡 감지되면 윈도우 RTT마다 1씩 증가, 혼잡 감지되면 윈도우 절반으로 감소
- 가장 기본적인 알고리즘
- 톱니 모양으로 혼잡 윈도우 크기가 변함
- 혼잡 윈도우 증가 속도가 느려 초기 전송 속도 확보 어려움
느린 시작 알고리즘 : 윈도우를 1부터 시작해 문제없이 수신된 ACK 세그먼트 하나당 1씩 증가
- RTT마다 2배씩 지수적으로 증가
- 윈도우 크기 1 → 1개 보내고 ACK 1개 받음 → 윈도우 크기 2 → 2개 보내고 ACK 2개 받음 → 윈도우 크기 4 → …
- 초기 전송 속도 어느 정도 빠르게 확보 가능
- 하지만 계속 증가만 하기 때문에 언젠가는 혼잡 상황 마주칠 가능성 높아 ‘느린 시작 임계치’ 값 설정
- 혼잡 감지 상황별 대처
- 타임아웃 발생 : 혼잡 윈도우 값은 1, 느린 시작 임계치 값은 혼잡 감지 시점의 절반 값으로 초기화한 후 알고리즘 재개
- 혼잡 윈도우 >= 느린 시작 임계치 : 느린 시작 종료, 혼잡 회피 수행
- 세 번의 중복 ACK 발생 : 빠른 재전송 후 빠른 회복 수행
RWND, CWND, SSTHRESH
TCP의 상태를 관리하는 상태 변수의 형태로 존재
- RWND (Receiver WiNDow) : 수신 윈도우
- CWND (Congestion WiNDow) : 혼잡 윈도우
- SSTHRESH (Slow Start THRESHold) : 느린 시작 임계치
혼잡 회피 알고리즘 : RTT마다 혼잡 윈도우를 1MSS 만큼 증가
- 크기 선형적으로 증가
- 느린 시작 임계치 넘어선 시점부터는 혼잡 발생할 우려 있으니 천천히 증가시키는 것
- 혼잡 감지 상황별 대처
- 타임아웃 발생 : 혼잡 윈도우 값은 1, 느린 시작 임계치 값은 혼잡 감지 시점의 절반 값으로 초기화한 후 알고리즘 재개
- 세 번의 중복 ACK 발생 : 혼잡 윈도우 값과 느린 시작 임계치를 대략 절반으로 떨어뜨리고 빠른 회복 알고리즘
빠른 재전송 / 빠른 회복 알고리즘 : 세 번의 중복 ACK 세그먼트 수신 시 느린 시작 건너뛰고 혼잡 회피 수행
- 전송률을 빠르게 회복하기 위함
- 타임 아웃 발생 시 혼잡 윈도우 값은 1, 느린 시작 임계치 값은 혼잡 감지 시점의 절반 값으로 초기화한 후 알고리즘 재개
실제 동작 방식
3개의 알고리즘은 서로 별개의 개념이긴 한데, TCP의 실제 동작에서는 “순차적이면서도 유기적으로 섞어서” 사용
- 연결 생성 → 느린 시작
- ssthresh 도달 → 혼잡 회피
- 패킷 손실(중복 ACK 3회) → 빠른 재전송/빠른 회복
- 회복 후 다시 혼잡 회피로 복귀
- 패킷 손실(타임아웃) → 느린 시작으로 재진입
수신 윈도우 vs 혼잡 윈도우
- 송신자가 실제로 한 번에 보낼 수 있는 데이터 양 = min(rwnd, cwnd)
- TCP 소켓은 계속 min(rwnd, cwnd) 값을 체크하면서 “한 번에 보낼 수 있는 데이터”를 결정
명시적 혼잡 알림 (ECN, Explicit Congestion Notification)
최근에 혼잡을 피하기 위해 등장한 라우터와 같은 네트워크 중간 장치의 도움을 받는 방법
- ECN 지원 호스트는 IP 헤더와 TCP 헤더에 ECN 관련 필드 추가
- 동작 방식
- 호스트 A가 호스트 B에게 메시지 전송 위해 라우터에 메시지 보냄
- 라우터가 혼잡해질 것 같다고 판단하면, IP헤더의 ECN 비트를 설정하고 B에게 메시지 전달
- 11로 설정되면 ‘혼잡을 감지했다’는 의미
- 호스트 B가 전달받은 IP 패킷 내에 혼잡 표시가 되어 있다면, TCP ACK 세그먼트 내 ECE 비트 세팅을 통해 송신 호스트에게 네크워크 혼잡 전달
- 호스트 A가 응답받은 세그먼트에서 ECE 비트 설정된 경우, CWR 비트를 세팅 후 혼잡 윈도우 절반으로 감소
- 효과
- ECN 이용 X : 송신 호스트만 혼잡 제어 수행. 문제가 발생한 이후에 혼잡 제어 실시
- ECN 이용 : 수신 호스트의 ACK 세그먼트로 빠르게 혼잡 감지
Footnotes
-
재전송 타이머 만료 전이라도 세 번의 동일한 ACK 세그먼트 수신할 경우 해당 세그먼트 재전송 ↩
-
수신된 세그먼트가 읽히기 전 임시 저장되는 공간 ↩
-
https://velog.io/@jyok0120/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-Ch-3.-Transport-layer-part5 ↩
-
https://ai-com.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-TCP-Congestion-Control-2-%EA%B8%B0%EB%B3%B8-%EB%8F%99%EC%9E%91 ↩