FoxiGram/TMessagesProj/jni/tgnet/DrsEngine.h
instant992 8e79f2ee9c FoxiGram: Telegram client with built-in Xray VLESS proxy
Based on Nekogram. Key additions:
- Rebrand to FoxiGram (app name, APK name, applicationId com.foxigram.app)
- Embedded Xray (VLESS+Reality) proxy client via JNI libxray.so
- Bundled hidden one-tap proxies (LTE + WiFi), read-only in UI
- Auto-restore proxy on restart, rebind to active network (LTE/WiFi)
- Server credentials externalized to git-ignored XrayServers.java (+ template)
- libxray Go source included; compiled .so, keystore, google-services.json ignored
2026-06-08 16:41:07 +04:00

117 lines
3.8 KiB
C++

/*
* DrsEngine.h — Dynamic Record Sizing for tgnet
* Ported from telemt/tdlib-obf (MIT License, Copyright 2026 telemt community)
* Adapted for tgnet: C++17, no tdlib dependencies.
*
* DRS shapes TLS record payload sizes across three phases to match
* empirically-captured browser traffic patterns, defeating DPI classifiers
* that identify MTProto by its characteristic fixed-size records.
*
* Phase progression:
* SlowStart — small records (80-494 bytes), first N records after connect
* CongestionOpen — medium records (200-2941 bytes), until M bytes sent
* SteadyState — full browser-range records (200-8192 bytes)
*
* After idle (default 250-1200ms) resets to SlowStart.
*/
#ifndef DRS_ENGINE_H
#define DRS_ENGINE_H
#include <cstdint>
#include <vector>
namespace stealth {
struct RecordSizeBin {
int32_t lo;
int32_t hi;
uint32_t weight;
};
struct DrsPhaseModel {
std::vector<RecordSizeBin> bins;
int32_t local_jitter{0}; // ± jitter added to sampled value
int32_t max_repeat_run{3}; // penalise picking same size >N times in a row
};
struct DrsPolicy {
DrsPhaseModel slow_start;
DrsPhaseModel congestion_open;
DrsPhaseModel steady_state;
int32_t min_payload_cap{80};
int32_t max_payload_cap{16408};
int32_t slow_start_records{8}; // records before leaving SlowStart
int32_t congestion_bytes{32768}; // bytes before leaving CongestionOpen
int32_t idle_reset_ms_min{250};
int32_t idle_reset_ms_max{1200};
};
// Returns the default policy with capture-aligned bins from tdlib-obf baselines
DrsPolicy default_drs_policy();
// Traffic hint — tells DRS which sampling path to use
enum class TrafficHint : uint8_t {
Unknown = 0,
Interactive = 1, // normal messaging — uses phase model
BulkData = 2, // file upload/download — uses steady_state bins directly
Keepalive = 3, // ping — uses min_payload_cap
AuthHandshake = 4, // key exchange — uses min_payload_cap
};
class DrsEngine {
public:
enum class Phase : uint8_t { SlowStart = 0, CongestionOpen = 1, SteadyState = 2 };
explicit DrsEngine(const DrsPolicy &policy);
// Returns the max payload bytes for the next TLS record.
// Call before each send(); pass result as the record size cap.
int32_t next_payload_cap(TrafficHint hint = TrafficHint::Interactive);
// Call after a record is actually sent with `bytes` payload bytes.
void notify_bytes_written(size_t bytes);
// Call when the connection goes idle (no sends for idle_reset_ms).
void notify_idle();
Phase current_phase() const noexcept { return phase_; }
// Returns true if idle_ms exceeds the sampled idle reset threshold
bool should_reset_after_idle(int64_t idle_ms) const noexcept;
private:
DrsPolicy policy_;
Phase phase_{Phase::SlowStart};
size_t records_in_phase_{0};
size_t bytes_in_phase_{0};
int32_t sampled_idle_reset_ms_{0};
int32_t transition_anchor_cap_{-1};
int32_t previous_cap_{-1};
int32_t last_cap_{-1};
int32_t last_cap_run_{0};
int32_t monotonic_run_{0};
int8_t last_direction_{0};
// Bulk-isolated run state
int32_t bulk_previous_cap_{-1};
int32_t bulk_last_cap_{-1};
int32_t bulk_last_cap_run_{0};
int32_t bulk_monotonic_run_{0};
int8_t bulk_last_direction_{0};
const DrsPhaseModel &phase_model() const noexcept;
int32_t sample_from_phase(const DrsPhaseModel &model);
int32_t sample_weighted_bin_value(const DrsPhaseModel &model);
int32_t score_candidate(const DrsPhaseModel &model, int32_t candidate) const noexcept;
int32_t smooth_transition(int32_t candidate) noexcept;
void maybe_advance_phase();
void note_selected_cap(int32_t cap) noexcept;
void reset_run_state() noexcept;
static uint32_t rand_bounded(uint32_t n);
};
} // namespace stealth
#endif // DRS_ENGINE_H