--check can now probe the proxy's own listener, not just the upstreams it is configured with:
--check-listener serves as usual, sends a real MTProto request through its own socket, and requires
Telegram's resPQ back.
Why
--check answers "will this box reach Telegram", and it answers it for every tier the config names —
CF domains, a Worker, upstream MTProto proxies. What it never covered is the listener a client
actually connects to: it can be up with a secret no client has, and the tier the routing picks can be
the one that does not work here, while every upstream probe still prints OK.
The handshake alone cannot close that gap, and the existing plain-MTProto upstream probe shows why: it
sends the 64 obfuscated bytes and never reads a reply, so a proxy that accepts the handshake and then
has nowhere to forward the connection passes the check. The Worker probe was fixed for exactly this
reason in #93 — a tunnel has to prove the far end is a DC, not merely that something answered.
Added
-
--check-listener(envTG_CHECK_LISTENER, implies--check). The process binds and serves as
usual, probes the socket it just bound with a client-side obfuscated handshake and a real
req_pq_multi, and requires the reply to decrypt toresPQ. It is the only check that covers the
whole chain: the inbound handshake, the tier the routing picks and the DC.- The probe talks to this process's own socket, so the secret, the address and the inbound mode are
the ones actually being served — nothing to repeat by hand, andTG_CHECK=true TG_CHECK_LISTENER=truein a container tests something instead of finding nothing listening. - The probe reaches the bound socket over loopback, never through an outbound proxy.
- A listener configured with
--listen-faketls-domainis reported as skipped rather than failed:
its first byte is a TLS record, so the plain probe cannot speak to it. A run whose only probe was
skipped exits non-zero, because nothing was verified. - The wait covers the connect timeouts the routing can spend before the DC answers, not just the
handshake budget: on a blackholed network the direct WebSocket attempt alone can burn
--ws-connect-timeoutbefore the next tier is tried.
- The probe talks to this process's own socket, so the secret, the address and the inbound mode are
Notes
- The probe checks the listener and the routing, not the
tg://link: it reaches the bound socket
over loopback, so a wrong--link-ip, a missing port-forward or a LAN firewall rule still passes. - FakeTLS inbound is not covered: that needs the client half of the camouflage — ClientHello signing
and app-data records in both directions. It is reported as skipped rather than half-implemented. - The
msg_idin the probe's request comes from the local clock, as the protocol defines it. On a
router whose RTC is still unsynced after boot the DC may reject it, while real clients — which use
their own clocks — keep working.