diff --git a/easytier/src/easytier-core.rs b/easytier/src/easytier-core.rs index 721b476..ba7ec00 100644 --- a/easytier/src/easytier-core.rs +++ b/easytier/src/easytier-core.rs @@ -97,10 +97,6 @@ struct Cli { "wg://0.0.0.0:11011".to_string()])] listeners: Vec, - /// specify the linux network namespace, default is the root namespace - #[arg(long)] - net_ns: Option, - #[arg(long, help = "console log level", value_parser = clap::builder::PossibleValuesParser::new(["trace", "debug", "info", "warn", "error", "off"]))] console_log_level: Option, @@ -122,13 +118,6 @@ struct Cli { )] instance_name: String, - #[arg( - short = 'd', - long, - help = "instance uuid to identify this vpn node in whole vpn network example: 123e4567-e89b-12d3-a456-426614174000" - )] - instance_id: Option, - #[arg( long, help = "url that defines the vpn portal, allow other vpn clients to connect. @@ -163,6 +152,13 @@ and the vpn client is in network of 10.14.14.0/24" help = "mtu of the TUN device, default is 1420 for non-encryption, 1400 for encryption" )] mtu: Option, + + #[arg( + long, + help = "path to the log file, if not set, will print to stdout", + default_value = "false" + )] + latency_first: bool, } impl From for TomlConfigLoader { @@ -188,7 +184,6 @@ impl From for TomlConfigLoader { cli.network_secret.clone(), )); - cfg.set_netns(cli.net_ns.clone()); if let Some(ipv4) = &cli.ipv4 { cfg.set_ipv4( ipv4.parse() @@ -307,6 +302,7 @@ impl From for TomlConfigLoader { } f.enable_encryption = !cli.disable_encryption; f.enable_ipv6 = !cli.disable_ipv6; + f.latency_first = cli.latency_first; if let Some(mtu) = cli.mtu { f.mtu = mtu; } diff --git a/easytier/src/instance/instance.rs b/easytier/src/instance/instance.rs index 16cb932..7ad1e91 100644 --- a/easytier/src/instance/instance.rs +++ b/easytier/src/instance/instance.rs @@ -1,6 +1,7 @@ use std::borrow::BorrowMut; use std::net::Ipv4Addr; use std::pin::Pin; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Weak}; use anyhow::Context; @@ -44,6 +45,8 @@ struct IpProxy { tcp_proxy: Arc, icmp_proxy: Arc, udp_proxy: Arc, + global_ctx: ArcGlobalCtx, + started: Arc, } impl IpProxy { @@ -57,10 +60,17 @@ impl IpProxy { tcp_proxy, icmp_proxy, udp_proxy, + global_ctx, + started: Arc::new(AtomicBool::new(false)), }) } async fn start(&self) -> Result<(), Error> { + if self.global_ctx.get_proxy_cidrs().is_empty() || self.started.load(Ordering::Relaxed) { + return Ok(()); + } + + self.started.store(true, Ordering::Relaxed); self.tcp_proxy.start().await?; self.icmp_proxy.start().await?; self.udp_proxy.start().await?; @@ -297,7 +307,7 @@ impl Instance { self.get_global_ctx(), self.get_peer_manager(), )?); - self.ip_proxy.as_ref().unwrap().start().await?; + self.run_ip_proxy().await?; self.udp_hole_puncher.lock().await.run().await?; @@ -317,6 +327,14 @@ impl Instance { Ok(()) } + pub async fn run_ip_proxy(&mut self) -> Result<(), Error> { + if self.ip_proxy.is_none() { + return Err(anyhow::anyhow!("ip proxy not enabled.").into()); + } + self.ip_proxy.as_ref().unwrap().start().await?; + Ok(()) + } + pub async fn run_vpn_portal(&mut self) -> Result<(), Error> { if self.global_ctx.get_vpn_portal_cidr().is_none() { return Err(anyhow::anyhow!("vpn portal cidr not set.").into()); diff --git a/easytier/src/peer_center/instance.rs b/easytier/src/peer_center/instance.rs index 35831a0..85f8208 100644 --- a/easytier/src/peer_center/instance.rs +++ b/easytier/src/peer_center/instance.rs @@ -424,10 +424,10 @@ mod tests { route_cost.calculate_cost(peer_mgr_c.my_peer_id(), peer_mgr_b.my_peer_id()) < 30 ); assert!( - route_cost.calculate_cost(peer_mgr_c.my_peer_id(), peer_mgr_a.my_peer_id()) > 10000 + route_cost.calculate_cost(peer_mgr_c.my_peer_id(), peer_mgr_a.my_peer_id()) > 50 ); assert!( - route_cost.calculate_cost(peer_mgr_a.my_peer_id(), peer_mgr_c.my_peer_id()) > 10000 + route_cost.calculate_cost(peer_mgr_a.my_peer_id(), peer_mgr_c.my_peer_id()) > 50 ); route_cost.end_update(); assert!(!route_cost.need_update()); diff --git a/easytier/src/peer_center/service.rs b/easytier/src/peer_center/service.rs index d6b4d59..e6d4d04 100644 --- a/easytier/src/peer_center/service.rs +++ b/easytier/src/peer_center/service.rs @@ -11,12 +11,14 @@ impl From> for PeerInfoForGlobalMap { fn from(peers: Vec) -> Self { let mut peer_map = BTreeMap::new(); for peer in peers { - let min_lat = peer + let Some(min_lat) = peer .conns .iter() .map(|conn| conn.stats.as_ref().unwrap().latency_us) .min() - .unwrap_or(u32::MAX as u64); + else { + continue; + }; let dp_info = DirectConnectedPeerInfo { latency_ms: std::cmp::max(1, (min_lat as u32 / 1000) as i32), diff --git a/easytier/src/peers/peer_map.rs b/easytier/src/peers/peer_map.rs index e0bbfa7..286b9d1 100644 --- a/easytier/src/peers/peer_map.rs +++ b/easytier/src/peers/peer_map.rs @@ -103,7 +103,7 @@ impl PeerMap { return Some(dst_peer_id); } - if self.has_peer(dst_peer_id) { + if self.has_peer(dst_peer_id) && matches!(policy, NextHopPolicy::LeastHop) { return Some(dst_peer_id); } diff --git a/easytier/src/tests/three_node.rs b/easytier/src/tests/three_node.rs index 1ecdee3..279b166 100644 --- a/easytier/src/tests/three_node.rs +++ b/easytier/src/tests/three_node.rs @@ -187,12 +187,13 @@ pub async fn basic_three_node_test(#[values("tcp", "udp", "wg", "ws", "wss")] pr pub async fn tcp_proxy_three_node_test(#[values("tcp", "udp", "wg")] proto: &str) { use crate::tunnel::{common::tests::_tunnel_pingpong_netns, tcp::TcpTunnelListener}; - let insts = init_three_node(proto).await; + let mut insts = init_three_node(proto).await; insts[2] .get_global_ctx() .add_proxy_cidr("10.1.2.0/24".parse().unwrap()) .unwrap(); + insts[2].run_ip_proxy().await.unwrap(); assert_eq!(insts[2].get_global_ctx().get_proxy_cidrs().len(), 1); wait_proxy_route_appear( @@ -222,12 +223,13 @@ pub async fn tcp_proxy_three_node_test(#[values("tcp", "udp", "wg")] proto: &str #[tokio::test] #[serial_test::serial] pub async fn icmp_proxy_three_node_test(#[values("tcp", "udp", "wg")] proto: &str) { - let insts = init_three_node(proto).await; + let mut insts = init_three_node(proto).await; insts[2] .get_global_ctx() .add_proxy_cidr("10.1.2.0/24".parse().unwrap()) .unwrap(); + insts[2].run_ip_proxy().await.unwrap(); assert_eq!(insts[2].get_global_ctx().get_proxy_cidrs().len(), 1); wait_proxy_route_appear( @@ -318,12 +320,13 @@ pub async fn proxy_three_node_disconnect_test(#[values("tcp", "wg")] proto: &str pub async fn udp_proxy_three_node_test(#[values("tcp", "udp", "wg")] proto: &str) { use crate::tunnel::{common::tests::_tunnel_pingpong_netns, udp::UdpTunnelListener}; - let insts = init_three_node(proto).await; + let mut insts = init_three_node(proto).await; insts[2] .get_global_ctx() .add_proxy_cidr("10.1.2.0/24".parse().unwrap()) .unwrap(); + insts[2].run_ip_proxy().await.unwrap(); assert_eq!(insts[2].get_global_ctx().get_proxy_cidrs().len(), 1); wait_proxy_route_appear(