Прямой TCP убрали из лестницы в сентябре (f74d97f0df): без охраны он
держал DC в «подключении» минутами. Но там, где закрыт только Cloudflare,
а Telegram открыт, он единственный путь. Теперь WssOfficialRoute снова
отдаёт его после туннеля — WssRoute::direct, — но под охраной:
- свой ключ здоровья direct-dc<N> по сети (metered/unmetered), пауза
после первой же неудачи 2 → 4 → 8 → 16 → 30 мин, хранится в tdata;
- фабрика сокетов строит WssDirectStepSocket: обычный TcpSocket внутри и
вердикт один раз — тайм-аут бюджета (нет TCP, нет ответа, заморозка),
ошибка или закрытие раньше 32 КБ — неудача; 32 КБ ответа снимают
историю пауз. Неудачи IPv6-попыток не считаются: без IPv6 в сети они
падают всегда и ставили бы на паузу рабочий IPv4;
- бюджет подключения прямого шага не меньше 4 с: первая секунда ставила
бы на паузу медленный, но рабочий путь.
Лестница: релей → фронты → туннель → прямой TCP (если не на паузе) →
фронты без учёта паузы; DC203 так же. Тест test_proxy_wss_default это
закрепляет; блок __main__ перенесён в конец файла — раньше запуск
скриптом, как в CI, не выполнял тест DC203. Та же схема в Android
(c7575323d) и ZapretGUI (605d76f3).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>