Протягом десятиліть стандартною реакцією мережевої інфраструктури на перевантаження каналів зв'язку залишалося примусове скидання пакетів (packet drop). За класичного керування чергами Drop-Tail та алгоритмів контролю перевантаження, таких як TCP Reno та Cubic, маршрутизатор сигналізує про вичерпання буфера простим відкиданням вхідних пакетів. Відправник фіксує відсутність підтвердження (ACK), зменшує вікно перевантаження (cwnd) удвічі та здійснює повторну передачу.

Хоча цей механізм запобігає колапсу мережі, він спричиняє значні експлуатаційні втрати. В інтерактивних сервісах — голосовому зв'язку реального часу, відеоконференціях, змагальних онлайн-іграх та фінансових системах — втрата пакетів викликає раптові сплески затримки та джитер. Коли трафік проходить крізь зашифровані тунелі VPN (IPsec або WireGuard), ефект роздуття буфера (bufferbloat) та втрати даних помножуються через багаторівневу інкапсуляцію.

Щоб відокремити сповіщення про перевантаження від втрати пакетів, група IETF стандартизувала механізм явного сповіщення про перевантаження (ECN - Explicit Congestion Notification) у специфікації RFC 3168 та деталізувала правила для тунелів у RFC 6040. Подальшим розвитком стала архітектура L4S (RFC 9330, RFC 9331, RFC 9332), яка запровадила керування DualQ Coupled AQM, що забезпечує затримку черги менше 1 мілісекунди як на відкритих маршрутах, так і всередині зашифрованих VPN.

Парадигма втрати пакетів: чому скидання Drop-Tail не працює в сучасних мережах

У традиційній мережевій архітектурі заповнення черг коливається між двома проблемними станами. Якщо буфери занадто малі, вони не здатні згладити короткочасні сплески трафіку, що призводить до передчасних втрат пакетів і недовантаження каналу. Навпаки, коли ємність буферів завищують для виключення втрат, виникає явище bufferbloat.

Під час bufferbloat проміжні маршрутизатори накопичують мегабайти даних під час масивних завантажень. Пакети перебувають у фізичній пам'яті сотні мілісекунд в очікуванні відправлення. Для паралельного інтерактивного трафіку UDP ця затримка виявляється критичною. Реальний час кругового обігу ($RTT$) зростає за формулою:

$$RTT_{\text{actual}} = RTT_{\text{propagation}} + \frac{Q_{\text{bytes}}}{\text{Bandwidth}}$$

Коли буфер переповнюється, каскадне скидання пакетів призводить до глобальної синхронізації TCP: усі з'єднання одночасно скидають швидкість. Канал входить у циклічний режим накопичення черги, деградації відгуку, скидання пакетів та падіння пропускної здатності.

Архітектура ECN: 2-бітне поле IP та узгодження в рукостисканні TCP (RFC 3168)

Стандарт RFC 3168 усуває необхідність навмисного скидання пакетів завдяки використанню двох молодших бітів у полі ToS протоколу IPv4 та полі Traffic Class протоколу IPv6:

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
|      DSCP (6 bits)    |  ECN  |
+---+---+---+---+---+---+---+---+

2-бітне поле ECN підтримує чотири кодові комбінації:

Значення бітів Позначення Семантичне значення
00 Non-ECT Транспорт без підтримки ECN (стандартне скидання)
01 ECT(1) Підтримку ECN увімкнено (масштабовані потоки L4S)
10 ECT(0) Підтримку ECN увімкнено (класичний зворотний зв'язок RFC 3168)
11 CE Зафіксовано перевантаження (Congestion Experienced)

Для використання ECN кінцеві вузли узгоджують підтримку механізму на етапі тристороннього рукостискання TCP:

  1. SYN: Клієнт виставляє прапорці ECE (ECN-Echo) та CWR (Congestion Window Reduced) у заголовку TCP.
  2. SYN-ACK: Сервер, який підтримує ECN, відповідає зі встановленим прапорцем ECE та скинутим CWR.
  3. ACK: Клієнт завершує рукостискання зі знятими прапорцями ECN, переводячи з'єднання в режим активної передачі.
Клієнт                                                  Сервер
  |--- SYN [ECE=1, CWR=1] ------------------------------->| (Пропозиція ECN)
  |<-- SYN-ACK [ECE=1, CWR=0] ----------------------------| (Підтвердження ECN)
  |--- ACK [ECE=0, CWR=0] ------------------------------->| (З'єднання встановлено)
  |                                                       |
  |=== Пакет даних [IP: ECT(0)] =========================>| (Маршрутизатор ставить CE)
  |<== Пакет ACK [TCP: ECE=1] ============================| (Повернення сигналу перевантаження)
  |--- Пакет даних [TCP: CWR=1, IP: ECT(0)] ------------>| (Підтвердження зниження вікна)

У разі виникнення черги проміжний маршрутизатор перезаписує поле IP з ECT(0) або ECT(1) на CE (11) замість знищення пакета. Одержувач, виявивши мітку CE, активує біт ECE в наступних пакетах підтвердження. Відправник зменшує вікно передачі та надсилає пакет із прапорцем CWR.

Дилема тунельної інкапсуляції: втрата міток та утворення чорних дір

Якщо для відкритих з'єднань логіка RFC 3168 прозора, то в контексті тунелювання виникли суттєві розбіжності. Інкапсуляція є основою віртуальних приватних мереж: внутрішній пакет IP упаковується в зовнішній транспортний протокол (IPsec ESP, WireGuard UDP або GRE).

Якщо інкапсульований пакет проходить крізь перевантажений вузол провайдера, цей вузол маркує зовнішній заголовок IP кодом CE (11). Проте обробка на виході з тунелю історично страждала від двох дефектів:

  1. Втрата сигналу (ECN Blindness): Вихідний шлюз знімав зовнішній заголовок IP та відправляв внутрішній пакет із первинним станом (ECT(0) або Not-ECT). Мітка CE безслідно зникала під час деінкапсуляції. Навантаження продовжувало зростати до фізичного переповнення буфера.
  2. Неконтрольоване копіювання (ECN Black-Holing): Вхідний вузол копіював внутрішні прапорці в зовнішній заголовок без перевірки можливостей внутрішнього протоколу. Якщо внутрішній пакет без підтримки ECN (00) упаковувався в зовнішній заголовок із позначкою CE, перенесення мітки всередину порушувало логіку застарілих стеків.

Через ці помилки адміністратори корпоративних VPN нерідко вимикали ECN.

Специфікація RFC 6040: режими Normal, Compatibility та деінкапсуляція на виході

Специфікація RFC 6040 усунула неоднозначність тунелювання, регламентувавши правила обробки міток ECN на вході (Ingress) та виході (Egress) тунелю незалежно від протоколу.

Правила інкапсуляції Ingress: прив'язка внутрішнього ECT до зовнішнього заголовка

На вході в тунель пристрій формує зовнішній заголовок IP на основі вмісту внутрішнього пакета:

  • Стандартний режим (Normal Mode - за замовчуванням у RFC 6040): Якщо внутрішній пакет позначений як Not-ECT (00), зовнішній заголовок ЗОБОВ'ЯЗАНИЙ бути встановлений у Not-ECT (00). Це гарантує, що проміжні вузли скинуть пакет у разі сильного перевантаження, оскільки одержувач не зрозуміє сигнал CE. Якщо внутрішній пакет містить ECT(0), ECT(1) або CE, зовнішній заголовок дзеркально копіює це значення.
  • Режим сумісності (Compatibility Mode): Застосовується, якщо вихідний шлюз не підтримує RFC 6040. Для всіх зовнішніх заголовків жорстко встановлюється Not-ECT (00), змушуючи мережу використовувати стандартне скидання.

Таблиця станів Egress: поєднання зовнішнього CE із внутрішнім кодом

На виході з тунелю шлюз зіставляє зовнішній та внутрішній коди ECN перед зняттям зовнішньої оболонки згідно з таблицею станів:

Внутрішній заголовок Зовнішній заголовок Результат деінкапсуляції Дія та протокольна оцінка
Not-ECT (00) Not-ECT (00) Not-ECT (00) Стандартна передача
Not-ECT (00) ECT(0) / ECT(1) Not-ECT (00) Помилка конфігурації зовнішнього вузла
Not-ECT (00) CE (11) СКИДАННЯ ПАКЕТА Обов'язкове скидання: зовнішній канал перевантажений, всередині немає ECN
ECT(0) (10) Not-ECT (00) ECT(0) (10) Стандартне доставлення: зовнішня ділянка вільна
ECT(0) (10) ECT(0) (10) ECT(0) (10) Штатне доставлення без перевантажень
ECT(0) (10) CE (11) CE (11) Перенесення сигналу перевантаження у внутрішній стек
ECT(1) (01) CE (11) CE (11) Перенесення сигналу перевантаження у внутрішній стек
CE (11) Not-ECT (00) CE (11) Збереження початкового внутрішнього сигналу
CE (11) CE (11) CE (11) Збереження мітки перевантаження

Ключове правило безпеки RFC 6040 відображено в рядку 3: якщо внутрішній пакет не підтримує ECN, а зовнішній надійшов із міткою CE, вихідний вузол зобов'язаний скинути пакет. Це ініціює коректну реакцію застарілого відправника та виключає роздуття черги.

Еволюція до L4S: низька затримка, мінімальні втрати та масштабованість (RFC 9330)

Класичний ECN розв'язує проблему скидання пакетів, але не усуває затримок у буферах. Традиційні алгоритми TCP реагують на сигнал CE так само жорстко, як на втрату даних: зменшують вікно передачі вдвічі. Щоб уникнути недовантаження каналів, пороги маркування виставлялися високими, допускаючи накопичення затримки в 10–50 мілісекунд.

Архітектура L4S (RFC 9330) долає цю проблему за рахунок трьох компонентів:

  1. Масштабований контроль перевантаження (TCP Prague / QUIC L4S): Відправник безперервно коригує швидкість передачі з високою частотою. Замість поділу вікна навпіл Prague реагує на позначки CE мінімальними кроками масштабування ($O(1)$), зберігаючи чергу близькою до нуля.
  2. Кодова точка ідентифікації (RFC 9331): L4S задіює код ECT(1) (01). Проміжні маршрутизатори використовують його для розділення потоків L4S та класичного трафіку ECT(0) або Not-ECT.
  3. Зв'язане керування чергами DualQ Coupled AQM (RFC 9332): Мережевий шлюз ділить трафік на дві паралельні логічні черги, ізолюючи інтерактивні потоки від об'ємних завантажень зі збереженням балансу смуги.
Вхідний потік пакетів
       |
       v
+-----------------------+
| Класифікатор (9331)   |
+-----------------------+
       |               |
       | [ECT(1)]      | [Not-ECT, ECT(0)]
       v               v
+-------------+ +---------------+
|  L-Черга    | |    C-Черга    |
| (Малий буфер| | (Глибокий буф,|
|  Step-марк.)| |  Класичн. AQM)|
+-------------+ +---------------+
       \               /
        \             /
         v           v
+-------------------------------+
| Зв'язаний планувальник (9332) |
+-------------------------------+
                |
                v  Передача без затримок (<1мс)

Механізм DualQ Coupled AQM: ізоляція класичних потоків та Prague (RFC 9332)

Механізм DualQ Coupled Active Queue Management за RFC 9332 забезпечує співіснування чутливих до затримок сервісів та традиційних завантажень на одному фізичному інтерфейсі.

Класична черга: взаємодія алгоритмів FQ-CoDel та PIE

Класична черга (C-Queue) приймає пакети Not-ECT та ECT(0). Вона використовує перевірені алгоритми AQM, такі як PIE або FQ-CoDel.

Черга C утримує цільову затримку в межах 10–20 мс. У разі перевантаження вона відкидає пакети Not-ECT або маркує ECT(0) кодом CE з імовірністю, пропорційною квадратному кореню з перевантаження ($p_C$).

Черга низької затримки: порогове маркування та субмілісекундні буфери

Черга низької затримки (L-Queue) обробляє виключно пакети ECT(1). Оскільки алгоритм Prague миттєво реагує на поодинокі мітки, черзі L не потрібен глибокий буфер.

У ній застосовується ступінчасте маркування (Step Marking): якщо затримка в черзі перевищує поріг у 500 мікросекунд – 1 мілісекунду, вхідні пакети негайно маркуються кодом CE. Скидання пакетів виключене аж до повного вичерпання пам'яті.

Для збереження справедливості розподілу пропускної здатності RFC 9332 зв'язує ймовірності маркування формулою:

$$p_L = k \times p_C^2$$

Ймовірність маркування в черзі L ($p_L$) динамічно залежить від квадрата ймовірності перевантаження в черзі C ($p_C$), що гарантує рівний розподіл місткості між потоками L4S та TCP Cubic.

Реальний ефект продуктивності: геймінг, відеозв'язок та тунелі VPN

Спільне впровадження тунелювання ECN за стандартом RFC 6040 та архітектури L4S DualQ AQM кардинально підвищує якість зв'язку.

У хмарному геймінгу, потоковому рендерингу та телеметрії нестабільність затримки (джитер) завдає більше шкоди, ніж її абсолютне значення. У звичайних тунелях із політикою Drop-Tail паралельне надсилання файлу на швидкості 500 Мбіт/с збільшує пінг у грі з 25 мс до понад 200 мс через заповнення буферів.

У разі інтеграції RFC 6040 та DualQ AQM:

  • Затримка в черзі: Скорочується з 80–250 мс до значень менше 1 мілісекунди.
  • Втрати пакетів: Наближаються до 0,00% за високої утилізації завдяки сигналам CE.
  • Блокування початку черги (Head-of-Line): Усувається, зберігаючи безперервність передачі команд керування.

Крім того, підтримка ECN органічно доповнює механізми захисту стека, такі як запобігання паніці ядра під час TCP SACK, підтримуючи стабільність буферів сокетів.

Архітектура RiceGuard: тунелювання ECN за стандартом RFC 6040 та DualQ

VPNRice впроваджує специфікації RFC 6040 та RFC 9330 безпосередньо у власний мережевий стек передачі даних RiceGuard.

У поширених рішеннях VPN зовнішні прапорці IP нерідко втрачаються в процесі криптографічних операцій. Коли ядро інкапсулює пакет у WireGuard UDP або IPsec ESP, стандартна конфігурація часто не транслює зовнішню мітку CE назад у сокет клієнта під час деінкапсуляції.

[ Простір користувача: TCP Prague / QUIC ]
       |
       | (Внутрішній заголовок IP: кодова точка ECT(1))
       v
[ Клієнтський модуль RiceGuard ]
       |
       | Інкапсуляція на вході (RFC 6040 Normal Mode)
       | Дзеркалювання ECT(1) у зовнішній заголовок UDP/IP
       v
[ Магістральний канал провайдера з вузьким місцем DualQ ]
       |
       | Фіксація перевантаження: маршрутизатор ставить CE (11)
       v
[ Прикордонний шлюз RiceGuard (модуль деінкапсуляції) ]
       |
       | Таблиця станів Egress RFC 6040:
       | Зовнішній=CE + Внутрішній=ECT(1) ---> Пересилання внутрішнього пакета з CE (11)
       v
[ Цільовий сервер / Хмарна інфраструктура ]
       |
       | Плавна адаптація швидкості: додаткова затримка в буфері = 0 мс

В архітектурі RiceGuard:

  • Суворе дотримання правил Ingress/Egress RFC 6040: Криптографічний конвеєр обробляє зовнішні та внутрішні заголовки на апаратній швидкості. У разі надходження пакета з позначкою CE RiceGuard оновлює внутрішній заголовок перед маршрутизацією.
  • Апаратне розвантаження DualQ: На прикордонних серверах VPNRice вхідний трафік розподіляється за апаратними чергами DualQ за допомогою фільтрів eBPF/XDP. Інтерактивні дані UDP та пакети L4S спрямовуються виділеними трактами окремо від черг масивних даних.
  • Інтеграція з контролем MTU: Заголовки тунелю формуються з динамічним MSS Clamping, що виключає фрагментацію та спотворення міток ECN.

Інженерний контрольний список: налаштування ECN та L4S у ядрах Linux та шлюзах VPN

Для розгортання та перевірки підтримки RFC 6040 і L4S в операційній системі Linux та шлюзах VPN дотримуйтеся чек-листа:

  • Увімкнення системної підтримки ECN: Задайте net.ipv4.tcp_ecn = 1 у файлі /etc/sysctl.conf для узгодження ECN у вхідних та вихідних сесіях.
  • Перевірка версії ядра Linux: Переконайтеся, що використовується ядро версії 6.4 або вище, яке містить модуль TCP Prague та планувальник DualQ AQM (sch_dualpi2).
  • Підключення дисципліни черги DualQ: Налаштуйте планувальник на фізичному та тунельному інтерфейсах:
    tc qdisc add dev eth0 root dualpi2
    
  • Контроль параметрів RFC 6040 у тунелях WireGuard/IPsec: Перевірте збереження бітів ECN під час інкапсуляції та маршрутизації інтерфейсу (sysctl -w net.ipv4.conf.all.rp_filter=2).
  • Аудит узгодження ECN у дампах трафіку: За допомогою tcpdump перевірте виставлення прапорців ECE та CWR під час обміну пакетами SYN, SYN-ACK та ACK:
    tcpdump -i any 'tcp[13] & 0xc0 != 0' -n -vv
    
  • Тестування таблиці деінкапсуляції: Надішліть тестові пакети із зовнішнім кодом CE і переконайтеся, що мітка коректно переноситься у внутрішній заголовок на виході з тунелю.
  • Моніторинг лічильників міток та скидань: Відстежуйте статистику черг, щоб переконатися у зниженні втрат даних у разі виникнення перевантажень:
    tc -s qdisc show dev eth0