use crate::api::VntApi; use crate::compression::PacketCompression; use crate::context::config::Config; use crate::context::{AppState, NetworkAddr, NetworkRoute}; use crate::crypto::PacketCrypto; use crate::enhanced_tunnel::enhanced_ipv4_tunnel; use crate::enhanced_tunnel::inbound::EnhancedInbound; use crate::enhanced_tunnel::outbound::EnhancedOutbound; use crate::fec::{FecDecoder, FecEncoder}; use crate::nat::internal_nat::{InternalNatInbound, PortMappingManager}; use crate::nat::{AllowSubnetExternalRoute, SubnetExternalRoute}; use crate::protocol::control_message::ErrorResponseMsg; use crate::tun::enhanced_tun::EnhancedTunInbound; use crate::tun::{DeviceConfig, DeviceIOManager, TunDataInbound, TunReceiver, tun_channel}; use crate::tunnel_core::outbound::{BasicOutbound, HybridOutbound}; use crate::tunnel_core::p2p::inbound::{P2pInboundConfig, P2pInboundHandler}; use crate::tunnel_core::p2p::transport::punch::NatPuncher; use crate::tunnel_core::p2p::transport::task::init_tunnel; use crate::tunnel_core::server::connection_manager::{ InboundHandlerConfig, ServerTurnManager, coordinated_registration, create_server_tunnel, }; use crate::tunnel_core::server::rpc::ServerRPC; use crate::utils::task_control::TaskGroup; use anyhow::bail; use ipnet::Ipv4Net; #[cfg(not(target_os = "android"))] use std::net::Ipv4Addr; pub const DEFAULT_MTU: u16 = 1380; /// Context for deferred registration struct RegistrationContext { server_managers: Vec, subnet_external_route: SubnetExternalRoute, puncher: NatPuncher, packet_crypto: PacketCrypto, packet_compression: PacketCompression, enhanced_inbound: EnhancedInbound, fec_decoder: FecDecoder, } pub struct NetworkManager { config: Box, app_state: AppState, task_group: TaskGroup, device_io_manager: DeviceIOManager, enhanced_outbound: Option, server_rpc: ServerRPC, tun_receiver: Option, registration_context: Option>, } pub enum RegisterResponse { Success(NetworkAddr), Failed(ErrorResponseMsg), } impl NetworkManager { pub async fn create_network( config: Box, task_group: TaskGroup, ) -> anyhow::Result { let app_state = AppState::default(); config.check()?; let outbound_interface_name = config .outbound_interface .as_deref() .map(str::trim) .filter(|name| !name.is_empty()) .map(str::to_owned); let resolved_interface = crate::utils::socket::resolve_interface(outbound_interface_name.as_deref())?; let default_interface = resolved_interface .as_ref() .map(|interface| interface.socket_interface.clone()); let canonical_interface_name = resolved_interface .as_ref() .map(|interface| interface.name.clone()); if let Some(name) = canonical_interface_name.as_deref() { log::info!("绑定出口网卡: {name}"); } let mtu = config.mtu.unwrap_or(DEFAULT_MTU); let packet_crypto = PacketCrypto::new_from_str(config.password.as_deref()); let packet_compression = PacketCompression::new(config.compress); let (server_manager_list, tunnel_to_server, server_rpc) = create_server_tunnel( app_state.clone(), &config, packet_crypto.clone(), default_interface.clone(), ); let device_io_manager = DeviceIOManager::new(task_group.clone()); let allow_subnet = AllowSubnetExternalRoute::new(config.output.clone()); let (puncher, p2p_socket, p2p_task) = if !config.no_punch { let (puncher, p2p_socket_manager, p2p_task) = init_tunnel( task_group.clone(), app_state.clone(), tunnel_to_server.clone(), packet_crypto.clone(), config.tunnel_port, default_interface.clone(), canonical_interface_name, ) .await?; (Some(puncher), Some(p2p_socket_manager), Some(p2p_task)) } else { (None, None, None) }; let puncher = NatPuncher::new( app_state.network.clone(), app_state.punch_backoff.clone(), puncher, packet_crypto.clone(), ); let subnet_external_route = app_state.subnet_route.clone(); subnet_external_route.set_route_table(config.input.clone()); let fec_decoder = FecDecoder::new(); let basic_outbound = BasicOutbound::new( tunnel_to_server.clone(), p2p_socket.clone(), packet_crypto.clone(), ); let fec_encoder = if config.fec { Some(FecEncoder::new(&task_group, basic_outbound.clone())) } else { None }; let hybrid_outbound = HybridOutbound::new( app_state.network.clone(), app_state.server_info_collection.clone(), app_state.traffic_stats.clone(), basic_outbound, packet_compression.clone(), subnet_external_route.clone(), fec_encoder, ); let port_mapping_manager = PortMappingManager::new( config.no_tun, config.allow_port_mapping, app_state.network.clone(), default_interface.clone(), ); let internal_nat_inbound = if config.no_nat && !config.no_tun { None } else { let nat_inbound = InternalNatInbound::create( &task_group, mtu, hybrid_outbound.clone(), allow_subnet.clone(), app_state.network.clone(), config.no_tun, default_interface.clone(), ) .await?; Some(nat_inbound) }; let (enhanced_tun_inbound, tun_receiver) = if config.no_tun { ( EnhancedTunInbound::Nat( internal_nat_inbound .clone() .expect("internal_nat_inbound must be Some when no_tun is true"), ), None, ) } else { let (tun_inbound, tun_receiver) = tun_channel(); let tun_data_sender = TunDataInbound::new(tun_inbound, allow_subnet.clone()); (EnhancedTunInbound::Tun(tun_data_sender), Some(tun_receiver)) }; let (enhanced_inbound, enhanced_outbound) = enhanced_ipv4_tunnel( app_state.clone(), task_group.clone(), enhanced_tun_inbound, crate::enhanced_tunnel::TunnelConfig { mtu, password: config.password.clone(), open_quic_client: config.rtx, port_mapping: config.port_mapping.clone(), }, crate::enhanced_tunnel::TunnelComponents { hybrid_outbound: hybrid_outbound.clone(), external_route: subnet_external_route.clone(), internal_nat_inbound, port_mapping_manager, }, ) .await?; if let Some(p2p_task) = p2p_task { let handler = P2pInboundHandler::new(P2pInboundConfig { network_route: NetworkRoute::new( app_state.network.clone(), subnet_external_route.clone(), ), route_table: app_state.route_table.clone(), packet_loss_stats: app_state.packet_loss_stats.clone(), packet_crypto: packet_crypto.clone(), packet_compression: packet_compression.clone(), enhanced_inbound: enhanced_inbound.clone(), fec_decoder: fec_decoder.clone(), }); p2p_task.start(handler); } let registration_context = Box::new(RegistrationContext { server_managers: server_manager_list, subnet_external_route, puncher, packet_crypto, packet_compression, enhanced_inbound, fec_decoder, }); app_state.set_config(config.clone()); Ok(Self { config, app_state, task_group, device_io_manager, enhanced_outbound, server_rpc, tun_receiver, registration_context: Some(registration_context), }) } /// Register with server(s) and start data handling tasks. /// Returns the registration response on success. /// On connection-level failure the internal state is kept, so the call can be retried. pub async fn register(&mut self) -> anyhow::Result { let Some(mut ctx) = self.registration_context.take() else { bail!("register can only be called once"); }; match Self::register_impl(&self.app_state, &self.task_group, &mut ctx).await { Ok(response) => Ok(response), Err(e) => { // 注册失败时归还上下文,允许调用方重试 self.registration_context = Some(ctx); Err(e) } } } async fn register_impl( app_state: &AppState, task_group: &TaskGroup, ctx: &mut RegistrationContext, ) -> anyhow::Result { let is_multi_server = ctx.server_managers.len() > 1; let response = if is_multi_server { // Multi-server: coordinated pre-registration log::info!( "Multi-server mode: performing coordinated registration for {} servers", ctx.server_managers.len() ); coordinated_registration(&mut ctx.server_managers).await? } else { // Single-server: normal registration log::info!("Single-server mode: performing normal registration"); ctx.server_managers[0] .connect_and_reg(crate::protocol::control_message::RegistrationMode::Normal) .await? }; let reg_response = match response { crate::protocol::control_message::ResponseMessage::Reg(reg) => { log::info!( "Registration completed, IP: {}, prefix_len: {}", reg.ip, reg.prefix_len ); reg } crate::protocol::control_message::ResponseMessage::Error(e) => { return Ok(RegisterResponse::Failed(e)); } crate::protocol::control_message::ResponseMessage::ConfirmReg(_) => { bail!("Unexpected ConfirmReg response"); } }; let network_addr = NetworkAddr { gateway: reg_response.gateway, broadcast: Ipv4Net::new(reg_response.ip, reg_response.prefix_len)?.broadcast(), ip: reg_response.ip, prefix_len: reg_response.prefix_len, }; app_state.network.set(network_addr); // 保存服务器版本信息 if !reg_response.server_version.is_empty() { for (index, _) in ctx.server_managers.iter().enumerate() { app_state .server_info_collection .set_server_version(index as u32, reg_response.server_version.clone()); } } // Start data handling tasks for all servers for turn_manager in ctx.server_managers.drain(..) { let handler_config = Box::new(InboundHandlerConfig { network_route: NetworkRoute::new( app_state.network.clone(), ctx.subnet_external_route.clone(), ), server_info: app_state.server_info_collection.clone(), nat_info: app_state.nat_info.clone(), peer_map: app_state.peer_map.clone(), punch_backoff: app_state.punch_backoff.clone(), puncher: ctx.puncher.clone(), packet_crypto: ctx.packet_crypto.clone(), packet_compression: ctx.packet_compression.clone(), enhanced_inbound: ctx.enhanced_inbound.clone(), fec_decoder: ctx.fec_decoder.clone(), }); turn_manager.data_handle_task_connected(task_group, handler_config, network_addr); } Ok(RegisterResponse::Success(network_addr)) } pub fn is_no_tun(&self) -> bool { self.config.no_tun } pub async fn start_tun(&mut self) -> anyhow::Result<()> { if self.tun_receiver.is_none() || self.enhanced_outbound.is_none() { bail!("start_tun can only be called once"); } let mut config = DeviceConfig::default(); config = config.set_mtu(self.config.mtu.unwrap_or(DEFAULT_MTU)); if let Some(tun_name) = self.config.tun_name.clone() { config = config.set_tun_name(tun_name); } // 失败时 tun_receiver/enhanced_outbound 不会被消耗,可以重试 self.device_io_manager .start_task(config, &mut self.tun_receiver, &mut self.enhanced_outbound) .await } #[cfg(unix)] pub async fn start_tun_fd(&mut self, tun_fd: Option) -> anyhow::Result<()> { if self.tun_receiver.is_none() || self.enhanced_outbound.is_none() { bail!("start_tun_fd can only be called once"); } let mut config = DeviceConfig::default(); if let Some(tun_fd) = tun_fd { config = config.set_tun_fd(tun_fd); } if let Some(tun_name) = self.config.tun_name.clone() { config = config.set_tun_name(tun_name); } self.device_io_manager .start_task(config, &mut self.tun_receiver, &mut self.enhanced_outbound) .await } #[cfg(not(target_os = "android"))] pub async fn set_tun_network_ip(&self, ip: Ipv4Addr, prefix_len: u8) -> anyhow::Result<()> { self.device_io_manager.set_network(ip, prefix_len).await?; Ok(()) } fn stop_network(&mut self) { self.task_group.stop(); self.app_state.stop_network(); } #[cfg(not(target_os = "android"))] pub async fn tun_if_index(&self) -> anyhow::Result { self.device_io_manager.tun_if_index().await } pub async fn wait_all_stopped(&mut self) { self.task_group.wait_all_stopped().await; } pub fn vnt_api(&self) -> VntApi { VntApi::new(self.app_state.clone(), self.server_rpc.clone()) } } impl Drop for NetworkManager { fn drop(&mut self) { self.stop_network(); } }