//! Time Sync use std::time::Duration; use chrono::{DateTime, Utc}; use tracing::{debug, warn, error}; const TIME_SYNC_URL: &str = "https://core.telegram.org/getProxySecret"; const MAX_TIME_SKEW_SECS: i64 = 30; /// Time sync result #[derive(Debug, Clone)] pub struct TimeSyncResult { pub server_time: DateTime, pub local_time: DateTime, pub skew_secs: i64, pub is_skewed: bool, } /// Check time synchronization with Telegram servers pub async fn check_time_sync() -> Option { let client = reqwest::Client::builder() .timeout(Duration::from_secs(10)) .build() .ok()?; let response = client.get(TIME_SYNC_URL).send().await.ok()?; // Get Date header let date_header = response.headers().get("date")?; let date_str = date_header.to_str().ok()?; // Parse date let server_time = DateTime::parse_from_rfc2822(date_str) .ok()? .with_timezone(&Utc); let local_time = Utc::now(); let skew_secs = (local_time - server_time).num_seconds(); let is_skewed = skew_secs.abs() > MAX_TIME_SKEW_SECS; let result = TimeSyncResult { server_time, local_time, skew_secs, is_skewed, }; if is_skewed { warn!( server = %server_time, local = %local_time, skew = skew_secs, "Time skew detected" ); } else { debug!(skew = skew_secs, "Time sync OK"); } Some(result) } /// Background time sync task pub async fn time_sync_task(check_interval: Duration) -> ! { loop { if let Some(result) = check_time_sync().await { if result.is_skewed { error!( "System clock is off by {} seconds. Please sync your clock.", result.skew_secs ); } } tokio::time::sleep(check_interval).await; } }