ZaStoGram/Tools/check_mtproxy_clienthello_fragmentation.py
loop-uh 899de7640c Add MtProxy options JNI and refactor proxy policies
Introduce MtProxyOptions Java<->native binding and move MTProxy handshake/resilience logic into dedicated policy/state-machine modules. CMakeLists updated to include new source files (ConnectionSocketStateMachine, MtProxyAdaptivePolicy, MtProxyEndpointPolicy). TgNetWrapper now reads an MtProxyOptions object from JNI, updates native signatures for setProxySettings and checkProxy, and registers MtProxyOptions field IDs. ConnectionSocket has been refactored to delegate endpoint cooldowns, TCP connect gating, DNS coalescing, recipe/adaptive behavior and DNS cache handling to MtProxyEndpointPolicy and MtProxyAdaptivePolicy (removing large inline global maps and mutexed logic) and to use ConnectionSocketStateMachine helpers. Added MtProxyOptions Java class and several new tools/scripts to validate MTProxy behaviors. This change modularizes proxy policy, simplifies ConnectionSocket, and centralizes option handling.
2026-06-24 14:47:17 +03:00

107 lines
4.7 KiB
Python

#!/usr/bin/env python3
from pathlib import Path
import re
import sys
ROOT = Path(__file__).resolve().parents[1]
SOCKET_CPP = ROOT / "TMessagesProj/jni/tgnet/ConnectionSocket.cpp"
SOCKET_H = ROOT / "TMessagesProj/jni/tgnet/ConnectionSocket.h"
MACHINE_H = ROOT / "TMessagesProj/jni/tgnet/ConnectionSocketStateMachine.h"
MANAGER_CPP = ROOT / "TMessagesProj/jni/tgnet/ConnectionsManager.cpp"
MANAGER_H = ROOT / "TMessagesProj/jni/tgnet/ConnectionsManager.h"
WRAPPER_CPP = ROOT / "TMessagesProj/jni/TgNetWrapper.cpp"
CONNECTIONS_JAVA = ROOT / "TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java"
SHARED_CONFIG = ROOT / "TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java"
PROXY_LIST = ROOT / "TMessagesProj/src/main/java/org/telegram/ui/ProxyListActivity.java"
STRINGS = ROOT / "TMessagesProj/src/main/res/values/strings.xml"
STRINGS_RU = ROOT / "TMessagesProj/src/main/res/values-ru/strings.xml"
COLLECT = ROOT / "Tools/collect_mtproxy_logs.ps1"
def text(path: Path) -> str:
return path.read_text(encoding="utf-8", errors="replace")
def require(condition: bool, message: str) -> None:
if not condition:
print(f"FAIL: {message}", file=sys.stderr)
sys.exit(1)
def main() -> None:
socket_cpp = text(SOCKET_CPP)
socket_h = text(SOCKET_H)
socket_state = socket_h + "\n" + text(MACHINE_H) + "\n" + socket_cpp
manager_cpp = text(MANAGER_CPP)
manager_h = text(MANAGER_H)
wrapper_cpp = text(WRAPPER_CPP)
connections_java = text(CONNECTIONS_JAVA)
shared_config = text(SHARED_CONFIG)
proxy_list = text(PROXY_LIST)
collect = text(COLLECT)
require(
"mtProxyClientHelloFragmentation" in shared_config
and "mtProxyClientHelloFragmentation" in proxy_list
and "R.string.MtProxyClientHelloFragmentation" in proxy_list,
"proxy settings UI must expose a global ClientHello fragmentation toggle",
)
require(
"MT_PROXY_CLIENT_HELLO_FRAGMENTATION_OFF" in connections_java
and "resolveMtProxyClientHelloFragmentationMode()" in connections_java,
"Java must resolve a stable ClientHello fragmentation mode from SharedConfig",
)
require(
"MtProxyOptions.resolve(proxyAddress, proxyPort, proxySecret)" in connections_java
and "clientHelloFragmentation" in (ROOT / "TMessagesProj/src/main/java/org/telegram/tgnet/MtProxyOptions.java").read_text(encoding="utf-8", errors="replace"),
"real proxy settings must pass ClientHello fragmentation through MtProxyOptions",
)
require(
"native_checkProxy(currentAccount, address, port, username, password, secret, MtProxyOptions.resolve(address, port, secret), requestTimeDelegate)" in connections_java,
"proxy checks must use the same MtProxyOptions as real connections",
)
require(
"readMtProxyOptions(JNIEnv *env, jobject options)" in wrapper_cpp
and "jclass_MtProxyOptions_clientHelloFragmentation" in wrapper_cpp
and "Lorg/telegram/tgnet/MtProxyOptions;" in wrapper_cpp,
"JNI signatures must carry ClientHello fragmentation via MtProxyOptions",
)
require(
"MtProxyOptions proxyMtProxyOptions" in manager_h
and "optionsChanged" in manager_cpp
and "normalizeMtProxyOptions(options)" in manager_cpp,
"ConnectionsManager must store MTProxy options and reconnect when fragmentation changes",
)
require(
"proxyCheckInfo->mtProxyOptions = normalizeMtProxyOptions(options)" in manager_cpp,
"proxy-check native state must receive MtProxyOptions",
)
require(
"overrideMtProxyOptions" in socket_h
and "currentClientHelloFragmentation" in socket_state
and "setOverrideProxy" in socket_h,
"ConnectionSocket must carry fragmentation mode through MtProxyOptions for normal and override proxy paths",
)
require(
"sendPendingClientHelloFragment" in socket_cpp
and "mtproxy_startup client_hello_fragment" in socket_cpp
and "MT_PROXY_CLIENT_HELLO_FRAGMENTATION_SOFT" in socket_cpp,
"ClientHello send path must implement and log soft fragmentation as a separate layer",
)
require(
"client_hello_fragment" in collect
and "$textFiles = @(Join-Path $sessionDir \"logcat.txt\")" in collect,
"collector must include fragmentation markers and analyze live logcat without old device-log contamination",
)
require(
'name="MtProxyClientHelloFragmentation"' in text(STRINGS)
and 'name="MtProxyClientHelloFragmentation"' in text(STRINGS_RU),
"ClientHello fragmentation UI strings must exist in base and Russian resources",
)
print("MTProxy ClientHello fragmentation guard passed.")
if __name__ == "__main__":
main()