ZaStoGram/TMessagesProj/jni/mtproxy/MtProxyAdaptivePolicy.h
2026-08-05 19:18:49 +03:00

165 lines
6.7 KiB
C++

/*
* This is the source code of tgnet library v. 1.1
* It is licensed under GNU GPL v. 2 or later.
*/
#ifndef MTPROXYADAPTIVEPOLICY_H
#define MTPROXYADAPTIVEPOLICY_H
#include <stdint.h>
#include <string>
#include "MtProxyOptions.h"
#include "MtProxyRecoveryPolicy.h"
class MtProxyAdaptivePolicy {
public:
enum ClientHelloFamily : int32_t {
CLIENT_HELLO_CHROME_MODERN_SOFT_FRAGMENT = 0,
CLIENT_HELLO_CHROME_MODERN_NO_FRAGMENT = 1,
CLIENT_HELLO_ANDROID_CHROME_NO_FRAGMENT = 2,
CLIENT_HELLO_FIREFOX_ANDROID_NO_FRAGMENT = 3,
CLIENT_HELLO_LEGACY_NO_GREASE_NO_MODERN_EXTENSIONS = 4,
CLIENT_HELLO_LEGACY_TLS12_MINIMAL = 5,
CLIENT_HELLO_FAMILY_COUNT = 6,
};
enum SniVariant : int32_t {
SNI_ORIGINAL = 0,
SNI_SANITIZED = 1,
SNI_LOWERCASE_ASCII = 2,
SNI_NO_TRAILING_DOT = 3,
SNI_PUNYCODE = 4,
SNI_OPTIONAL_NO_SNI = 5,
SNI_VARIANT_COUNT = 6,
};
enum ServerHelloParserVariant : int32_t {
PARSER_STANDARD_HMAC = 0,
PARSER_LENIENT_RECORD = 1,
PARSER_TOLERATE_EXTRA_RECORDS_BEFORE_SERVER_HELLO = 2,
PARSER_TOLERATE_CCS_TICKET_ORDERING = 3,
PARSER_TOLERATE_FRAGMENTED_SERVER_HELLO = 4,
PARSER_TOLERATE_TLS_ALERT_EXACT_DESC = 5,
PARSER_VARIANT_COUNT = 6,
};
enum ClassicVariant : int32_t {
CLASSIC_NONE = 0,
CLASSIC_STANDARD_INTERMEDIATE = 1,
CLASSIC_RANDOMIZED_INTERMEDIATE = 2,
CLASSIC_ABRIDGED_FALLBACK = 3,
CLASSIC_INTERMEDIATE_FALLBACK = 4,
CLASSIC_VARIANT_COUNT = 5,
};
struct RecipeCursor {
int32_t family = CLIENT_HELLO_CHROME_MODERN_NO_FRAGMENT;
int32_t sniVariant = SNI_ORIGINAL;
int32_t parserVariant = PARSER_STANDARD_HMAC;
int32_t classicVariant = CLASSIC_NONE;
uint32_t generation = 0;
};
struct CompatibilityRecipe {
RecipeCursor cursor;
std::string familyName;
std::string sniVariantName;
std::string parserVariantName;
std::string classicVariantName;
std::string transportMode;
std::string tlsProfile;
std::string clientHelloSni;
bool fragmentClientHello = false;
bool useGrease = false;
bool useModernExtensions = false;
bool experimentalNoSni = false;
int32_t clientHelloFragmentation = MT_PROXY_CLIENT_HELLO_FRAGMENTATION_OFF;
int32_t effectiveTlsProfile = MT_PROXY_TLS_PROFILE_FIREFOX_ANDROID;
int32_t serverHelloParserMode = MT_PROXY_SERVER_HELLO_PARSER_STANDARD;
int32_t connectionPatternMode = MT_PROXY_CONNECTION_PATTERN_OFF;
int32_t recordSizingMode = MT_PROXY_RECORD_SIZING_OFF;
int32_t timingMode = MT_PROXY_TIMING_OFF;
int32_t startupCoverMode = MT_PROXY_STARTUP_COVER_OFF;
};
struct RecipeInput {
bool fakeTls = false;
std::string endpointKey;
std::string sni;
std::string originalSni;
std::string sanitizedSni;
std::string lowercaseAsciiSni;
std::string noTrailingDotSni;
std::string punycodeSni;
uint32_t allowedSniVariants = 0;
bool useRecipeCursor = false;
RecipeCursor cursor;
bool forceNoGrease = false;
bool probeGrease = false;
bool greaseSupported = false;
std::string lastDiagnostic;
int32_t recipeLevel = 0;
int32_t alternateProfileIndex = 0;
int32_t clientHelloFragmentation = MT_PROXY_CLIENT_HELLO_FRAGMENTATION_OFF;
int32_t configuredTlsProfile = MT_PROXY_TLS_PROFILE_AUTO;
int32_t effectiveTlsProfile = MT_PROXY_TLS_PROFILE_FIREFOX_ANDROID;
int32_t serverHelloParserMode = MT_PROXY_SERVER_HELLO_PARSER_STANDARD;
int32_t connectionPatternMode = MT_PROXY_CONNECTION_PATTERN_OFF;
int32_t recordSizingMode = MT_PROXY_RECORD_SIZING_OFF;
int32_t timingMode = MT_PROXY_TIMING_OFF;
int32_t startupCoverMode = MT_PROXY_STARTUP_COVER_OFF;
};
struct MtProxyRecipe {
std::string transportMode;
std::string tlsProfile;
bool fragmentClientHello = false;
bool useGrease = false;
bool useModernExtensions = false;
std::string serverHelloParser;
std::string sni;
};
struct RecipeResult {
bool changed = false;
int32_t recipeLevel = 0;
int32_t clientHelloFragmentation = MT_PROXY_CLIENT_HELLO_FRAGMENTATION_OFF;
int32_t effectiveTlsProfile = MT_PROXY_TLS_PROFILE_FIREFOX_ANDROID;
int32_t serverHelloParserMode = MT_PROXY_SERVER_HELLO_PARSER_STANDARD;
std::string clientHelloSni;
int32_t connectionPatternMode = MT_PROXY_CONNECTION_PATTERN_OFF;
int32_t recordSizingMode = MT_PROXY_RECORD_SIZING_OFF;
int32_t timingMode = MT_PROXY_TIMING_OFF;
int32_t startupCoverMode = MT_PROXY_STARTUP_COVER_OFF;
};
struct RotateResult {
bool rotated = false;
int32_t previousProfile = MT_PROXY_TLS_PROFILE_FIREFOX_ANDROID;
int32_t nextProfile = MT_PROXY_TLS_PROFILE_FIREFOX_ANDROID;
uint32_t failures = 0;
};
static uint32_t sniVariantMask(int32_t variant);
static const char *clientHelloFamilyName(int32_t family);
static const char *sniVariantName(int32_t variant);
static const char *parserVariantName(int32_t parserVariant);
static const char *classicVariantName(int32_t classicVariant);
static RecipeCursor initialCursor(uint32_t allowedSniVariants);
static bool nextCursor(RecipeCursor *cursor, const std::string &diagnostic, uint32_t allowedSniVariants, bool classicFallbackAllowed);
static bool nextCursorForRecovery(RecipeCursor *cursor, MtProxyRecoveryAction action, uint32_t allowedSniVariants, bool classicFallbackAllowed);
static CompatibilityRecipe recipeForCursor(const RecipeInput &input, const RecipeCursor &cursor);
static RecipeResult applyRecipe(const RecipeInput &input);
static MtProxyRecipe recipeForResult(const RecipeInput &input, const RecipeResult &result);
static MtProxyRecipe recipeForCompatibilityRecipe(const CompatibilityRecipe &recipe);
static std::string recipeId(const CompatibilityRecipe &recipe);
static std::string recipeId(const MtProxyRecipe &recipe);
static bool profileUsesGrease(int32_t profile);
static int32_t resolveEffectiveTlsProfile(int32_t profile, const std::string &key);
static RotateResult rotateTlsProfileOnFailureIfNeeded(const std::string &key, const std::string &diagnostic, int32_t previousProfile);
static bool failureNeedsRecipe(const std::string &diagnostic);
static int32_t compatibilityTlsProfile(int32_t configuredProfile, int32_t effectiveProfile, int32_t recipeLevel);
static int32_t adaptiveTlsProfile(int32_t configuredProfile, int32_t effectiveProfile);
};
#endif