ZaStoGram_desktop/Telegram/SourceFiles/mtproto/proxy/socket_factory.cpp
loop-uh 70a70e809d
Some checks failed
Desktop source guards / guards (push) Has been cancelled
WSS: прямой TCP — последняя ступень с охраной, перед фронтами без учёта паузы
Прямой 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>
2026-10-16 21:48:41 +03:00

80 lines
2 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "mtproto/proxy/socket_factory.h"
#include "mtproto/proxy/mtproxy/tls_socket.h"
#include "mtproto/proxy/wss/socket.h"
#include "mtproto/details/mtproto_web_proxy_socket.h"
#include "mtproto/transport/details/mtproto_tcp_socket.h"
namespace MTP::details {
std::unique_ptr<AbstractSocket> CreateProxyAwareSocket(
not_null<RuntimeEnvironment*> runtime,
not_null<QThread*> thread,
const bytes::vector &secret,
const ProxyData &proxy,
bool protocolForFiles,
const ProxyStealthOptions &stealth,
int16 protocolDcId,
ProxyConnectionAttempt mtproxyAttempt,
MtProxyAttemptPlan mtproxyPlan,
crl::time mtproxyAttemptStartedAt,
bool wssFront) {
if (proxy.type == ProxyData::Type::Web) {
return std::make_unique<WebProxySocket>(
runtime,
thread,
proxy,
mtproxyAttempt.use);
}
const auto networkProxy = ToNetworkProxy(proxy);
if (stealth.transport == ProxyTransport::Wss) {
auto route = WssCustomRoute(stealth);
if (!route && wssFront) {
route = WssFrontRoute(protocolDcId);
}
if (!route) {
route = WssOfficialRoute(protocolDcId);
}
if (route && route->direct) {
return std::make_unique<WssDirectStepSocket>(
runtime,
thread,
networkProxy,
protocolForFiles,
std::move(*route));
} else if (route) {
return std::make_unique<WssSocket>(
runtime,
thread,
networkProxy,
protocolForFiles,
std::move(*route));
}
}
if (secret.size() >= 21 && secret[0] == bytes::type(0xEE)) {
return std::make_unique<TlsSocket>(
runtime,
thread,
secret,
proxy,
protocolForFiles,
stealth,
mtproxyAttempt,
std::move(mtproxyPlan),
mtproxyAttemptStartedAt);
}
return std::make_unique<TcpSocket>(
runtime,
thread,
networkProxy,
protocolForFiles);
}
} // namespace MTP::details