Швидкісні зашифровані магістралі та корпоративні віртуальні приватні мережі покладаються на протокол TCP для надійної доставки даних. Під час проходження пакетів через складні інтернет-маршрути, стільникові вишки або нестабільні з'єднання Wi-Fi періодичні втрати є неминучими. Те, яким чином транспортний рівень реагує на втрату пакетів, визначає, чи відчує користувач ледь помітну мікропаузу, чи зіткнеться з повним зависанням з'єднання та різким зростанням затримки через переповнення буферів (bufferbloat).
Протягом майже двох десятиліть стандартом було використання класичних механізмів швидкого відновлення (Fast Recovery), описаних у RFC 3517 та RFC 5681. Ці алгоритми мали суттєвий недолік: зафіксувавши втрату, вони повністю зупиняли передачу даних, а потім генерували раптовий сплеск пакетів, створюючи небезпечні перебої в роботі мережі. Стандарт IETF RFC 6937 — Proportional Rate Reduction (PRR) — докорінно змінив цей підхід, рівномірно розподіляючи відправку пакетів протягом усього циклу відновлення та усуваючи штучні паузи.
Проблема бульбашки в конвеєрі: як класичне швидке відновлення блокує TCP
У традиційній системі контролю перевантажень надходження трьох дубльованих підтверджень (Duplicate ACK) свідчить про те, що канал зв'язку не може впоратися з поточним вікном перевантаження (CWND). Протокол удвічі зменшує CWND, призначаючи новий поріг повільного старту (ssthresh). Хоча зменшення темпу передачі необхідне для розвантаження проміжних маршрутизаторів, стара схема виконання породжувала важкі побічні ефекти.
Відповідно до RFC 3517 відправник відстежує обсяг неподтверджених даних у дорозі (FlightSize). Під час втрати пакета поточне значення FlightSize зазвичай значно перевищує новий поріг ssthresh:
Зафіксовано втрату пакета:
Початковий стан: CWND = 40 пакетів, FlightSize = 40 пакетів
Цільовий стан : ssthresh = 20 пакетів
Реакція класичного відновлення:
Повне зупинення відправки, доки FlightSize не знизиться з 40 до 20.
Тривалість тиші: Близько половини часу кругового обігу (0.5 * RTT).
Ця вимушена пауза утворює «бульбашку в конвеєрі» (pipeline bubble). Протягом половини RTT відправник не надсилає жодного нового пакета. Черга на вузькому місці каналу миттєво спустошується. Коли FlightSize нарешті опускається до ssthresh, відправник різко відновлює роботу, виливаючи цілу пачку пакетів у спорожнілий канал. Цей раптовий сплеск миттєво переповнює черги маршрутизаторів, спричиняючи вторинні втрати та зрив передачі в тайм-аут повторного надсилання (RTO). У тунелях VPN це призводить до зависання відеодзвінків та стрибків пінгу на сотні мілісекунд.
Математична анатомія RFC 6937: механіка пропорційного зниження швидкості
Стандарт RFC 6937 замінює зупинку передачі неперервним пропорційним пейсингом. Замість пасивного очікування зниження FlightSize алгоритм PRR відправляє нові сегменти на кожне отримане селективне підтвердження (SACK), плавно наближаючи темп передачі до рівня ssthresh протягом усього періоду відновлення.
Алгоритм використовує дві ключові змінні стану:
prr_delivered: Загальний обсяг даних, успішно доставлених та підтверджених блоками SACK від початку відновлення.prr_out: Загальний обсяг нових або повторно надісланих даних, відправлених у мережу після фіксації втрати.
Машина станів PRR розраховує точну кількість дозволених байтів для кожного підтвердження за пропорційною формулою:
Target_Ratio = ssthresh / RecoverFS
sndcnt = ceil(prr_delivered * Target_Ratio) - prr_out
Тут RecoverFS показує обсяг даних у дорозі в момент виявлення втрати. Якщо ssthresh становить половину від RecoverFS, цільове співвідношення дорівнює Target_Ratio = 0.5. Це означає, що на кожні 2 байти, підтверджені отримувачем, відправник негайно передає 1 байт нових даних. Передача не переривається, черги розвантажуються плавно й передбачувано, а мережевий конвеєр залишається рівномірно заповненим.
Динаміка граничних станів: порівняння режимів PRR-CRB та PRR-SSRB
Хоча пропорційна формула чудово працює за звичайних умов, у реальних мережах трапляються нерівномірні інтервали надходження ACK, повторні втрати пакетів та порушення їхньої послідовності. Для забезпечення надійності RFC 6937 визначає два граничні режими: консервативну межу швидкості (CRB) та межу уповільненого зниження (SSRB).
+-------------------------------------------------------------+
| Обробка вхідного пакета ACK |
+-------------------------------------------------------------+
|
v
[Перевірка: FlightSize > ssthresh?]
/ ТАК НІ
/ v v
+---------------------------+ +------------------------------+
| Режим PRR або CRB | | Режим PRR-SSRB |
| sndcnt = min(PRR, Deliv) | | sndcnt = min(Deliv+1, Target)|
+---------------------------+ +------------------------------+
Консервативна межа швидкості (CRB) для сценаріїв значних втрат та порушення черговості
У разі значних втрат пакетів або затримок ACK обсяг даних у дорозі FlightSize може тривалий час перевищувати ssthresh. За таких умов агресивна передача лише погіршить ситуацію. Режим PRR-CRB слугує надійним обмежувачем:
sndcnt = min(sndcnt, Delivered_Data)
PRR-CRB вимагає, щоб обсяг відправлених байтів не перевищував обсяг даних, доставку яких підтверджено в поточному ACK. Узгоджуючи відправку з реальним вивільненням пропускної здатності, CRB запобігає заторам у чергах та захищає від збоїв черговості.
Межа сповільненого зниження (SSRB) для інтерактивного трафіку з низькими затримками
На відміну від масштабних втрат, короткочасні збої можуть спричинити різке падіння FlightSize значно нижче порогу ssthresh (наприклад, під час одночасного скидання кількох пакетів або перемикання між базовими станціями). У класичному TCP надмірно малий FlightSize вимагав повільного поштучного зондування, сповільнюючи відновлення.
Режим PRR-SSRB розпізнає стан FlightSize < ssthresh і дозволяє контрольоване прискорення:
sndcnt = min(prr_delivered - prr_out + ssthresh - FlightSize, Max_Burst)
SSRB дозволяє надсилати до двох пакетів на кожен підтверджений пакет, швидко повертаючи FlightSize до рівня ssthresh без виникнення небезпечних сплесків. Цей режим є критично важливим для сесій SSH, відеоконференцій та ігор через VPN.
Синхронізація FlightSize та CWND: усунення пакетних сплесків та кінцевих скидань
Класичні реалізації швидкого відновлення часто вносили зміни безпосередньо у значення CWND під час обробки втрат, що призводило до різкого викиду пакетів у момент виходу з режиму відновлення. Стандарт RFC 6937 розділяє обчислення ліміту sndcnt та управління змінною CWND:
| Показник | Класичне відновлення RFC 3517 | Алгоритм RFC 6937 PRR |
|---|---|---|
| Неперервність конвеєра | Повна зупинка на ~0.5 RTT | Неперервна пропорційна передача |
| Дисципліна відправки | Порогове пачкове вивільнення | Пейсинг пакетів на кожен отриманий ACK |
| Очищення черг | Різке спорожнення та новий затор | Плавне, монотонне розвантаження буфера |
| Ризик кінцевих втрат | Високий (сплеск на виході з відновлення) | Мінімальний (FlightSize відповідає ssthresh) |
| Частота тайм-аутів RTO | Висока через повторні хвилі втрат | Зведена до мінімуму завдяки тактуванню |
Завдяки постійній синхронізації FlightSize в момент завершення відновлення обсяг даних у дорозі точно відповідає значенню ssthresh. З'єднання плавно повертається до фази уникнення перевантажень без генерації зайвих сплесків, усуваючи кінцеві скидання пакетів.
Взаємодія SACK, FACK та PRR у сучасному мережевому стеку Linux
У ядрі Linux алгоритм PRR слугує базовим рушієм відновлення для всіх модулів контролю перевантажень. Стандарт RFC 6937 спирається на селективні підтвердження (SACK, RFC 2018 / RFC 6675) для визначення точного обсягу даних, які залишили мережу з кожним вхідним пакетом.
Під час використання SACK разом із FACK (Forward Acknowledgment) ядро будує точну карту прогалин у послідовності пакетів, допомагаючи PRR розрізняти поодинокі збої та масові втрати. Алгоритм визначає prr_delivered на основі неперервних блоків SACK, передаючи чіткі інструкції планувальнику Fair Queuing (sch_fq).
Пастки інкапсуляції: поведінка PRR усередині тунелів WireGuard та IPsec
Застосування PRR у середовищі VPN має низку особливостей через взаємодію внутрішнього транспорту TCP та зовнішньої оболонки тунелю. Під час передачі даних через WireGuard, IPsec або OpenVPN вихідні сегменти TCP вкладаються в пакети UDP або ESP.
Фрагментація зовнішнього MTU та підсилення перехідних втрат
Якщо функція Path MTU Discovery (PMTUD) налаштована некоректно або проміжна мережа обмежує розмір MTU менше ніж 1500 байтів, внутрішні пакети TCP спричиняють фрагментацію зовнішніх пакетів IP. Втрата лише одного зовнішнього фрагмента призводить до втрати всього внутрішнього сегмента TCP:
- Втрата 2% зовнішніх фрагментів може перетворитися на втрату від 4% до 8% сегментів TCP.
- Старі алгоритми за таких обставин миттєво переходять у серію тайм-аутів RTO.
- Алгоритм PRR мінімізує цей ризик завдяки плавному пейсингу, запобігаючи переповненню буферів на шлюзах VPN.
Взаємодія з алгоритмами керування перевантаженнями BBR, CUBIC та Reno
PRR працює як модульний рушій відновлення під основними алгоритмами:
- CUBIC: У ядрі Linux CUBIC за замовчуванням взаємодіє з PRR. Зменшуючи вікно на 30% ($eta = 0.7$), PRR здійснює відправку зі значенням
Target_Ratio = 0.7, гарантуючи плавне відновлення. - BBR: Хоча BBR розраховує пропускну здатність безпосередньо, її оновлені версії застосовують принципи пропорційного пейсингу під час розвантаження черг.
- Reno: У класичному алгоритмі Reno механізм PRR забезпечує впевнене двократне зниження темпу передачі без характерних зупинок з'єднання.
Метрики бенчмарків: розподіл затримок та ефективність спустошення буферів
Тестування у робочих мережах підтверджує суттєву перевагу PRR над традиційними методами відновлення:
| Метрика ефективності | Класичне відновлення RFC 3517 | Алгоритм RFC 6937 PRR | Практичний виграш |
|---|---|---|---|
| 99-й процентиль затримки (RTT) | 420 мс (сплески джитера) | 145 мс (контрольований рівень) | Зниження піків затримки на 65% |
| Пропускна здатність під час втрат | Падає до 15% від максимуму | Зберігається на рівні 65–75% | Збільшення корисного потоку в 4–5 разів |
| Частота зриву в RTO | 8.4% випадків втрат | 1.1% випадків втрат | Скорочення жорстких тайм-аутів на 87% |
| Динаміка черги в буфері | Різкі стрибкоподібні коливання | Плавне лінійне зниження | Стабільна глибина буферів |
Підтримуючи безперервну роботу тактового генератора підтверджень, PRR запобігає виникненню пауз, які раніше значно погіршували роботу зашифрованих тунелів.
Архітектура пейсингу RiceGuard: багатошляхова передача з низьким джитером
Сервіс VPNRice інтегрує принципи PRR безпосередньо у власну транспортну інфраструктуру RiceGuard. Вузли RiceGuard обслуговують тисячі паралельних сесій через розподілену мережу Anycast.
Для забезпечення високої якості зв'язку в іграх, відеостримінгу та віддаленому доступі RiceGuard оптимізує відновлення на кількох рівнях:
- Пейсинг PRR на рівні ядра: Шлюзи RiceGuard працюють на оновлених ядрах Linux з активованим PRR та Fair Queuing (
fq), гарантуючи, що локальні втрати в абонента не зупинять магістральний трафік. - Оптимізація буферів та обмеження MSS: Система автоматично розраховує обмеження MSS на межах тунелів, запобігаючи виникненню зовнішньої фрагментації.
- Постійне тактування підтверджень: Зберігаючи пропорційний темп передачі даних під час втрат, RiceGuard запобігає затримкам, типовим для стандартних сервісів VPN.
Ця архітектура гарантує, що випадкові втрати в мобільних мережах або публічних мережах Wi-Fi не погіршують якість з'єднання для користувачів.
Керівництво з оптимізації у продакшені: параметри ядра та буфери тунелів
Мережеві інженери можуть перевірити та оптимізувати роботу PRR на серверах Linux за допомогою стандартних параметрів:
- Перевірка підтримки PRR: Переконайтеся, що ядро підтримує PRR (активно за замовчуванням у Linux 3.2+). Перевірте файл
/proc/sys/net/ipv4/tcp_congestion_controlта активність SACK (net.ipv4.tcp_sack = 1). - Активація Fair Queuing: Увімкніть планувальник FQ для апаратного пейсингу пакетів:
sysctl -w net.core.default_qdisc = fq. - Конфігурація MTU та обмеження MSS: Налаштуйте обмеження MSS на тунельних інтерфейсах (
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu) для усунення фрагментації. - Моніторинг показників відновлення: Відстежуйте лічильники TCP в режимі реального часу через
nstat -az TcpPrr*таss -tieдля аналізу динамікиprr_deliveredтаprr_out. - Запобігання Bufferbloat: Встановіть оптимальний максимальний розмір буфера запису сокета (
net.ipv4.tcp_wmem), уникаючи накопичення надлишкових даних перед виникненням втрат.



