TCP 재전송 — RTO, Fast Retransmit, SACK
TCP가 신뢰성을 보장하는 핵심은 "패킷이 손실되면 다시 보낸다"는 재전송 메커니즘입니다. 언제, 어떻게 재전송하느냐에 따라 성능이 크게 달라집니다.
RTO (Retransmission Timeout)
ACK를 일정 시간 내에 받지 못하면 패킷을 재전송합니다.
송신자 수신자
│── 패킷 1 ──────────→│
│ │
│ (ACK가 안 옴) │
│ │
│ RTO 타이머 만료! │
│ │
│── 패킷 1 (재전송) ──→│
│ │
│←──── ACK ────────────│
RTO 계산
RTO는 RTT(Round Trip Time)을 기반으로 동적 계산됩니다.
SRTT = (1-α) × SRTT + α × RTT_sample (α = 1/8)
RTTVAR = (1-β) × RTTVAR + β × |SRTT - RTT_sample| (β = 1/4)
RTO = SRTT + 4 × RTTVAR
- RTT가 안정적이면 → RTO가 작음 → 빠른 재전송 감지
- RTT가 불안정하면 → RTO가 큼 → 불필요한 재전송 방지
RTO 최소값은 보통 200ms, 재전송 실패 시 지수적 백오프(1s → 2s → 4s → 8s...).
Fast Retransmit (빠른 재전송)
3개의 중복 ACK 를 받으면 타이머 만료를 기다리지 않고 즉시 재전송합니다.
송신자 수신자
│── 패킷 1 ──────────→│ ACK 2
│── 패킷 2 ──────────→│ (손실!)
│── 패킷 3 ──────────→│ ACK 2 (중복 1)
│── 패킷 4 ──────────→│ ACK 2 (중복 2)
│── 패킷 5 ──────────→│ ACK 2 (중복 3)
│ │
│ 3 Dup ACK 감지! │
│── 패킷 2 (재전송) ──→│ ACK 6 (누적 ACK)
RTO 대기(수백 ms)보다 훨씬 빠르게 재전송할 수 있습니다.
SACK (Selective ACK)
기본 TCP ACK는 "여기까지 받았다"(누적 ACK)만 알려줍니다. SACK은 어떤 패킷을 받았고 어떤 패킷이 빠졌는지 상세하게 알려줍니다.
누적 ACK만 사용:
수신: 1, 2, (3 손실), 4, 5, 6
ACK: "2번까지 받았어" → 송신자는 3~6을 모두 재전송? 3만?
SACK 사용:
ACK: "2번까지 받았어, 그리고 4~6도 받았어"
→ 송신자는 3만 재전송하면 됨!
# SACK 활성화 확인 (리눅스 기본 활성)
cat /proc/sys/net/ipv4/tcp_sack
# 1
재전송 관련 커널 파라미터
# 최대 재전송 횟수 (이후 연결 종료)
cat /proc/sys/net/ipv4/tcp_retries2 # 기본 15 (약 924초)
# SYN 재전송 횟수
cat /proc/sys/net/ipv4/tcp_syn_retries # 기본 6
# 타임스탬프 (RTT 측정 정확도)
cat /proc/sys/net/ipv4/tcp_timestamps # 기본 1
핵심 포인트
- RTO vs Fast Retransmit: RTO는 최후의 수단(느림), Fast Retransmit은 3 Dup ACK으로 빠르게
- SACK의 장점: 필요한 패킷만 선택적으로 재전송 → 대역폭 절약
- Spurious Retransmission: RTT가 갑자기 늘어나 RTO가 잘못 발동 → DSACK으로 감지
정리
TCP 재전송은 신뢰성의 핵심이지만, 무작정 재전송하면 네트워크를 더 악화시킵니다. RTO로 기본 보장하고, Fast Retransmit으로 빠르게 대응하며, SACK으로 불필요한 재전송을 줄이는 것이 현대 TCP의 전략입니다.