Три оси формы трафика: почему два механизма требуют противоположного

Объёмное ограничение требует дробить соединения, ограничение параллелизма — сливать. Противоречие исчезает, если различать количество, одновременность и объём как независимые оси.

2026-08-31 GIGATAP Team #vpn
#vpn#anticensorship#network#dpi#traffic-analysis

Три оси формы трафика: почему два механизма требуют противоположного

Инженер, настраивающий транспорт против современных ограничений, довольно быстро упирается в неприятное: два задокументированных механизма требуют взаимно исключающих настроек. Одно требует держать соединения долго и переиспользовать их, другое — наоборот, менять чаще. Противоречие снимается, как только становится видно, что механизмы считают разные величины, а не одну и ту же.

Разберём, где проходит настоящая граница.

Два механизма#

Объёмное ограничение. Соединение позволяет передать порядка шестнадцати килобайт, после чего поток встаёт. Учёт ведётся на одно TCP-соединение. Cloudflare публично описал это поведение с 9 июня 2025 года; в сообществе оно обсуждалось как «TCP 16-20», а позже было переименовано с уточнением, что лимит применяется и к TCP, и к UDP.

Очевидная контрмера: дробить. Много коротких соединений, каждое не доходит до порога.

Ограничение параллелизма. Несколько одновременных защищённых соединений к одному адресу в коротком окне вызывают срабатывание, после которого новые попытки не проходят некоторое время.

Очевидная контрмера: сливать. Мало соединений, много потоков внутри каждого.

Настройки прямо противоположны. Классическая реакция — выбрать, какой механизм терпеть.

Почему противоречие кажущееся?#

Оно исчезает, если заметить, что «много соединений» — не одна величина, а две. Одна величина — сколько соединений открыто за период, вторая — сколько их живёт одновременно, и механизмы считают их порознь.

Ось Что ограничивает объёмный механизм Что ограничивает механизм параллелизма
Соединений всего за сессию нужно много безразлично
Соединений одновременно безразлично нужно мало
Байт на соединение нужно мало безразлично

Первый механизм ограничивает накопленный объём. Второй — скорость открытия. Это разные величины, и они конфликтуют только если открывать соединения пачками.

Плавная ротация удовлетворяет обоим: много соединений последовательно, но никогда больше двух-трёх одновременных рукопожатий. Количество набирается во времени, а не в моменте.

Ротация во времени не равна параллелизму в моменте — и вся развязка держится на этом различии.

Разбор: пачка против плавной ротации#

Разница между двумя способами набрать одно и то же количество соединений — на временной шкале.

ПАЧКОЙ — срабатывает ограничение параллелизма
время →  0мс   100мс  200мс  300мс  400мс
         │     │      │      │      │
соед. 1  ├─────────────────────────────────►
соед. 2  ├─────────────────────────────────►   4 одновременных
соед. 3  ├─────────────────────────────────►   рукопожатия
соед. 4  ├─────────────────────────────────►   в окне 400 мс
         ▲
         └── порог превышен здесь

ПЛАВНО — то же количество, ограничение не срабатывает
время →  0с    3с     6с     9с     12с
         │     │      │      │      │
соед. 1  ├──────────►│
соед. 2        ├──────────►│                   не более 1–2
соед. 3               ├──────────►│            одновременно
соед. 4                      ├──────────►│     в любой момент

Соединений в обоих случаях четыре. Различается только распределение во времени.

Нижний вариант удовлетворяет оба механизма сразу: количество набирается — значит ни одно соединение не копит объём; одновременность низкая — значит порог параллелизма не достигается.

Числовой пример: где именно ломается односторонняя настройка#

Возьмём загрузку в 2 МБ и посчитаем три конфигурации.

Настройка Соединений Байт на соединение Одновременно Итог
«Мало соединений, много потоков» 2 ~1 000 000 2 ❌ объёмное ограничение на 16 КБ
«Много соединений, мало потоков» 130 ~16 000 8 ❌ порог параллелизма
Плавная ротация 130 ~16 000 2 ✅ оба порога не достигнуты

Первая строка — типовая рекомендация против ограничения параллелизма. Она даёт по мегабайту на соединение, то есть превышает объёмный порог в шестьдесят раз.

Вторая — типовая рекомендация против объёмного ограничения. Объём в норме, но восемь одновременных рукопожатий превышают порог параллелизма.

Третья отличается от второй только одним параметром — сколько соединений держится открытыми в один момент. Количество, объём и время те же.

Это и есть практический смысл разделения на оси: третья конфигурация не является компромиссом между первыми двумя. Она удовлетворяет оба ограничения полностью, потому что они ограничивают разные величины.

Где развязка упирается в предел#

Красиво в теории, ограниченно на практике — по конкретной причине.

Транспорты, дающие мультиплексирование поверх HTTP, обычно позволяют настроить, когда переоткрывать нижележащее соединение. Но триггеры ротации почти всегда временны́е и по числу запросов, а не по объёму.

Задать «переоткрывать после пятнадцати килобайт» напрямую нельзя. Приблизить — можно, снижая допустимое число запросов на соединение, но это косвенная регулировка величины, которая считается в байтах.

Именно поэтому в трекере Xray с июня 2025 года висит открытый запрос на дробление нисходящего потока по разным TCP-соединениям заданного размера. Автор запроса — тот же человек, который описал механизм, — оценивает цену честно: около двух с половиной тысяч TCP-соединений на файл в пятьдесят мегабайт, что «много и довольно подозрительно, но явно лучше, чем не работать вообще».

Запрос до сих пор не реализован. Параметрический тюнинг здесь паллиатив, а не решение.

Распространённая ошибка: дробление не на том уровне#

Отдельно стоит назвать ловушку, в которую попадают многие.

Транспорты вроде XHTTP умеют разбивать передачу на множество HTTP-запросов. Возникает соблазн считать, что это и есть дробление против объёмного ограничения.

Не является. Если все эти запросы идут внутри одного TCP-соединения, счётчик механизма — а он считает по TCP-соединению — продолжает расти. Автор механизма формулировал это прямо: разделение на несколько HTTP-запросов в одном соединении — это другое, и оно не поможет.

Полезное следствие для проверки любой настройки: смотрите, на каком уровне происходит дробление. Если на прикладном, а счётчик на транспортном — вы не решили задачу, а замаскировали её от себя.

Ещё одна ловушка: односторонняя оптимизация#

Обе очевидные контрмеры односторонни, и обе встречаются в готовых рекомендациях.

Настройка «одно-два соединения, много потоков в каждом» правильна против параллелизма и худшая возможная против объёма: потоки сводятся в минимум соединений и наполняют каждое быстрее всего.

Обратная — «много соединений, мало потоков» — правильна против объёма и провоцирует срабатывание по параллелизму.

Готовые наборы параметров из обсуждений обычно оптимизированы против одного механизма, потому что автор наблюдал именно его. Перенос такого набора в другие условия даёт результат хуже, чем настройка по умолчанию.

Что из этого практически применимо#

Помечайте каждый параметр осью. Параметр формы потока, заданный без указания, что именно он ограничивает — количество, одновременность или объём, — не является решением. Он является догадкой.

Проверяйте, что измеряете. Один и тот же симптом «не работает» порождается обоими механизмами, и различаются они только по признаку: объёмный даёт остановку после N килобайт, параллельный — отказ новых соединений при живом старом.

Не переносите числа между условиями. Пороги наблюдались разными людьми на разных операторах в разное время. Числовой порог из внешнего источника разумно считать гипотезой, а в конфигурации выражать диапазоном, а не константой.

Вывод#

Противоречие между двумя механизмами существует только в формулировке «много или мало соединений». Как только величина разделяется на количество, одновременность и объём, обе задачи оказываются решаемыми одновременно.

Но у развязки есть потолок: триггеры ротации не байтовые, и пока в транспортах нет дробления по объёму, параметрическая настройка остаётся приближением. Знать её предел важнее, чем найти удачный набор чисел, — потому что набор чисел устаревает вместе с наблюдением, а понимание осей нет.

Термины#

  • Ось количества - сколько соединений открыто за период — величина, которую считает один из механизмов.
  • Ось одновременности - сколько соединений живёт параллельно в один момент времени.
  • Ось объёма на соединение - сколько байт передано в пределах одного соединения до срабатывания ограничения.

FAQ: частые вопросы#

Держать соединения долго или менять чаще?#

Ни то ни другое в чистом виде. Плавная ротация удовлетворяет обоим механизмам: соединения меняются, но не пачкой и не поодиночке.

Почему односторонняя настройка проигрывает?#

Она оптимизирует одну ось и ухудшает другую. Механизмы считают разные величины, поэтому выигрыш по одной оплачивается проигрышем по второй.

Есть ли предел у такой развязки?#

Да. При достаточно большом трафике обе оси упираются в свои потолки одновременно, и компромисса, удовлетворяющего обоим, не остаётся.

Что читать дальше#