mirror of https://github.com/telemt/telemt.git
Compare commits
No commits in common. "07d774a82a28acc2389e04b0b5bf73eefe9f8ac3" and "567453e0f8955e4168b7b54dd7a7515c75fb1e31" have entirely different histories.
07d774a82a
...
567453e0f8
|
|
@ -91,7 +91,6 @@ This document lists all configuration keys accepted by `config.toml`.
|
||||||
| upstream_connect_retry_attempts | `u32` | `2` | Must be `> 0`. | Connect attempts for selected upstream before error/fallback. |
|
| upstream_connect_retry_attempts | `u32` | `2` | Must be `> 0`. | Connect attempts for selected upstream before error/fallback. |
|
||||||
| upstream_connect_retry_backoff_ms | `u64` | `100` | — | Delay between upstream connect attempts (ms). |
|
| upstream_connect_retry_backoff_ms | `u64` | `100` | — | Delay between upstream connect attempts (ms). |
|
||||||
| upstream_connect_budget_ms | `u64` | `3000` | Must be `> 0`. | Total wall-clock budget for one upstream connect request (ms). |
|
| upstream_connect_budget_ms | `u64` | `3000` | Must be `> 0`. | Total wall-clock budget for one upstream connect request (ms). |
|
||||||
| tg_connect | `u64` | `10` | Must be `> 0`. | Per-attempt upstream TCP connect timeout to Telegram DC (seconds). |
|
|
||||||
| upstream_unhealthy_fail_threshold | `u32` | `5` | Must be `> 0`. | Consecutive failed requests before upstream is marked unhealthy. |
|
| upstream_unhealthy_fail_threshold | `u32` | `5` | Must be `> 0`. | Consecutive failed requests before upstream is marked unhealthy. |
|
||||||
| upstream_connect_failfast_hard_errors | `bool` | `false` | — | Skips additional retries for hard non-transient connect errors. |
|
| upstream_connect_failfast_hard_errors | `bool` | `false` | — | Skips additional retries for hard non-transient connect errors. |
|
||||||
| stun_iface_mismatch_ignore | `bool` | `false` | none | Reserved compatibility flag in current runtime revision. |
|
| stun_iface_mismatch_ignore | `bool` | `false` | none | Reserved compatibility flag in current runtime revision. |
|
||||||
|
|
@ -250,6 +249,7 @@ Note: When `server.proxy_protocol` is enabled, incoming PROXY protocol headers a
|
||||||
| relay_client_idle_soft_secs | `u64` | `120` | Must be `> 0`; must be `<= relay_client_idle_hard_secs`. | Soft idle threshold for middle-relay client uplink inactivity (seconds). |
|
| relay_client_idle_soft_secs | `u64` | `120` | Must be `> 0`; must be `<= relay_client_idle_hard_secs`. | Soft idle threshold for middle-relay client uplink inactivity (seconds). |
|
||||||
| relay_client_idle_hard_secs | `u64` | `360` | Must be `> 0`; must be `>= relay_client_idle_soft_secs`. | Hard idle threshold for middle-relay client uplink inactivity (seconds). |
|
| relay_client_idle_hard_secs | `u64` | `360` | Must be `> 0`; must be `>= relay_client_idle_soft_secs`. | Hard idle threshold for middle-relay client uplink inactivity (seconds). |
|
||||||
| relay_idle_grace_after_downstream_activity_secs | `u64` | `30` | Must be `<= relay_client_idle_hard_secs`. | Extra hard-idle grace after recent downstream activity (seconds). |
|
| relay_idle_grace_after_downstream_activity_secs | `u64` | `30` | Must be `<= relay_client_idle_hard_secs`. | Extra hard-idle grace after recent downstream activity (seconds). |
|
||||||
|
| tg_connect | `u64` | `10` | — | Upstream Telegram connect timeout. |
|
||||||
| client_keepalive | `u64` | `15` | — | Client keepalive timeout. |
|
| client_keepalive | `u64` | `15` | — | Client keepalive timeout. |
|
||||||
| client_ack | `u64` | `90` | — | Client ACK timeout. |
|
| client_ack | `u64` | `90` | — | Client ACK timeout. |
|
||||||
| me_one_retry | `u8` | `12` | none | Fast reconnect attempts budget for single-endpoint DC scenarios. |
|
| me_one_retry | `u8` | `12` | none | Fast reconnect attempts budget for single-endpoint DC scenarios. |
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,7 @@ pub(super) fn build_limits_effective_data(cfg: &ProxyConfig) -> EffectiveLimitsD
|
||||||
me_pool_force_close_secs: cfg.general.effective_me_pool_force_close_secs(),
|
me_pool_force_close_secs: cfg.general.effective_me_pool_force_close_secs(),
|
||||||
timeouts: EffectiveTimeoutLimits {
|
timeouts: EffectiveTimeoutLimits {
|
||||||
client_handshake_secs: cfg.timeouts.client_handshake,
|
client_handshake_secs: cfg.timeouts.client_handshake,
|
||||||
tg_connect_secs: cfg.general.tg_connect,
|
tg_connect_secs: cfg.timeouts.tg_connect,
|
||||||
client_keepalive_secs: cfg.timeouts.client_keepalive,
|
client_keepalive_secs: cfg.timeouts.client_keepalive,
|
||||||
client_ack_secs: cfg.timeouts.client_ack,
|
client_ack_secs: cfg.timeouts.client_ack,
|
||||||
me_one_retry: cfg.timeouts.me_one_retry,
|
me_one_retry: cfg.timeouts.me_one_retry,
|
||||||
|
|
|
||||||
|
|
@ -584,7 +584,6 @@ me_pool_drain_soft_evict_cooldown_ms = 1000
|
||||||
me_bind_stale_mode = "never"
|
me_bind_stale_mode = "never"
|
||||||
me_pool_min_fresh_ratio = 0.8
|
me_pool_min_fresh_ratio = 0.8
|
||||||
me_reinit_drain_timeout_secs = 90
|
me_reinit_drain_timeout_secs = 90
|
||||||
tg_connect = 10
|
|
||||||
|
|
||||||
[network]
|
[network]
|
||||||
ipv4 = true
|
ipv4 = true
|
||||||
|
|
@ -611,6 +610,7 @@ ip = "::"
|
||||||
|
|
||||||
[timeouts]
|
[timeouts]
|
||||||
client_handshake = 15
|
client_handshake = 15
|
||||||
|
tg_connect = 10
|
||||||
client_keepalive = 60
|
client_keepalive = 60
|
||||||
client_ack = 300
|
client_ack = 300
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -696,7 +696,6 @@ fn warn_non_hot_changes(old: &ProxyConfig, new: &ProxyConfig, non_hot_changed: b
|
||||||
if old.general.upstream_connect_retry_attempts != new.general.upstream_connect_retry_attempts
|
if old.general.upstream_connect_retry_attempts != new.general.upstream_connect_retry_attempts
|
||||||
|| old.general.upstream_connect_retry_backoff_ms
|
|| old.general.upstream_connect_retry_backoff_ms
|
||||||
!= new.general.upstream_connect_retry_backoff_ms
|
!= new.general.upstream_connect_retry_backoff_ms
|
||||||
|| old.general.tg_connect != new.general.tg_connect
|
|
||||||
|| old.general.upstream_unhealthy_fail_threshold
|
|| old.general.upstream_unhealthy_fail_threshold
|
||||||
!= new.general.upstream_unhealthy_fail_threshold
|
!= new.general.upstream_unhealthy_fail_threshold
|
||||||
|| old.general.upstream_connect_failfast_hard_errors
|
|| old.general.upstream_connect_failfast_hard_errors
|
||||||
|
|
|
||||||
|
|
@ -346,12 +346,6 @@ impl ProxyConfig {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.general.tg_connect == 0 {
|
|
||||||
return Err(ProxyError::Config(
|
|
||||||
"general.tg_connect must be > 0".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.general.upstream_unhealthy_fail_threshold == 0 {
|
if config.general.upstream_unhealthy_fail_threshold == 0 {
|
||||||
return Err(ProxyError::Config(
|
return Err(ProxyError::Config(
|
||||||
"general.upstream_unhealthy_fail_threshold must be > 0".to_string(),
|
"general.upstream_unhealthy_fail_threshold must be > 0".to_string(),
|
||||||
|
|
@ -1913,26 +1907,6 @@ mod tests {
|
||||||
let _ = std::fs::remove_file(path);
|
let _ = std::fs::remove_file(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn tg_connect_zero_is_rejected() {
|
|
||||||
let toml = r#"
|
|
||||||
[general]
|
|
||||||
tg_connect = 0
|
|
||||||
|
|
||||||
[censorship]
|
|
||||||
tls_domain = "example.com"
|
|
||||||
|
|
||||||
[access.users]
|
|
||||||
user = "00000000000000000000000000000000"
|
|
||||||
"#;
|
|
||||||
let dir = std::env::temp_dir();
|
|
||||||
let path = dir.join("telemt_tg_connect_zero_test.toml");
|
|
||||||
std::fs::write(&path, toml).unwrap();
|
|
||||||
let err = ProxyConfig::load(&path).unwrap_err().to_string();
|
|
||||||
assert!(err.contains("general.tg_connect must be > 0"));
|
|
||||||
let _ = std::fs::remove_file(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_proxy_req_every_out_of_range_is_rejected() {
|
fn rpc_proxy_req_every_out_of_range_is_rejected() {
|
||||||
let toml = r#"
|
let toml = r#"
|
||||||
|
|
|
||||||
|
|
@ -663,10 +663,6 @@ pub struct GeneralConfig {
|
||||||
#[serde(default = "default_upstream_connect_budget_ms")]
|
#[serde(default = "default_upstream_connect_budget_ms")]
|
||||||
pub upstream_connect_budget_ms: u64,
|
pub upstream_connect_budget_ms: u64,
|
||||||
|
|
||||||
/// Per-attempt TCP connect timeout to Telegram DC (seconds).
|
|
||||||
#[serde(default = "default_connect_timeout")]
|
|
||||||
pub tg_connect: u64,
|
|
||||||
|
|
||||||
/// Consecutive failed requests before upstream is marked unhealthy.
|
/// Consecutive failed requests before upstream is marked unhealthy.
|
||||||
#[serde(default = "default_upstream_unhealthy_fail_threshold")]
|
#[serde(default = "default_upstream_unhealthy_fail_threshold")]
|
||||||
pub upstream_unhealthy_fail_threshold: u32,
|
pub upstream_unhealthy_fail_threshold: u32,
|
||||||
|
|
@ -1011,7 +1007,6 @@ impl Default for GeneralConfig {
|
||||||
upstream_connect_retry_attempts: default_upstream_connect_retry_attempts(),
|
upstream_connect_retry_attempts: default_upstream_connect_retry_attempts(),
|
||||||
upstream_connect_retry_backoff_ms: default_upstream_connect_retry_backoff_ms(),
|
upstream_connect_retry_backoff_ms: default_upstream_connect_retry_backoff_ms(),
|
||||||
upstream_connect_budget_ms: default_upstream_connect_budget_ms(),
|
upstream_connect_budget_ms: default_upstream_connect_budget_ms(),
|
||||||
tg_connect: default_connect_timeout(),
|
|
||||||
upstream_unhealthy_fail_threshold: default_upstream_unhealthy_fail_threshold(),
|
upstream_unhealthy_fail_threshold: default_upstream_unhealthy_fail_threshold(),
|
||||||
upstream_connect_failfast_hard_errors: default_upstream_connect_failfast_hard_errors(),
|
upstream_connect_failfast_hard_errors: default_upstream_connect_failfast_hard_errors(),
|
||||||
stun_iface_mismatch_ignore: false,
|
stun_iface_mismatch_ignore: false,
|
||||||
|
|
@ -1340,6 +1335,9 @@ pub struct TimeoutsConfig {
|
||||||
#[serde(default = "default_relay_idle_grace_after_downstream_activity_secs")]
|
#[serde(default = "default_relay_idle_grace_after_downstream_activity_secs")]
|
||||||
pub relay_idle_grace_after_downstream_activity_secs: u64,
|
pub relay_idle_grace_after_downstream_activity_secs: u64,
|
||||||
|
|
||||||
|
#[serde(default = "default_connect_timeout")]
|
||||||
|
pub tg_connect: u64,
|
||||||
|
|
||||||
#[serde(default = "default_keepalive")]
|
#[serde(default = "default_keepalive")]
|
||||||
pub client_keepalive: u64,
|
pub client_keepalive: u64,
|
||||||
|
|
||||||
|
|
@ -1364,6 +1362,7 @@ impl Default for TimeoutsConfig {
|
||||||
relay_client_idle_hard_secs: default_relay_client_idle_hard_secs(),
|
relay_client_idle_hard_secs: default_relay_client_idle_hard_secs(),
|
||||||
relay_idle_grace_after_downstream_activity_secs:
|
relay_idle_grace_after_downstream_activity_secs:
|
||||||
default_relay_idle_grace_after_downstream_activity_secs(),
|
default_relay_idle_grace_after_downstream_activity_secs(),
|
||||||
|
tg_connect: default_connect_timeout(),
|
||||||
client_keepalive: default_keepalive(),
|
client_keepalive: default_keepalive(),
|
||||||
client_ack: default_ack_timeout(),
|
client_ack: default_ack_timeout(),
|
||||||
me_one_retry: default_me_one_retry(),
|
me_one_retry: default_me_one_retry(),
|
||||||
|
|
|
||||||
|
|
@ -302,7 +302,6 @@ async fn run_inner(
|
||||||
config.general.upstream_connect_retry_attempts,
|
config.general.upstream_connect_retry_attempts,
|
||||||
config.general.upstream_connect_retry_backoff_ms,
|
config.general.upstream_connect_retry_backoff_ms,
|
||||||
config.general.upstream_connect_budget_ms,
|
config.general.upstream_connect_budget_ms,
|
||||||
config.general.tg_connect,
|
|
||||||
config.general.upstream_unhealthy_fail_threshold,
|
config.general.upstream_unhealthy_fail_threshold,
|
||||||
config.general.upstream_connect_failfast_hard_errors,
|
config.general.upstream_connect_failfast_hard_errors,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,6 @@ async fn adversarial_tls_handshake_timeout_during_masking_delay() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -142,7 +141,6 @@ async fn blackhat_proxy_protocol_slowloris_timeout() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -195,7 +193,6 @@ async fn negative_proxy_protocol_enabled_but_client_sends_tls_hello() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -242,7 +239,6 @@ async fn edge_client_stream_exactly_4_bytes_eof() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -286,7 +282,6 @@ async fn edge_client_stream_tls_header_valid_but_body_1_byte_short_eof() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -333,7 +328,6 @@ async fn integration_non_tls_modes_disabled_immediately_masks() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ async fn invariant_tls_clienthello_truncation_exact_boundary_triggers_masking()
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -178,7 +177,6 @@ async fn invariant_direct_mode_partial_header_eof_is_error_not_bad_connect() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ fn build_harness(config: ProxyConfig) -> PipelineHarness {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ fn build_harness(secret_hex: &str, mask_port: u16) -> PipelineHarness {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ fn make_test_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ fn build_harness(secret_hex: &str, mask_port: u16) -> RedTeamHarness {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -238,7 +237,6 @@ async fn redteam_03_masking_duration_must_be_less_than_1ms_when_backend_down() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
Arc::new(Stats::new()),
|
Arc::new(Stats::new()),
|
||||||
|
|
@ -479,7 +477,6 @@ async fn measure_invalid_probe_duration_ms(delay_ms: u64, tls_len: u16, body_sen
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
Arc::new(Stats::new()),
|
Arc::new(Stats::new()),
|
||||||
|
|
@ -553,7 +550,6 @@ async fn capture_forwarded_probe_len(tls_len: u16, body_sent: usize) -> usize {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
Arc::new(Stats::new()),
|
Arc::new(Stats::new()),
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ fn new_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,6 @@ async fn blackhat_proxy_protocol_massive_garbage_rejected_quickly() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -147,7 +146,6 @@ async fn edge_tls_body_immediate_eof_triggers_masking_and_bad_connect() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -197,7 +195,6 @@ async fn security_classic_mode_disabled_masks_valid_length_payload() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,6 @@ async fn relay_task_abort_releases_user_gate_and_ip_reservation() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -453,7 +452,6 @@ async fn relay_cutover_releases_user_gate_and_ip_reservation() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -577,7 +575,6 @@ async fn integration_route_cutover_and_quota_overlap_fails_closed_and_releases_s
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -747,7 +744,6 @@ async fn proxy_protocol_header_is_rejected_when_trust_list_is_empty() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -824,7 +820,6 @@ async fn proxy_protocol_header_from_untrusted_peer_range_is_rejected_under_load(
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -984,7 +979,6 @@ async fn short_tls_probe_is_masked_through_client_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1072,7 +1066,6 @@ async fn tls12_record_probe_is_masked_through_client_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1158,7 +1151,6 @@ async fn handle_client_stream_increments_connects_all_exactly_once() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1251,7 +1243,6 @@ async fn running_client_handler_increments_connects_all_exactly_once() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1341,7 +1332,6 @@ async fn partial_tls_header_stall_triggers_handshake_timeout() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1524,7 +1514,6 @@ async fn valid_tls_path_does_not_fall_back_to_mask_backend() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1633,7 +1622,6 @@ async fn valid_tls_with_invalid_mtproto_falls_back_to_mask_backend() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1740,7 +1728,6 @@ async fn client_handler_tls_bad_mtproto_is_forwarded_to_mask_backend() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1862,7 +1849,6 @@ async fn alpn_mismatch_tls_probe_is_masked_through_client_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1955,7 +1941,6 @@ async fn invalid_hmac_tls_probe_is_masked_through_client_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -2054,7 +2039,6 @@ async fn burst_invalid_tls_probes_are_masked_verbatim() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -2892,7 +2876,6 @@ async fn relay_connect_error_releases_user_and_ip_before_return() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -3453,7 +3436,6 @@ async fn untrusted_proxy_header_source_is_rejected() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -3523,7 +3505,6 @@ async fn empty_proxy_trusted_cidrs_rejects_proxy_header_by_default() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -3620,7 +3601,6 @@ async fn oversized_tls_record_is_masked_in_generic_stream_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -3723,7 +3703,6 @@ async fn oversized_tls_record_is_masked_in_client_handler_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -3840,7 +3819,6 @@ async fn tls_record_len_min_minus_1_is_rejected_in_generic_stream_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -3943,7 +3921,6 @@ async fn tls_record_len_min_minus_1_is_rejected_in_client_handler_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -4049,7 +4026,6 @@ async fn tls_record_len_16384_is_accepted_in_generic_stream_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -4150,7 +4126,6 @@ async fn tls_record_len_16384_is_accepted_in_client_handler_pipeline() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ fn make_test_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ fn make_test_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ fn make_test_upstream_manager(stats: Arc<Stats>) -> Arc<UpstreamManager> {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats,
|
stats,
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ fn build_harness(secret_hex: &str, mask_port: u16) -> PipelineHarness {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -1302,7 +1302,6 @@ async fn direct_relay_abort_midflight_releases_route_gauge() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1409,7 +1408,6 @@ async fn direct_relay_cutover_midflight_releases_route_gauge() {
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1531,7 +1529,6 @@ async fn direct_relay_cutover_storm_multi_session_keeps_generic_errors_and_relea
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1764,7 +1761,6 @@ async fn negative_direct_relay_dc_connection_refused_fails_fast() {
|
||||||
1,
|
1,
|
||||||
100,
|
100,
|
||||||
5000,
|
5000,
|
||||||
10,
|
|
||||||
3,
|
3,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
@ -1855,7 +1851,6 @@ async fn adversarial_direct_relay_cutover_integrity() {
|
||||||
1,
|
1,
|
||||||
100,
|
100,
|
||||||
5000,
|
5000,
|
||||||
10,
|
|
||||||
3,
|
3,
|
||||||
false,
|
false,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ const NUM_DCS: usize = 5;
|
||||||
|
|
||||||
/// Timeout for individual DC ping attempt
|
/// Timeout for individual DC ping attempt
|
||||||
const DC_PING_TIMEOUT_SECS: u64 = 5;
|
const DC_PING_TIMEOUT_SECS: u64 = 5;
|
||||||
|
/// Timeout for direct TG DC TCP connect readiness.
|
||||||
|
const DIRECT_CONNECT_TIMEOUT_SECS: u64 = 10;
|
||||||
/// Interval between upstream health-check cycles.
|
/// Interval between upstream health-check cycles.
|
||||||
const HEALTH_CHECK_INTERVAL_SECS: u64 = 30;
|
const HEALTH_CHECK_INTERVAL_SECS: u64 = 30;
|
||||||
/// Timeout for a single health-check connect attempt.
|
/// Timeout for a single health-check connect attempt.
|
||||||
|
|
@ -317,8 +319,6 @@ pub struct UpstreamManager {
|
||||||
connect_retry_attempts: u32,
|
connect_retry_attempts: u32,
|
||||||
connect_retry_backoff: Duration,
|
connect_retry_backoff: Duration,
|
||||||
connect_budget: Duration,
|
connect_budget: Duration,
|
||||||
/// Per-attempt TCP connect timeout to Telegram DC (`[general] tg_connect`, seconds).
|
|
||||||
tg_connect_timeout_secs: u64,
|
|
||||||
unhealthy_fail_threshold: u32,
|
unhealthy_fail_threshold: u32,
|
||||||
connect_failfast_hard_errors: bool,
|
connect_failfast_hard_errors: bool,
|
||||||
no_upstreams_warn_epoch_ms: Arc<AtomicU64>,
|
no_upstreams_warn_epoch_ms: Arc<AtomicU64>,
|
||||||
|
|
@ -332,7 +332,6 @@ impl UpstreamManager {
|
||||||
connect_retry_attempts: u32,
|
connect_retry_attempts: u32,
|
||||||
connect_retry_backoff_ms: u64,
|
connect_retry_backoff_ms: u64,
|
||||||
connect_budget_ms: u64,
|
connect_budget_ms: u64,
|
||||||
tg_connect_timeout_secs: u64,
|
|
||||||
unhealthy_fail_threshold: u32,
|
unhealthy_fail_threshold: u32,
|
||||||
connect_failfast_hard_errors: bool,
|
connect_failfast_hard_errors: bool,
|
||||||
stats: Arc<Stats>,
|
stats: Arc<Stats>,
|
||||||
|
|
@ -348,7 +347,6 @@ impl UpstreamManager {
|
||||||
connect_retry_attempts: connect_retry_attempts.max(1),
|
connect_retry_attempts: connect_retry_attempts.max(1),
|
||||||
connect_retry_backoff: Duration::from_millis(connect_retry_backoff_ms),
|
connect_retry_backoff: Duration::from_millis(connect_retry_backoff_ms),
|
||||||
connect_budget: Duration::from_millis(connect_budget_ms.max(1)),
|
connect_budget: Duration::from_millis(connect_budget_ms.max(1)),
|
||||||
tg_connect_timeout_secs: tg_connect_timeout_secs.max(1),
|
|
||||||
unhealthy_fail_threshold: unhealthy_fail_threshold.max(1),
|
unhealthy_fail_threshold: unhealthy_fail_threshold.max(1),
|
||||||
connect_failfast_hard_errors,
|
connect_failfast_hard_errors,
|
||||||
no_upstreams_warn_epoch_ms: Arc::new(AtomicU64::new(0)),
|
no_upstreams_warn_epoch_ms: Arc::new(AtomicU64::new(0)),
|
||||||
|
|
@ -800,7 +798,7 @@ impl UpstreamManager {
|
||||||
}
|
}
|
||||||
let remaining_budget = self.connect_budget.saturating_sub(elapsed);
|
let remaining_budget = self.connect_budget.saturating_sub(elapsed);
|
||||||
let attempt_timeout =
|
let attempt_timeout =
|
||||||
Duration::from_secs(self.tg_connect_timeout_secs).min(remaining_budget);
|
Duration::from_secs(DIRECT_CONNECT_TIMEOUT_SECS).min(remaining_budget);
|
||||||
if attempt_timeout.is_zero() {
|
if attempt_timeout.is_zero() {
|
||||||
last_error = Some(ProxyError::ConnectionTimeout {
|
last_error = Some(ProxyError::ConnectionTimeout {
|
||||||
addr: target.to_string(),
|
addr: target.to_string(),
|
||||||
|
|
@ -1903,7 +1901,6 @@ mod tests {
|
||||||
1,
|
1,
|
||||||
100,
|
100,
|
||||||
1000,
|
1000,
|
||||||
10,
|
|
||||||
1,
|
1,
|
||||||
false,
|
false,
|
||||||
Arc::new(Stats::new()),
|
Arc::new(Stats::new()),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue