ZaStoGram/TMessagesProj/jni/mtproxy/MtProxyFailureEvidence.cpp
loop-uh 3f8f8f27e7 Extract mtproxy module with unified retry authority
Move MTProxy policy engine from tgnet/ to self-contained jni/mtproxy/ module. Consolidate reconnect hold computation into single MtProxyRetryAuthority owner (was split across Connection, ConnectionSocket, endpoint policy, and probe coordinator, causing hold misalignment bugs). Add MtProxyTerminalDiagnostic module with host tests for pre-I/O verdict preservation (fixes 02.07/30.06 clobber livelocks). Auto-generate phase classification (isPreIoTerminalVerdict, needsReconnectBackoff, isObservationFacadePhase, isLocalSchedulerTimeout) from single Python contract into both C++ and Java to eliminate parallel maintenance. Pass native hold (coordinator terminal hold + endpoint cooldown) via JNI to Java so reconnect timer and health store use THE clock, not re-derived ones. Optimize log flushing: batch debug lines, flush errors immediately. Add module boundary guard, host build system (MSVC), and unit tests for retry logic and terminal diagnostic derivation.
2026-07-02 18:25:13 +03:00

93 lines
4.3 KiB
C++

#include "MtProxyFailureEvidence.h"
#include "MtProxyPhaseContract.h"
MtProxyFailureEvidenceKind mtProxyEvidenceForPhase(const std::string &phase, size_t responseBytes) {
if (phase.empty()) {
return MtProxyFailureEvidenceKind::None;
}
if (phase == MtProxyPhase::ConnectionNotStarted
|| phase == MtProxyPhase::AdmissionTimeout
|| phase == MtProxyPhase::EndpointCooldownTimeout
|| phase == MtProxyPhase::MtproxyProbeWaitTimeout
|| phase == MtProxyPhase::DnsCoalesceTimeout
|| phase == MtProxyPhase::TcpConnectGateTimeout) {
return MtProxyFailureEvidenceKind::PreTcpLocalWait;
}
if (phase == MtProxyPhase::DnsNegativeCacheHit
|| phase == MtProxyPhase::DnsBlockedZeroAddress
|| phase == MtProxyPhase::HostResolveFailed
|| phase == MtProxyPhase::HostResolveTimeout) {
return MtProxyFailureEvidenceKind::DnsFailure;
}
if (phase == MtProxyPhase::TcpNotConnected
|| phase == MtProxyPhase::TcpConnectionRefused
|| phase == MtProxyPhase::TcpConnectTimeout
|| phase == MtProxyPhase::TcpConnectedNoPong) {
return MtProxyFailureEvidenceKind::TcpFailure;
}
if (phase == MtProxyPhase::FaketlsServerHelloWaitTimeout
|| phase == MtProxyPhase::FaketlsNoServerHelloTerminal
|| phase == MtProxyPhase::FaketlsServerClosedTerminal
|| phase == "true_client_hello_timeout"
|| phase == "client_hello_sent_no_server_hello") {
return MtProxyFailureEvidenceKind::NoBytesAfterClientHello;
}
if (phase == MtProxyPhase::ServerClosedAfterClientHello) {
return responseBytes == 0
? MtProxyFailureEvidenceKind::NoBytesAfterClientHello
: MtProxyFailureEvidenceKind::ServerBytesParserFailure;
}
if (phase == MtProxyPhase::TlsAlertAfterClientHello
|| phase == MtProxyPhase::ShortTlsResponseAfterClientHello
|| phase == MtProxyPhase::UnrecognizedResponseAfterClientHello
|| phase == MtProxyPhase::FaketlsNotMtproxyResponse
|| phase == "unrecognized_tls_response_after_client_hello") {
return MtProxyFailureEvidenceKind::ServerBytesParserFailure;
}
if (phase == MtProxyPhase::ServerHelloHmacMismatch) {
return MtProxyFailureEvidenceKind::ServerHelloHmacMismatch;
}
if (phase == MtProxyPhase::PostHandshakeNoAppdata
|| phase == MtProxyPhase::MtproxyPacketSentNoResponse
|| phase == MtProxyPhase::DroppedEarlyAfterAppdata
|| phase == MtProxyPhase::DroppedAfterAppdata) {
return MtProxyFailureEvidenceKind::PostHandshakeNoAppData;
}
if (phase == MtProxyPhase::SecretParseInvalidDomainControlChar
|| phase == MtProxyPhase::SecretParseInvalidDomain) {
return MtProxyFailureEvidenceKind::ConfigInvalidSecret;
}
if (phase == MtProxyPhase::BackgroundHandshakeAborted
|| phase == MtProxyPhase::ShadowedSocketFailure
|| phase == MtProxyPhase::IgnoredCancelledGeneration) {
return MtProxyFailureEvidenceKind::CancelledOrShadowed;
}
return MtProxyFailureEvidenceKind::None;
}
const char *mtProxyFailureEvidenceName(MtProxyFailureEvidenceKind kind) {
switch (kind) {
case MtProxyFailureEvidenceKind::PreTcpLocalWait:
return "pre_tcp_local_wait";
case MtProxyFailureEvidenceKind::DnsFailure:
return "dns_failure";
case MtProxyFailureEvidenceKind::TcpFailure:
return "tcp_failure";
case MtProxyFailureEvidenceKind::NoBytesAfterClientHello:
return "no_bytes_after_client_hello";
case MtProxyFailureEvidenceKind::ServerBytesParserFailure:
return "server_bytes_parser_failure";
case MtProxyFailureEvidenceKind::ServerHelloHmacMismatch:
return "server_hello_hmac_mismatch";
case MtProxyFailureEvidenceKind::PostHandshakeNoAppData:
return "post_handshake_no_app_data";
case MtProxyFailureEvidenceKind::ConfigInvalidSecret:
return "config_invalid_secret";
case MtProxyFailureEvidenceKind::CancelledOrShadowed:
return "cancelled_or_shadowed";
case MtProxyFailureEvidenceKind::None:
default:
return "none";
}
}