Blackmagics...
This commit is contained in:
26
src/main.rs
26
src/main.rs
@@ -140,7 +140,7 @@ fn print_proxy_links(host: &str, port: u16, config: &ProxyConfig) {
|
||||
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||
let (config_path, cli_silent, cli_log_level) = parse_cli();
|
||||
|
||||
let config = match ProxyConfig::load(&config_path) {
|
||||
let mut config = match ProxyConfig::load(&config_path) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
if std::path::Path::new(&config_path).exists() {
|
||||
@@ -229,18 +229,9 @@ async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let prefer_ipv6 = decision.prefer_ipv6();
|
||||
let mut use_middle_proxy = config.general.use_middle_proxy && (decision.ipv4_me || decision.ipv6_me);
|
||||
let config = Arc::new(config);
|
||||
let stats = Arc::new(Stats::new());
|
||||
let rng = Arc::new(SecureRandom::new());
|
||||
|
||||
let replay_checker = Arc::new(ReplayChecker::new(
|
||||
config.access.replay_check_len,
|
||||
Duration::from_secs(config.access.replay_window_secs),
|
||||
));
|
||||
|
||||
let upstream_manager = Arc::new(UpstreamManager::new(config.upstreams.clone()));
|
||||
let buffer_pool = Arc::new(BufferPool::with_config(16 * 1024, 4096));
|
||||
|
||||
// IP Tracker initialization
|
||||
let ip_tracker = Arc::new(UserIpTracker::new());
|
||||
ip_tracker.load_limits(&config.access.user_max_unique_ips).await;
|
||||
@@ -389,12 +380,27 @@ match crate::transport::middle_proxy::fetch_proxy_secret(proxy_secret_path).awai
|
||||
None
|
||||
};
|
||||
|
||||
// If ME failed to initialize, force direct-only mode.
|
||||
if me_pool.is_some() {
|
||||
info!("Transport: Middle-End Proxy - all DC-over-RPC");
|
||||
} else {
|
||||
use_middle_proxy = false;
|
||||
// Make runtime config reflect direct-only mode for handlers.
|
||||
config.general.use_middle_proxy = false;
|
||||
info!("Transport: Direct DC - TCP - standard DC-over-TCP");
|
||||
}
|
||||
|
||||
// Freeze config after possible fallback decision
|
||||
let config = Arc::new(config);
|
||||
|
||||
let replay_checker = Arc::new(ReplayChecker::new(
|
||||
config.access.replay_check_len,
|
||||
Duration::from_secs(config.access.replay_window_secs),
|
||||
));
|
||||
|
||||
let upstream_manager = Arc::new(UpstreamManager::new(config.upstreams.clone()));
|
||||
let buffer_pool = Arc::new(BufferPool::with_config(16 * 1024, 4096));
|
||||
|
||||
// Middle-End ping before DC connectivity
|
||||
if let Some(ref pool) = me_pool {
|
||||
let me_results = run_me_ping(pool, &rng).await;
|
||||
|
||||
@@ -48,6 +48,8 @@ pub struct MePool {
|
||||
pub(super) nat_probe: bool,
|
||||
pub(super) nat_stun: Option<String>,
|
||||
pub(super) detected_ipv6: Option<Ipv6Addr>,
|
||||
pub(super) nat_probe_attempts: std::sync::atomic::AtomicU8,
|
||||
pub(super) nat_probe_disabled: std::sync::atomic::AtomicBool,
|
||||
pub(super) proxy_map_v4: Arc<RwLock<HashMap<i32, Vec<(IpAddr, u16)>>>>,
|
||||
pub(super) proxy_map_v6: Arc<RwLock<HashMap<i32, Vec<(IpAddr, u16)>>>>,
|
||||
pub(super) default_dc: AtomicI32,
|
||||
@@ -91,6 +93,8 @@ impl MePool {
|
||||
nat_probe,
|
||||
nat_stun,
|
||||
detected_ipv6,
|
||||
nat_probe_attempts: std::sync::atomic::AtomicU8::new(0),
|
||||
nat_probe_disabled: std::sync::atomic::AtomicBool::new(false),
|
||||
pool_size: 2,
|
||||
proxy_map_v4: Arc::new(RwLock::new(proxy_map_v4)),
|
||||
proxy_map_v6: Arc::new(RwLock::new(proxy_map_v6)),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
use std::time::Duration;
|
||||
|
||||
use tracing::{info, warn};
|
||||
use tracing::{info, warn, debug};
|
||||
|
||||
use crate::error::{ProxyError, Result};
|
||||
use crate::network::probe::is_bogon;
|
||||
@@ -98,6 +98,18 @@ impl MePool {
|
||||
family: IpFamily,
|
||||
) -> Option<std::net::SocketAddr> {
|
||||
const STUN_CACHE_TTL: Duration = Duration::from_secs(600);
|
||||
// If STUN probing was disabled after attempts, reuse cached (even stale) or skip.
|
||||
if self.nat_probe_disabled.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
if let Ok(cache) = self.nat_reflection_cache.try_lock() {
|
||||
let slot = match family {
|
||||
IpFamily::V4 => cache.v4,
|
||||
IpFamily::V6 => cache.v6,
|
||||
};
|
||||
return slot.map(|(_, addr)| addr);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Ok(mut cache) = self.nat_reflection_cache.try_lock() {
|
||||
let slot = match family {
|
||||
IpFamily::V4 => &mut cache.v4,
|
||||
@@ -110,6 +122,12 @@ impl MePool {
|
||||
}
|
||||
}
|
||||
|
||||
let attempt = self.nat_probe_attempts.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
if attempt >= 2 {
|
||||
self.nat_probe_disabled.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
return None;
|
||||
}
|
||||
|
||||
let stun_addr = self
|
||||
.nat_stun
|
||||
.clone()
|
||||
@@ -135,7 +153,15 @@ impl MePool {
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(error = %e, "NAT probe failed");
|
||||
let attempts = attempt + 1;
|
||||
if attempts <= 2 {
|
||||
warn!(error = %e, attempt = attempts, "NAT probe failed");
|
||||
} else {
|
||||
debug!(error = %e, attempt = attempts, "NAT probe suppressed after max attempts");
|
||||
}
|
||||
if attempts >= 2 {
|
||||
self.nat_probe_disabled.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user