diff --git a/README.md b/README.md index 1de8494..aa338d7 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ go build -o mtproxy_checker.exe ./cmd/mtproxy_checker Флаги: `-timeout` (по умолчанию 15s), `-dc-id` (по умолчанию 2). -Код выхода: `0` — OK, `1` — ошибка, `2` — неверные аргументы, `3` — прокси закрыл соединение после проверки, `4` — таймаут. +Код выхода: `0` — OK (после рукопожатия от прокси получен хотя бы один байт данных), `1` — ошибка (в т.ч. «тишина» после MTProxy-заголовка), `2` — неверные аргументы, `3` — прокси закрыл соединение после проверки, `4` — таймаут. **Docker:** [docs/docker.ru.md](docs/docker.ru.md) — один образ: **с аргументами** после образа — CLI; **без аргументов** — HTTP API (файл со списком `tg://`, интервал, опциональный whitelist IP). diff --git a/docs/docker.ru.md b/docs/docker.ru.md index ae293dd..5e0c1fc 100644 --- a/docs/docker.ru.md +++ b/docs/docker.ru.md @@ -60,7 +60,7 @@ docker run -d --name mtproxy-api --restart unless-stopped -p 8080:8080 ` | GET | `/health` | `200`, `{"status":"ok"}` | | GET | `/api/v1/proxies` | `200`, JSON с полями `cycle_finished_at`, `next_check_after`, массив `proxies` | -Элемент `proxies[]`: `raw_line`, при успешном разборе — `url`, `ok`, `exit_code` (`0` OK, `1` ошибка проверки, `2` ошибка разбора URL/секрета, `3` прокси закрыл соединение, `4` таймаут), `error`, при необходимости `parse_error`, `checked_at`. +Элемент `proxies[]`: `raw_line`, при успешном разборе — `url`, `ok`, `exit_code` (`0` OK — после отправки MTProxy-заголовка прочитан хотя бы один байт от сервера; `1` ошибка проверки, в т.ч. если за окно ожидания **нет ни одного байта** ответа; `2` ошибка разбора URL/секрета; `3` прокси закрыл соединение; `4` таймаут всего запроса), `error`, при необходимости `parse_error`, `checked_at`. ### Whitelist IP и Docker @@ -280,8 +280,8 @@ docker run --rm registry.example.com/owner/mtproxy_checker:latest \ | Код | Значение | |-----|----------| -| 0 | Проверка прошла | -| 1 | Ошибка (сеть, протокол, неверный ответ) | +| 0 | Проверка прошла: после MTProxy-заголовка получен хотя бы один байт от прокси | +| 1 | Ошибка (сеть, протокол, неверный ответ; в т.ч. **нет данных** от прокси после заголовка за окно ожидания) | | 2 | Неверные аргументы CLI | | 3 | Прокси закрыл TCP сразу после начального payload | | 4 | Общий таймаут (`-timeout`) | @@ -292,6 +292,7 @@ docker run --rm registry.example.com/owner/mtproxy_checker:latest \ - `connection refused` — порт закрыт или фильтр. - `FAIL: timeout` — нет ответа за `-timeout`. +- `no data from proxy after mtproxy header` — рукопожатие прошло, но прокси не прислал ни одного байта в фазе после заголовка (часто совпадает с «Недоступен» в клиенте Telegram). - Ошибки чтения/проверки ServerHello — несовместимый ответ или обрыв соединения. Для отладки без `--rm` можно посмотреть логи контейнера по id; с `--rm` контейнер удаляется сразу после выхода. diff --git a/internal/checker/checker.go b/internal/checker/checker.go index c45fc12..b92726e 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -16,6 +16,10 @@ import ( // ErrProxyClosed indicates the MTProxy dropped the TCP connection right after the probe (Telethon #1134 style). var ErrProxyClosed = errors.New("mtproxy closed connection after initial payload") +// ErrNoDataAfterHeader indicates the proxy accepted the probe but sent no application data back within the wait window. +// Treating silence as success matched some servers but often disagrees with Telegram client "unavailable". +var ErrNoDataAfterHeader = errors.New("no data from proxy after mtproxy header (timeout)") + // Check runs the handshake probe for the given parsed secret. func Check(ctx context.Context, host string, port int, parsed *secret.Parsed, dcID int16) error { conn, err := dialTCP(ctx, host, port) @@ -101,5 +105,5 @@ func waitPostPayload(conn net.Conn) error { } } _ = conn.SetReadDeadline(time.Time{}) - return nil + return ErrNoDataAfterHeader }