diff --git a/src/main.rs b/src/main.rs index acc07b9..0691bb2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -357,7 +357,9 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai info!("================= Telegram DC Connectivity ================="); - let ping_results = upstream_manager.ping_all_dcs(prefer_ipv6).await; + let ping_results = upstream_manager + .ping_all_dcs(prefer_ipv6, &config.dc_overrides) + .await; for upstream_result in &ping_results { let v6_works = upstream_result diff --git a/src/transport/upstream.rs b/src/transport/upstream.rs index 4b5fe9c..db0d366 100644 --- a/src/transport/upstream.rs +++ b/src/transport/upstream.rs @@ -2,6 +2,7 @@ //! //! IPv6/IPv4 connectivity checks with configurable preference. +use std::collections::HashMap; use std::net::{SocketAddr, IpAddr}; use std::sync::Arc; use std::time::Duration; @@ -350,7 +351,11 @@ impl UpstreamManager { /// Ping all Telegram DCs through all upstreams. /// Tests BOTH IPv6 and IPv4, returns separate results for each. - pub async fn ping_all_dcs(&self, prefer_ipv6: bool) -> Vec { + pub async fn ping_all_dcs( + &self, + prefer_ipv6: bool, + dc_overrides: &HashMap>, + ) -> Vec { let upstreams: Vec<(usize, UpstreamConfig)> = { let guard = self.upstreams.read().await; guard.iter().enumerate() @@ -450,6 +455,58 @@ impl UpstreamManager { v4_results.push(ping_result); } + // === Ping DC overrides (v4/v6) === + for (dc_key, addrs) in dc_overrides { + let dc_num: i16 = match dc_key.parse::() { + Ok(v) if v > 0 => v, + Err(_) => { + warn!(dc = %dc_key, "Invalid dc_overrides key, skipping"); + continue; + }, + _ => continue, + }; + let dc_idx = dc_num as usize; + for addr_str in addrs { + match addr_str.parse::() { + Ok(addr) => { + let is_v6 = addr.is_ipv6(); + let result = tokio::time::timeout( + Duration::from_secs(DC_PING_TIMEOUT_SECS), + self.ping_single_dc(&upstream_config, addr) + ).await; + + let ping_result = match result { + Ok(Ok(rtt_ms)) => DcPingResult { + dc_idx, + dc_addr: addr, + rtt_ms: Some(rtt_ms), + error: None, + }, + Ok(Err(e)) => DcPingResult { + dc_idx, + dc_addr: addr, + rtt_ms: None, + error: Some(e.to_string()), + }, + Err(_) => DcPingResult { + dc_idx, + dc_addr: addr, + rtt_ms: None, + error: Some("timeout".to_string()), + }, + }; + + if is_v6 { + v6_results.push(ping_result); + } else { + v4_results.push(ping_result); + } + } + Err(_) => warn!(dc = %dc_idx, addr = %addr_str, "Invalid dc_overrides address, skipping"), + } + } + } + // Check if both IP versions have at least one working DC let v6_has_working = v6_results.iter().any(|r| r.rtt_ms.is_some()); let v4_has_working = v4_results.iter().any(|r| r.rtt_ms.is_some()); @@ -624,4 +681,4 @@ impl UpstreamManager { Some(SocketAddr::new(ip, TG_DATACENTER_PORT)) } -} \ No newline at end of file +} diff --git a/telemt b/telemt deleted file mode 100644 index fbb8d6f..0000000 Binary files a/telemt and /dev/null differ