Files
telemt/docs/WEB/PROXY_PING.ru.md
T
2026-10-31 14:38:25 +03:00

245 lines
41 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ping в списке прокси: RPC Ping/Pong и задержки WEB
[English](PROXY_PING.en.md) | [Русский](PROXY_PING.ru.md) | [Deutsch](PROXY_PING.de.md)
Наблюдаемые **1000–1500 мс для WEB против 50–150 мс для Classic/DD/EE** могут относиться к измерениям с разными границами. В Android локальный сокет WEB-проверки становится готов раньше, чем обязательно готов удалённый WEB-поток. Оставшееся открытие потока и работа транспорта могут попасть в показанный результат. Код не задаёт фиксированный секундный штраф для каждого успешного WEB-ping.
Эти числа предоставлены оператором и не воспроизведены при подготовке документа. Анализ исходников подтверждает механизмы, но не устанавливает причину задержки в конкретном развёртывании.
## Клиенты и измерения
Проверено **2026-10-31** по DrKLO Android `3de37c8cfb039452be7398909461da6288babf15` и Telegram iOS `279f89e4d4f63f17227bf877dc3d8990f22ecd58`. Установленные релизы и форки могут отличаться.
| Измерение | Что охватывает | Поведение WEB |
| --- | --- | --- |
| Ping в списке прокси Android | Зашифрованный MTProto `TL_ping` / `TL_pong` через проверяемый прокси | Отдельный WEB-транспорт проверки, затем нативная проверка через локальный сокет. |
| Ping в списке прокси iOS | Проверка связности `req_pq` / `resPQ`; отсчёт от `connectionOpened` | Записи `.web` исключены из проверки; неактивный WEB-прокси отображается как непроверенный. |
| ICMP ping | IP echo до выбранного хоста с учётом маршрутизации и политики ICMP | Не измеряет прикладную пересылку и Telegram DC. |
| WEB transport `FRAME_PING` / `FRAME_PONG` или WebSocket keepalive | Жизнеспособность транспорта/сессии | Это не отображаемый Android результат MTProto. |
| Telemt ME RPC Ping/Pong | Один путь от Telemt до ME, включая локальную очередь writer и планирование flush | Не включает клиент, WebView и публичный TLS-фронтенд. |
Источники: [точка входа Android][android-entry], [нативные запросы][android-native], [фильтр iOS][ios-filter], [проверка iOS][ios-probe], [интерфейс iOS][ios-ui]. Поэтому формулу WEB-ping Android нельзя переносить на WEB-строку текущего iOS.
Android показывает последний результат проверки без медианы или EMA и пропускает новую проверку, если предыдущая была менее двух минут назад. У подключённого прокси тоже может отображаться сохранённый результат: это не непрерывное измерение RTT активной сессии. WEB-проверка создаёт собственный транспорт, а не использует напрямую активный транспорт приложения. См. [обновление списка][android-ui] и [WEB-транспорт][android-transport].
## Где Android запускает и останавливает таймер
Для Classic/DD/EE нативный callback готовности приходит после удалённого TCP-соединения и необходимой подготовки транспорта прокси, включая EE FakeTLS. Обработка запроса обновляет временную метку перед отправкой или повторной отправкой проверки. Поэтому обычный успешный замер исключает это начальное установление транспорта, но включает последующую пересылку и обратный путь. См. [готовность сокета][android-socket] и [обработку запросов][android-native].
Для WEB запуск моста, начальная HTTPS-загрузка, HELLO/WELCOME и дополнительные **500 мс** ожидания предшествуют `native_checkProxy`; эти 500 мс не прибавляются к показанному ping. WELCOME подтверждает WEB-сессию, а не готовность потока до Telegram DC. Затем нативная проверка подключается к `127.0.0.1`: готовность этого сокета не ждёт завершения удалённого OPEN. Java accept/OPEN и обновление нативной временной метки могут выполняться в разном порядке. Учитывается только работа, оставшаяся внутри интервала измерения. См. [порядок проверки][android-tester], [локальный сокет и WELCOME][android-transport], [создание серверной сессии][session] и [обработку потока][backend].
Схемы показывают обычный успешный путь, но не гарантируют порядок событий между потоками выполнения:
```mermaid
sequenceDiagram
participant C as Android native checker
participant P as Classic/DD/EE proxy
participant D as Telegram DC
C->>P: DNS / TCP / proxy transport setup
Note over C,P: Remote transport ready, measurement timestamp refreshed
C->>P: Encrypted TL_ping
P->>D: Relay
D->>P: TL_pong
P->>C: Relay
Note over C: Display elapsed time from latest request timestamp
```
```mermaid
sequenceDiagram
participant C as Android native checker
participant B as Local socket / Java / WebView
participant T as TLS frontend / Telemt
participant D as Telegram DC
B->>T: Bridge load, HELLO / session creation
T->>B: WELCOME
Note over B: Wait 500 ms before native_checkProxy
C->>B: Connect to 127.0.0.1
Note over C,B: Local socket ready, measurement timestamp refreshed
Note over B,T: OPEN may race with the native timestamp update
C->>B: MTProxy header and encrypted TL_ping
B->>T: OPEN / DATA over selected carrier
T->>D: Stream setup and relay via Direct / ME
D->>T: TL_pong
T->>B: Downlink DATA
B->>C: Local socket delivery
Note over C: Display elapsed time from latest request timestamp
```
`TL_pong` завершает замер относительно последней временной метки запроса. Принудительная обработка или повторная отправка могут обновить её: результат не обязательно равен полному времени неудачной попытки с повторами. Проверка использует [существующий ключ авторизации DC][android-key]; полный обмен для создания нового ключа MTProto не является обязательной частью каждой проверки.
## Вклад TLS
Публичное TLS-соединение завершается в NGINX, HAProxy или Caddy. Telemt получает обычный HTTP/1.1 на приватном listener. Внешний HTTP/2 и внутренний HTTP/1.1 — разные соединения; версии протокола на этих участках могут различаться. EE FakeTLS — маскирующий транспорт MTProxy, а не браузерное HTTPS-соединение с проверкой сертификата. WEB переносит plain/DD MTProxy; EE не является форматом секрета WEB. См. [руководство WEB](WEB_PROXY.ru.md).
Для нового соединения без потерь обычный TCP-handshake занимает примерно один RTT между клиентом и фронтендом. Полный TLS 1.3 handshake обычно добавляет один RTT, полный TLS 1.2 — два. Это оценка обменов протокола без DNS, обработки, проверки сертификата, планирования и повторной передачи, а не измеренный бюджет задержки WEB. Возобновление TLS-сессии может изменить обмен. См. [TLS 1.3][tls13] и [TLS 1.2][tls12].
Начальный TLS для загрузки моста обычно происходит до измерения Android. Дополнительные HTTP-соединения или WebSocket Upgrade могут оказаться внутри него; повторное использование соединений нужно подтверждать трассировкой. Постоянное HTTPS-соединение и установленный WebSocket не выполняют новый TLS-handshake для каждого ping. `cache: 'no-store'` управляет кешированием, а не повторным использованием TCP/TLS. Для объяснения и диагностики не требуется отключать проверку сертификатов или включать TLS 0-RTT. См. [постоянные HTTP-соединения][http1] и [запросы моста][request].
## Где WEB добавляет работу относительно обычного MTProxy
На схеме разделены этапы до запуска таймера Android и работа, которая может попасть в показанный результат. Базовый вариант — Classic/DD поверх TCP. Для EE FakeTLS относится к подготовке нативного транспорта. Размеры блоков и длины стрелок не обозначают длительность.
```mermaid
flowchart LR
subgraph N["Обычный MTProxy: Classic/DD"]
direction TB
N0["До измерения<br/>DNS + TCP + подготовка нативного транспорта"] --> N1["Удалённый транспорт готов<br/>Временная метка запроса обновлена"]
N1 --> N2["Запрос и ответ MTProxy<br/>Оставшаяся подготовка relay, сеть, очереди, Telegram DC"] --> N3["Получен TL_pong<br/>Отображаемый замер завершён"]
end
subgraph W["WEB: MTProxy внутри HTTPS или WebSocket"]
direction TB
W0["До измерения<br/>DNS + TCP + настоящий TLS<br/>HTTP-мост + HELLO/WELCOME + 500 мс"] --> W1["Локальный сокет готов<br/>Временная метка запроса обновлена"]
W1 --> W2["Дополнительная работа клиента<br/>Очереди Java / WebView / JavaScript<br/>Удалённый OPEN ещё может быть не завершён"] --> W3["Работа транспорта на отправке<br/>HTTP upload или кадр WebSocket<br/>Обработка фронтендом и возможная буферизация"]
W3 --> W4["Внутренний запрос и ответ MTProxy<br/>Оставшаяся подготовка relay, сеть, очереди, Telegram DC"] --> W5["Работа транспорта на приёме<br/>HTTP poll или кадр WebSocket<br/>Ожидание ACK/commit и очереди доставки в native"]
W5 --> W6["Получен TL_pong<br/>Отображаемый замер завершён"]
X["Только если нужно ещё одно соединение<br/>TCP + TLS, возможный WebSocket Upgrade<br/>При переиспользовании нет handshake на каждый ping"] -.-> W3
X -.-> W5
R["Только при ошибках или перегрузке<br/>Повторы и backoff<br/>База Telemt 250 мс<br/>Плюс опциональный jitter"] -.-> W3
R -.-> W5
end
classDef preparation fill:#eeeeee,stroke:#666666,color:#111111
classDef boundary fill:#dbeafe,stroke:#2563eb,color:#111111
classDef shared fill:#dcfce7,stroke:#15803d,color:#111111
classDef extra fill:#ffedd5,stroke:#c2410c,color:#111111
class N0,W0 preparation
class N1,N3,W1,W6 boundary
class N2,W4 shared
class W2,W3,W5,X,R extra
```
**Серый:** работа до отображаемого замера. **Синий:** границы таймера. **Зелёный:** работа MTProxy relay/DC, присутствующая в обоих путях, но не обязательно одинаковая по длительности. **Оранжевый:** работа WEB-транспорта и клиента внутри замера. **Пунктир:** условные затраты на соединения или повторы, а не обязательные этапы.
При повторном использовании транспорта условные затраты на TCP/TLS/Upgrade исчезают, но остаются формирование кадров, обработка HTTP или WebSocket и очереди клиента. HTTP может совмещать отправку и приём: каждый запрос не обязательно добавляет целый RTT. Polling пробуждается при появлении данных, а буферизация фронтенда зависит от развёртывания. Потери, перегрузка сети и подготовка upstream могут задерживать и обычный MTProxy.
Таким образом, в видимую разницу могут войти оставшееся открытие WEB-потока, дополнительные соединения, обработка транспорта, планирование и подтверждённые повторы. Это не фиксированная надбавка TLS и не арифметическая сумма блоков. Начальный настоящий TLS намеренно показан до таймера Android: он влияет на полное время проверки, но обычно не на отображаемый замер. Отдельный транспорт проверки также означает, что активное соединение приложения не гарантирует прогретую проверку в списке прокси.
### Настраиваемый jitter HTTP-повторов
`[web.retry_jitter]` добавляет независимо выбранную задержку к каждому существующему HTTP-повтору бриджа: сетевым ошибкам и ответам 408/429/502/503/504. Менять приложения Telegram не требуется. Без секции или при `enabled = false` сохраняются подсказка Telemt на 250 мс и прежний backoff/jitter.
```toml
[web.retry_jitter]
enabled = true
min_ms = 0
max_ms = 250
distribution = "uniform"
# Only for distribution = "triangular":
# peak_ms = 125
```
Диапазон задаёт **добавку**, а не полную паузу: подсказка Telemt 250 мс с этим примером даёт 250–500 мс. Без положительной серверной подсказки база остаётся 250, 500, 1000, затем 2000 мс. Включённый jitter заменяет прежний jitter до 25%. Корректный стандартный `Retry-After` во включённом режиме не сокращается прежним пределом в 30 секунд. Если пауза не помещается в оставшийся бюджет операции, бюджет истекает без раннего повтора.
Значения по умолчанию: `enabled = false`, `min_ms = 0`, `max_ms = 250`, `distribution = "uniform"`, `peak_ms` отсутствует. Требуется `0 <= min_ms <= max_ms <= 30000`. `uniform` выбирает целые миллисекунды равномерно; `triangular` использует треугольную плотность с округлением до миллисекунд. Необязательный пик по умолчанию находится посередине и должен входить в диапазон. Явный пик для `uniform`, неизвестные ключи/распределения и неверные границы отклоняются даже при выключенной опции. Одинаковые границы дают постоянную добавку.
Политика фиксируется в каждой странице бриджа. Reload через конфиг/API влияет на новые страницы; активные сохраняют настройки при recovery. Recovery JSON и HTTP-заголовки совместимости не меняются. Используется `crypto.getRandomValues`, при недоступности — `Math.random` для совместимости. Успешный трафик не задерживается. Лимиты попыток, общий бюджет, отмена и повтор неизменных payload/sequence сохраняются; более длинные паузы могут уменьшить число попыток, помещающихся в startup/recovery-бюджет.
Это размывает фиксированные интервалы повторов, но не гарантирует защиту от DPI. Планирование браузера, сетевые очереди и другие временные характеристики протокола остаются наблюдаемыми. Существующие примеры временной шкалы описывают выключенную опцию. Для включённого режима добавляйте выбранную задержку к каждой паузе повтора, а не к первому соединению или каждому кадру данных.
Политика меняет только уже предусмотренные паузы перед повтором. Более строгие ограничения отдельных вызовов сохраняются: обычный poll `/down` и вызов `/up` после commit выполняют одну попытку; их replay при восстановлении допускает две. Опция не создаёт новых циклов повторов. Она не продлевает `web.timeouts.bridge_retry_secs` и сроки запуска или восстановления.
## Ориентировочная временная шкала
**Поясняющая модель, а не бенчмарк и не норматив задержки.** Числа подобраны, чтобы показать сложение этапов. Они не восстанавливают наблюдавшиеся 1000–1500 мс. Условия примера: DNS уже закеширован, RTT от клиента до фронтенда — 40 мс, TCP-соединение новое, при необходимости выполняется полный TLS 1.3 handshake, ключ авторизации DC уже есть, потерь и сброса нативной временной метки запроса нет. Базовый вариант — Classic/DD. Для EE собственная подготовка FakeTLS добавляется до нативного таймера.
В этом примере подготовка обычного MTProxy занимает 40 мс на TCP. Подготовка WEB занимает 750 мс: 50 мс на запуск клиента/моста + 40 мс TCP + 40 мс TLS + 120 мс HTTP-обмена загрузки моста/создания сессии + 500 мс ожидания Android checker. Здесь выбраны последовательные длительности; в действительности этапы могут перекрываться. Начальный TLS и ожидание 500 мс находятся вне отображаемого ping.
Диаграмма начинается с **последней временной метки запроса** каждой проверки, а не с запуска приложения или первой попытки соединения. Горизонтальная ось показывает секунды с точностью до миллисекунд (0.200 = 200 мс). Ширина полос пропорциональна длительности. Каждая секция — отдельный сценарий; его этапы выполняются последовательно, а не параллельно. Начальная подготовка остаётся за пределами диаграммы.
```mermaid
%%{init: {"theme": "neutral", "gantt": {"leftPadding": 200, "rightPadding": 100, "barHeight": 24, "barGap": 8, "fontSize": 14, "sectionFontSize": 14}}}%%
gantt
dateFormat x
axisFormat %S.%L
tickInterval 100millisecond
todayMarker off
title Отображаемый ping - jitter выключен
accTitle: Отображаемый ping - jitter выключен
accDescr: Секунды от метки запроса, подписи этапов в миллисекундах
section Classic/DD - 100 мс
R 100 мс :n_r, 0, 100ms
section WEB без ошибок - 200 мс
U 40 мс :w_u, 0, 40ms
R 100 мс :w_r, after w_u, 100ms
D 60 мс :w_d, after w_r, 60ms
section WEB с повтором - 490 мс
F 40 мс :crit, f_u, 0, 40ms
Ожидание 250 мс :crit, retry_wait, after f_u, 250ms
U 40 мс :retry_u, after retry_wait, 40ms
R 100 мс :retry_r, after retry_u, 100ms
D 60 мс :retry_d, after retry_r, 60ms
```
Длительности этапов: `R` = 100 мс базовой работы MTProxy relay/сети/DC для запроса и ответа. `U` = 40 мс дополнительной работы WEB на отправке/OPEN/клиенте. `D` = 60 мс дополнительной работы WEB на приёме и доставке. `F` = 40 мс одной неудачной попытки upload. `Ожидание` = 250 мс ожидания по `X-Telemt-Retry-After-Ms: 250`. `U` и `D` — условные дополнительные затраты сверх `R`, а не повторный учёт полного сетевого RTT. Ожидание ACK/commit учитывается лишь в той мере, в какой оно действительно задержало доставку.
| Сценарий | До таймера ping | Отображаемый ping | Полное время проверки в модели |
| --- | --- | --- | --- |
| Classic/DD | 40 мс | 100 мс | 140 мс |
| WEB без ошибок | 750 мс | 40 + 100 + 60 = 200 мс | 950 мс |
| WEB с одной неудачной загрузкой и одним ожиданием повтора | 750 мс | 40 + 250 + 40 + 100 + 60 = 490 мс | 1240 мс |
| WEB, тот же повтор с uniform jitter 0–250 мс | 750 мс | 490–740 мс | 1240–1490 мс |
Ещё одно TCP + TLS 1.3 соединение, открытое **внутри** замера, могло бы добавить здесь около 80 мс при полностью последовательном выполнении: замер 200 мс превратился бы в 280 мс. При переиспользовании соединения затраты на этот дополнительный handshake равны нулю. Замена начального полного TLS 1.3 handshake на TLS 1.2 при этих условиях добавляет примерно 40 мс к подготовке, а не к показанному ping. В примерах не учтены обработка TLS, возобновление сессии и потери пакетов.
Строка с 490 мс и диаграмма показывают один повтор при выключенном jitter. Дополнительная строка таблицы применяет к тому же повтору `enabled = true`, `min_ms = 0`, `max_ms = 250`, `distribution = "uniform"`; её диапазон получен из модели, а не измерений. Прежний JavaScript-мост без миллисекундного расширения или посредник, удаляющий эту подсказку при выключенном jitter, сохраняет стандартную секундную паузу: отображаемый ping в той же модели составит 1240 мс. Ни один сценарий не устанавливает причину исходного наблюдения. Если повторы не подтверждены трассировкой, ищите другие задержки: очереди, буферизацию фронтенда, открытие соединений или upstream. Не подставляйте таймауты вместо пауз и не переносите перекрывающиеся этапы в эту последовательную модель без проверки.
## HTTP, WebSocket и другие источники задержки
Ответы Telemt при перегрузке содержат `Retry-After: 1` и `X-Telemt-Retry-After-Ms: 250`. Только статус `503` с этой точной парой заголовков задаёт сгенерированному мосту **базовую паузу 250 мс**. При `web.retry_jitter.enabled = false` пауза равна 250 мс; при включении добавляется настроенная случайная задержка. Для остальных ответов действуют стандартная обработка `Retry-After` или резервный backoff, описанные ниже. Ранее загруженные страницы JavaScript-моста без поддержки миллисекундной подсказки используют секундную паузу до загрузки новой страницы; обновлять приложение Telegram для этого не нужно. Лимиты попыток, абсолютные бюджеты, отмена и ограничения admission не меняются.
| Фактор | Влияние и подтверждение |
| --- | --- |
| HTTP uplink | Генерируемый мост предлагает `X-Telemt-Up-Window: 4`; сервер принимает 1–4, при отсутствии согласования используется 1. Окно 1 ждёт ACK перед следующей загрузкой, окно 4 допускает ограниченный параллелизм. Не весь HTTP работает по схеме «отправить и ждать». См. [согласование][runtime] и [обработчик сессии][session]. |
| Первый downlink | `/down` может запускаться одновременно с `/up`; обязательного дополнительного последовательного ACK RTT нет. Первичная доставка в нативный клиент ждёт первого корректного upload ACK/commit. Кадры доставляются по мере поступления. См. [conveyor][conveyor] и [downlink][downlink]. |
| Long polling | `long_poll_secs=25` ограничивает ожидание при отсутствии данных. Готовые данные немедленно будят poll. Промежутки между запросами и занятые слоты соединений браузера всё же могут задержать доставку. См. [серверный polling][poll]. |
| Общие ресурсы транспорта | `https` использует общую очередь загрузки; `https-lanes` разделяет логические линии. WebSocket после Upgrade передаёт кадры без POST на каждый кадр; `websocket-lanes` разделяет сокеты. Сеть, flow control и ресурсы WebView остаются общими. HTTP/2 мультиплексирует потоки, но не устраняет все задержки от перегрузки и flow control. См. [HTTP/2][http2] и [руководство по транспортам](WEB_PROXY.ru.md). |
| Буферизация фронтенда | Буферизация запросов/ответов или отсутствие поддержки streaming/Upgrade могут задерживать короткие сообщения. Сверьте настройки с существующим примером NGINX, сохраняя маршрутизацию, аутентификацию и лимиты. |
| Планирование клиента | Java accept/read, UI dispatch, WebView/JavaScript и возврат в нативный код добавляют очереди. Нагрузка CPU, энергосбережение и смена мобильной сети могут усиливать задержки. |
| Пересылка и сеть | Могут учитываться оставшийся admission потока, внутренний MTProxy-handshake, подключение Direct или регистрация ME, ответ Telegram, потери/повторная передача и очереди. Готовая WEB-сессия не доказывает готовность upstream. |
| Ошибки и повторы | Повторяемые статусы: 408/429/502/503/504. При выключенном jitter точная подсказка Telemt задаёт паузу 250 мс; без положительной подсказки сервера backoff начинается с 250 мс и удваивается до базовых 2000 мс плюс прежний jitter менее 25%. При включённом jitter пауза равна положительной подсказке сервера или этой базе **плюс** настроенная случайная добавка, заменяющая прежний jitter. Бюджеты и ограничения попыток отдельных вызовов сохраняются. Фиксируйте политику загруженного моста и фактическое время повторов. См. [ответы][response] и [повторы][request]. |
Дедлайны не являются обязательными паузами. Стандартные 10 с для запроса моста, 90 с бюджета повторов, 30 с ожидания первого байта потока и 10 с handshake потока нельзя складывать в обычный ping. `carrier_probe_coalesce_ms=0` отключает соответствующую дополнительную задержку объединения проб. Дедлайны переключения транспорта относятся к неудачным попыткам, а не к каждому успешному обмену. См. [значения по умолчанию](../../src/config/types/web/defaults.rs).
Условно WEB-замер включает **оставшуюся подготовку + передачу через транспорт и сеть + очереди + ответ Telegram + задержки повторов, попавшие внутрь таймера**. Этапы перекрываются; складывать все таймауты или назначать отдельный RTT каждому HTTP endpoint некорректно. Готовый транспорт может сократить подготовку, но Android проверяет прокси через отдельный транспорт. WebSocket не всегда быстрее; используйте только поддерживаемые клиентом транспорты. Для совместимости с текущим iOS используется `https`.
## Диагностика с сохранением защит
1. Запишите клиент/сборку, версию Android WebView, политику `web.retry_jitter` загруженного моста, транспорт, публичный endpoint, семейство IP, сеть, маршрут Direct/ME, DC и нагрузку. Сравнивайте при одинаковых условиях. Учитывайте двухминутное кеширование Android: повторное чтение интерфейса не означает новый замер.
2. Разделяйте три эксперимента: новую проверку в списке прокси; новый логический поток на готовом транспорте; прикладной RPC в установленной MTProto-сессии. Последние два требуют подходящих средств измерения в клиенте и не предоставляются автоматически списком прокси. Собирайте отдельные замеры и распределения, а не сравнивайте единичный холодный замер с прогретым.
3. Используйте аутентифицированный `GET /web-status` и существующие настройки `[web.debug]`: `capture_timings=true`, `capture_frames=true`, `body_capture="metadata"`. Включите ограниченный сбор по [руководству диагностики WEB](WEB_PROXY.ru.md), затем восстановите предыдущее состояние. Payload, capabilities и секреты для этой задачи не нужны.
4. Сопоставьте создание сессии, выбор/commit/ошибку транспорта, `stream_admitted`, `stream_first_byte`, `handshake_succeeded`, OPEN/DATA, HTTP-статусы и повторы. `relay_started` предшествует работе с upstream и не означает готовность DC. `GET /v1/runtime/web/status` и `GET /v1/runtime/web/sessions` дают контекст ёмкости и давления очередей, а не сквозной RTT.
5. `request_body_us`, `response_ready_us` и `response_body_us` — смещения от входа в обработчик. Это не независимые длительности для сложения и не моменты отправки в сеть или TCP ACK от другой стороны. Сравнивайте смещения там, где они записаны и имеют подходящий смысл. См. [определения timing-полей][timings].
6. Добавьте измерения соединений/TLS/запросов фронтенда и временные метки клиента, чтобы найти задержку вне Telemt. Проверьте повторное использование соединений, согласованный HTTP, буферизацию и Upgrade. Sideband-события запуска моста/HELLO не дают полную временную шкалу клиента. Для сравнения разных хостов синхронизируйте часы либо используйте локальные длительности.
7. При ME сопоставьте существующий trace `ME RTT sample` (`rtt_ms`, `ema_ms`, `base_ms`, `degraded`). Метка ставится до очереди writer/flush; EMA состоит из 80% прежнего значения и 20% нового замера. Планирование keepalive до этой метки не учитывается. Низкий ME RTT при высоком Android ping указывает на работу вне измеренного участка ME, но не определяет конкретную причину. См. [writer][writer] и [reader][reader].
Примеры интерпретации: быстрая обработка Telemt при поздней доставке клиенту направляет проверку к фронтенду, сети и очередям клиента; `503` и его retry-заголовки определяют базовую задержку, а политика jitter загруженного моста и клиентские отметки времени позволяют установить фактическую паузу; длительная работа upstream требует изучения Direct/ME. Ни один из признаков сам по себе не доказывает, что 1000–1500 мс вызваны криптографией TLS. При сборе данных сохраняйте совместимость, проверку сертификатов, лимиты admission и backpressure.
## Границы подтверждения
Документ описывает изученные исходники, а не сквозной тест на устройствах. Ссылки Android/iOS закрепляют указанные ревизии; ссылки Telemt ведут к сопровождающей документ реализации рабочего дерева, включая локальные WEB-изменения, и не утверждают идентичность всех опубликованных пакетов. Документация не меняет клиент, сервер, таймауты или настройки безопасности.
[android-entry]: https://github.com/DrKLO/Telegram/blob/3de37c8cfb039452be7398909461da6288babf15/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java#L752-L765
[android-tester]: https://github.com/DrKLO/Telegram/blob/3de37c8cfb039452be7398909461da6288babf15/TMessagesProj/src/main/java/org/telegram/utils/proxy/WebProxyConnectionTester.java#L111-L172
[android-transport]: https://github.com/DrKLO/Telegram/blob/3de37c8cfb039452be7398909461da6288babf15/TMessagesProj/src/main/java/org/telegram/utils/proxy/WebProxyTransport.java
[android-native]: https://github.com/DrKLO/Telegram/blob/3de37c8cfb039452be7398909461da6288babf15/TMessagesProj/jni/tgnet/ConnectionsManager.cpp
[android-socket]: https://github.com/DrKLO/Telegram/blob/3de37c8cfb039452be7398909461da6288babf15/TMessagesProj/jni/tgnet/ConnectionSocket.cpp
[android-key]: https://github.com/DrKLO/Telegram/blob/3de37c8cfb039452be7398909461da6288babf15/TMessagesProj/jni/tgnet/Datacenter.cpp#L1312-L1323
[android-ui]: https://github.com/DrKLO/Telegram/blob/3de37c8cfb039452be7398909461da6288babf15/TMessagesProj/src/main/java/org/telegram/ui/ProxyListActivity.java#L671-L687
[ios-filter]: https://github.com/TelegramMessenger/Telegram-iOS/blob/279f89e4d4f63f17227bf877dc3d8990f22ecd58/submodules/TelegramCore/Sources/Network/ProxyServersStatuses.swift#L54-L65
[ios-probe]: https://github.com/TelegramMessenger/Telegram-iOS/blob/279f89e4d4f63f17227bf877dc3d8990f22ecd58/submodules/MtProtoKit/Sources/MTProxyConnectivity.m#L57-L99
[ios-ui]: https://github.com/TelegramMessenger/Telegram-iOS/blob/279f89e4d4f63f17227bf877dc3d8990f22ecd58/submodules/SettingsUI/Sources/Data%20and%20Storage/ProxyListSettingsController.swift#L273-L310
[tls13]: https://datatracker.ietf.org/doc/html/rfc8446#section-2
[tls12]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.3
[http1]: https://www.rfc-editor.org/rfc/rfc9112#section-9.3
[http2]: https://datatracker.ietf.org/doc/html/rfc9113#section-5
[session]: ../../src/web/http/session.rs
[backend]: ../../src/web/session/backend.rs
[runtime]: ../../src/web/bridge/runtime.js
[conveyor]: ../../src/web/bridge/conveyor.js
[downlink]: ../../src/web/bridge/downlink.js
[poll]: ../../src/web/session/downlink.rs
[request]: ../../src/web/bridge/request.js
[response]: ../../src/web/http/response.rs
[timings]: ../../src/web/trace/types.rs
[writer]: ../../src/transport/middle_proxy/pool_writer.rs
[reader]: ../../src/transport/middle_proxy/reader.rs