github sleep3r/mtproto.zig v0.19.1

latest releases: v1.15.3, v1.15.2, v1.15.1...
5 months ago

🇷🇺 Что нового (RU)

Что решает этот релиз

Комплексное укрепление надёжности, безопасности и производительности прокси по итогам code review. Главные пользовательские эффекты:

  • Медиа-трафик больше не тормозит. Прокси теперь различает обычные и медиа‑MiddleProxy и маршрутизирует фото/видео через выделенный media‑MP флот Telegram. Ранее все запросы шли на один MP, что вызывало стеллы и сбросы при загрузке медиа.
  • Прокси на цензурируемых хостах обновляет конфигурацию MP через туннель. Если core.telegram.org заблокирован, прокси автоматически фоллбэчит на curl --interface <tunnel> и прогревает кэш MP в первые минуты работы (а не через 24 часа).
  • Устранены уязвимости: коллизия IPv4-mapped IPv6 в rate limiter, потенциальная коррупция данных в SOCKS5/HTTP CONNECT, переполнение буфера MiddleProxy, паника @memcpy при формировании nonce.
  • Повышена производительность: O(1) поиск секрета вместо O(N), streaming HMAC без аллокации ~3 KB, корректный DRS при отключённом anti-DPI.

Что изменено

Безопасность и корректность

  • Rate-limit: IPv4-mapped IPv6 (#197)

    • На dual-stack [::] listener'ах все IPv4-клиенты приходят как ::ffff:a.b.c.d. Без патча они коллапсировали в один subnet key, и весь IPv4 интернет делил один token bucket.
    • subnetKey() теперь детектирует IPv4-mapped адреса и применяет IPv4-specific /24 логику.
  • SOCKS5/HTTP CONNECT pipelined data

    • Лишние байты после успешного SOCKS5/HTTP CONNECT handshake теперь приводят к закрытию соединения с предупреждением вместо потенциальной коррупции протокола.
  • MiddleProxy buffer overflow

    • Scratch-буфер mp_c2s_scratch теперь выделяется с запасом ×96 (реальный worst-case расширения обфускации) + 256 байт заголовков.
  • MiddleProxy nonce selector fix

    • Исправлена регрессия формирования nonce-фрейма: 4 байта ключевого селектора корректно копируются побайтово вместо потенциально паникующего @memcpy.
  • TOML escape tracking (src/ctl/toml.zig)

    • При удалении инлайн-комментариев теперь учитывается escaped-состояние (символ # внутри экранированной последовательности не считается началом комментария).

Производительность

  • O(1) secret resolution

    • В finishClientHandshake используется slot.validation_secret напрямую вместо перебора всего списка пользователей.
  • Streaming HMAC (src/protocol/tls.zig)

    • В buildServerHelloWithTemplate убрана heap-аллокация ~3 KB: данные теперь подаются в хэшер потоково.
  • DRS init при drs = false

    • Когда Dynamic Record Sizing отключён, инициализация теперь стартует с full_size (16384), а не с 1369 — нет смысла клэмпить записи при отключённом anti-DPI.

Медиа-aware MiddleProxy routing (ключевое изменение)

  • Bundled media MP addresses (src/protocol/constants.zig)

    • Добавлен массив tg_media_middle_proxies_v4 с отдельными адресами для media‑MP, чтобы proxy_for -N endpoints были доступны даже без подключения к core.telegram.org.
  • DcSignFilter в парсере getProxyConfig

    • parseMiddleProxyAddressesForDc() теперь принимает фильтр positive_only (обычный трафик) / negative_only (медиа) / any (legacy), корректно разделяя два пула MP.
  • MiddleProxySnapshot с media-полями

    • Добавлены addrs_media_primary[5] и addrs_media_dc4[16] для хранения media‑MP.
    • getForDc() принимает media: bool и возвращает соответствующий endpoint.
  • buildDcConnectPlan() с media fallback

    • Если is_media_path — используется media-MP; если media-пул пуст — fallback на обычный MP.

Работа из цензурируемой сети

  • fetchUrlBytesViaInterface() — curl-based fallback

    • Когда прямой HTTP к core.telegram.org недоступен и сконфигурирован tunnel upstream, прокси вызывает curl --interface <tunnel_iface>.
    • Исправлена передача аргументов: --interface и значение как два отдельных элемента argv (не --interface=val).
  • Early retry loop в middleProxyUpdaterMain()

    • Перед переходом к 24-часовому циклу обновления MP выполняются ретраи с нарастающими интервалами: 10 с → 30 с → 1 мин → 5 мин → 30 мин.
    • На цензурируемом хосте кэш MP с media-endpoints прогревается в первые минуты, а не на следующие сутки.

Edge-cases

  • ENOBUFS / TCP aborts — корректная обработка error.SystemResources и benign TCP-abort в acceptNewConnections.
  • @memcpy panic guard — в middleProxyBegin предварительный @memset и условное побайтовое копирование ключевого селектора.

Tip

Обновление не требует изменения конфигурации. Все bundled MP-адреса автоматически обновляются из getProxyConfig при наличии связности (напрямую или через туннель).


🇬🇧 Release notes (EN)

What this release addresses

Comprehensive hardening of proxy reliability, security, and performance based on code review findings. Key user-visible effects:

  • Media traffic no longer stalls. The proxy now distinguishes regular vs media MiddleProxy endpoints and routes photo/video downloads through Telegram's dedicated media MP fleet. Previously all traffic was routed to the same MP, causing stalls and connection resets on large media downloads.
  • Proxy on censored hosts refreshes MP config via tunnel. When core.telegram.org is blocked, the proxy automatically falls back to curl --interface <tunnel> and warms the MP cache within the first few minutes (instead of waiting 24 hours).
  • Security fixes: IPv4-mapped IPv6 rate-limiter collision, potential SOCKS5/HTTP CONNECT data corruption, MiddleProxy buffer overflow, @memcpy panic in nonce frame construction.
  • Performance improvements: O(1) secret lookup instead of O(N), streaming HMAC without ~3 KB allocation, correct DRS initialization when anti-DPI is disabled.

What changed

Security & correctness

  • Rate-limit: IPv4-mapped IPv6 (#197)

    • On dual-stack [::] listeners, all IPv4 clients arrive as ::ffff:a.b.c.d. Without this fix they collapsed to a single subnet key, sharing one token bucket across the entire IPv4 internet.
    • subnetKey() now detects mapped addresses and applies IPv4-specific /24 logic.
  • SOCKS5/HTTP CONNECT pipelined data

    • Extra bytes after a successful SOCKS5/HTTP CONNECT handshake now cause the connection to be closed with a warning, preventing potential protocol corruption.
  • MiddleProxy buffer overflow

    • The mp_c2s_scratch buffer now allocates ×96 headroom (real worst-case obfuscation expansion) + 256 bytes for headers.
  • MiddleProxy nonce selector fix

    • Fixed a regression in nonce frame construction: 4 bytes of the key selector are now safely copied byte-by-byte instead of using a potentially panicking @memcpy.
  • TOML escape tracking (src/ctl/toml.zig)

    • Inline comment removal now respects the escaped state — a # inside an escape sequence is no longer treated as a comment start.

Performance

  • O(1) secret resolutionfinishClientHandshake now uses slot.validation_secret directly instead of iterating all users.
  • Streaming HMAC (src/protocol/tls.zig) — removed ~3 KB heap allocation from buildServerHelloWithTemplate; data is now fed to the hasher in a streaming fashion.
  • DRS init when drs = false — when Dynamic Record Sizing is disabled, initialization starts at full_size (16384) instead of the probe-friendly 1369.

Media-aware MiddleProxy routing (key change)

  • Bundled tg_media_middle_proxies_v4 addresses in constants.zig for fallback when getProxyConfig is unavailable.
  • parseMiddleProxyAddressesForDc() now takes a DcSignFilter parameter (positive_only/negative_only/any) to correctly separate regular vs media MP pools.
  • MiddleProxySnapshot carries separate addrs_media_primary and addrs_media_dc4 fields.
  • buildDcConnectPlan() selects media MP when is_media_path, with automatic fallback to regular MP if the media pool is empty.

Censored-network operation

  • fetchUrlBytesViaInterface() — curl-based fallback through the configured tunnel interface when core.telegram.org is unreachable.
  • Early retry loop in middleProxyUpdaterMain() — retries at 10s, 30s, 1m, 5m, 30m before entering the 24-hour refresh cadence. Warms the MP cache within the first few minutes on censored hosts.

Edge-cases

  • ENOBUFS / TCP aborts — proper handling of error.SystemResources and benign TCP abort in acceptNewConnections.
  • @memcpy panic guard — safe byte-by-byte copy of the key selector in middleProxyBegin.

Tip

This update requires no configuration changes. Bundled MP addresses are automatically refreshed from getProxyConfig when connectivity is available (directly or via tunnel).

Changelog

  • fix(proxy): address critical review findings (data corruption, DoS, perf) (#197) (a6b6c80)
  • fix(proxy): restore middleproxy key selector bytes in nonce request (58dd39f)
  • feat(proxy): media-aware middle-proxy routing with tunnel fallback (82366ba)

Don't miss a new mtproto.zig release

NewReleases is sending notifications on new releases.