diff --git a/src/args_config.rs b/src/args_config.rs index 924edd1..507a722 100644 --- a/src/args_config.rs +++ b/src/args_config.rs @@ -35,6 +35,7 @@ pub struct FileConfig { pub cert_mode: Option, pub udp_stun: Option>, pub tcp_stun: Option>, + pub tunnel_port: Option, } impl FileConfig { @@ -144,6 +145,9 @@ pub struct Args { /// 控制端口,设置0时禁用控制服务 #[clap(long)] pub ctrl_port: Option, + /// 隧道端口,用于P2P通信 + #[clap(long)] + pub tunnel_port: Option, /// 读取配置文件 #[arg(long)] pub conf: Option, @@ -253,6 +257,7 @@ fn build_from_args_and_file(args: Args, file: FileConfig) -> anyhow::Result<(Con allow_port_mapping: args.allow_mapping || file.allow_mapping.unwrap_or(false), udp_stun, tcp_stun, + tunnel_port: args.tunnel_port.or(file.tunnel_port), }; let ctrl_config = CtrlConfig { @@ -349,6 +354,7 @@ fn build_from_file_only(file: FileConfig) -> anyhow::Result<(Config, CtrlConfig) allow_port_mapping: file.allow_mapping.unwrap_or(false), udp_stun, tcp_stun, + tunnel_port: file.tunnel_port, }; let ctrl_config = CtrlConfig { ctrl_port: file.ctrl_port, @@ -424,6 +430,9 @@ server = ["quic://1.2.3.4:29872"] # 控制服务的 tcp 端口 # ctrl_port = 11233 +# 隧道端口,用于P2P通信 (默认为0,自动分配) +# tunnel_port = 0 + # MTU 设置 # mtu = 1400 diff --git a/vnt-core/src/context/config.rs b/vnt-core/src/context/config.rs index e0a1f99..9f4befa 100644 --- a/vnt-core/src/context/config.rs +++ b/vnt-core/src/context/config.rs @@ -37,6 +37,7 @@ pub struct Config { pub allow_port_mapping: bool, pub udp_stun: Vec, pub tcp_stun: Vec, + pub tunnel_port: Option, } impl Config { pub fn check(&self) -> anyhow::Result<()> { diff --git a/vnt-core/src/core/mod.rs b/vnt-core/src/core/mod.rs index de4243d..1d37025 100644 --- a/vnt-core/src/core/mod.rs +++ b/vnt-core/src/core/mod.rs @@ -74,6 +74,7 @@ impl NetworkManager { app_state.clone(), tunnel_to_server.clone(), packet_crypto.clone(), + config.tunnel_port, ) .await?; diff --git a/vnt-core/src/tunnel_core/p2p/transport/task.rs b/vnt-core/src/tunnel_core/p2p/transport/task.rs index b82ec21..2eff25b 100644 --- a/vnt-core/src/tunnel_core/p2p/transport/task.rs +++ b/vnt-core/src/tunnel_core/p2p/transport/task.rs @@ -23,14 +23,18 @@ pub async fn init_tunnel( app_state: AppState, tunnel_to_server: ServerOutbound, packet_crypto: PacketCrypto, + tunnel_port: Option, ) -> anyhow::Result<(Puncher, P2pOutbound, P2pTask)> { + let tunnel_port = tunnel_port.unwrap_or(0); let udp_config = rust_p2p_core::tunnel::config::UdpTunnelConfig::default() .set_main_udp_count(2) - .set_sub_udp_count(82); + .set_sub_udp_count(82) + .set_simple_udp_port(tunnel_port); let tcp_config = rust_p2p_core::tunnel::config::TcpTunnelConfig::new(Box::new( rust_p2p_core::tunnel::tcp::LengthPrefixedInitCodec, )) - .set_tcp_multiplexing_limit(2); + .set_tcp_multiplexing_limit(2) + .set_tcp_port(tunnel_port); let config = rust_p2p_core::tunnel::config::TunnelConfig::empty() .set_udp_tunnel_config(udp_config) .set_tcp_tunnel_config(tcp_config); diff --git a/vnt-jni/src/lib.rs b/vnt-jni/src/lib.rs index c8e47de..dad6b0b 100644 --- a/vnt-jni/src/lib.rs +++ b/vnt-jni/src/lib.rs @@ -71,10 +71,7 @@ pub extern "system" fn Java_com_vnt_VntManager_nativeInit( /// 销毁JNI模块 #[no_mangle] -pub extern "system" fn Java_com_vnt_VntManager_nativeDestroy( - _env: JNIEnv, - _class: JClass, -) { +pub extern "system" fn Java_com_vnt_VntManager_nativeDestroy(_env: JNIEnv, _class: JClass) { let mut state = GLOBAL_STATE.lock(); *state = None; } @@ -88,14 +85,10 @@ pub extern "system" fn Java_com_vnt_VntManager_nativeCreateNetwork<'local>( ) -> jlong { let result: anyhow::Result = (|| { let mut global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_mut() - .context("VNT not initialized")?; + let state = global_state.as_mut().context("VNT not initialized")?; // 解析配置JSON - let config_str: String = env - .get_string(&config_json)? - .into(); + let config_str: String = env.get_string(&config_json)?.into(); let config = parse_config_from_json(&config_str)?; // 创建任务组 @@ -117,7 +110,9 @@ pub extern "system" fn Java_com_vnt_VntManager_nativeCreateNetwork<'local>( state.next_id += 1; // 保存实例 - state.network_managers.insert(id, Arc::new(Mutex::new(Some(network_manager)))); + state + .network_managers + .insert(id, Arc::new(Mutex::new(Some(network_manager)))); state.task_group_managers.insert(id, task_group_manager); Ok(id) @@ -142,9 +137,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeRegister<'local>( let result: anyhow::Result = (|| { let (network_manager_arc, runtime) = { let mut global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_mut() - .context("VNT not initialized")?; + let state = global_state.as_mut().context("VNT not initialized")?; let network_manager_arc = state .network_managers @@ -162,9 +155,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeRegister<'local>( .as_mut() .context("Network manager already destroyed")?; - runtime.block_on(async { - manager.register().await - })? + runtime.block_on(async { manager.register().await })? }; match response { @@ -211,9 +202,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeStartTun( let result: anyhow::Result<()> = (|| { let (network_manager_arc, runtime) = { let mut global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_mut() - .context("VNT not initialized")?; + let state = global_state.as_mut().context("VNT not initialized")?; let network_manager_arc = state .network_managers @@ -233,17 +222,13 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeStartTun( #[cfg(unix)] { let tun_fd = if tun_fd < 0 { None } else { Some(tun_fd) }; - runtime.block_on(async { - manager.start_tun_fd(tun_fd).await - })?; + runtime.block_on(async { manager.start_tun_fd(tun_fd).await })?; } #[cfg(not(unix))] { let _ = tun_fd; // 避免未使用警告 - runtime.block_on(async { - manager.start_tun().await - })?; + runtime.block_on(async { manager.start_tun().await })?; } Ok(()) @@ -270,9 +255,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeSetNetworkIp<'local>( let result: anyhow::Result<()> = (|| { let (network_manager_arc, runtime) = { let mut global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_mut() - .context("VNT not initialized")?; + let state = global_state.as_mut().context("VNT not initialized")?; let network_manager_arc = state .network_managers @@ -285,8 +268,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeSetNetworkIp<'local>( }; let ip_str: String = env.get_string(&ip)?.into(); - let ip_addr: Ipv4Addr = ip_str.parse() - .context("Invalid IP address")?; + let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?; let manager_lock = network_manager_arc.lock(); let manager = manager_lock @@ -295,9 +277,8 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeSetNetworkIp<'local>( #[cfg(not(target_os = "android"))] { - runtime.block_on(async { - manager.set_tun_network_ip(ip_addr, prefix_len as u8).await - })?; + runtime + .block_on(async { manager.set_tun_network_ip(ip_addr, prefix_len as u8).await })?; } #[cfg(target_os = "android")] @@ -327,9 +308,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeGetApi( ) -> jlong { let result: anyhow::Result = (|| { let mut global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_mut() - .context("VNT not initialized")?; + let state = global_state.as_mut().context("VNT not initialized")?; let network_manager_arc = state .network_managers @@ -367,9 +346,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeIsNoTun( ) -> jboolean { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let network_manager_arc = state .network_managers @@ -386,7 +363,13 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeIsNoTun( })(); match result { - Ok(is_no_tun) => if is_no_tun { 1 } else { 0 }, + Ok(is_no_tun) => { + if is_no_tun { + 1 + } else { + 0 + } + } Err(e) => { let _ = env.throw(format!("Failed to check no_tun: {:?}", e)); 0 @@ -403,9 +386,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeStop( ) -> jboolean { let result: anyhow::Result<()> = (|| { let mut global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_mut() - .context("VNT not initialized")?; + let state = global_state.as_mut().context("VNT not initialized")?; // 停止任务组 if let Some(task_group_manager) = state.task_group_managers.get(&handle) { @@ -440,9 +421,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetClientList<'local>( ) -> jstring { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -483,9 +462,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetNetwork<'local>( ) -> jstring { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -526,9 +503,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetNatInfo<'local>( ) -> jstring { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -568,9 +543,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetServerList<'local>( ) -> jstring { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -615,9 +588,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetRouteTable<'local>( ) -> jstring { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -671,9 +642,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeIsDirect<'local>( ) -> jboolean { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -681,14 +650,19 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeIsDirect<'local>( .context("Invalid API handle")?; let ip_str: String = env.get_string(&ip)?.into(); - let ip_addr: Ipv4Addr = ip_str.parse() - .context("Invalid IP address")?; + let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?; Ok(api.is_direct(&ip_addr)) })(); match result { - Ok(is_direct) => if is_direct { 1 } else { 0 }, + Ok(is_direct) => { + if is_direct { + 1 + } else { + 0 + } + } Err(e) => { let _ = env.throw(format!("Failed to check direct: {:?}", e)); 0 @@ -706,9 +680,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetPeerNatInfo<'local>( ) -> jstring { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -716,8 +688,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetPeerNatInfo<'local>( .context("Invalid API handle")?; let ip_str: String = env.get_string(&ip)?.into(); - let ip_addr: Ipv4Addr = ip_str.parse() - .context("Invalid IP address")?; + let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?; if let Some(nat_info) = api.peer_nat_info(&ip_addr) { let json = serde_json::json!({ @@ -753,9 +724,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetPacketLoss<'local>( ) -> jstring { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -763,8 +732,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetPacketLoss<'local>( .context("Invalid API handle")?; let ip_str: String = env.get_string(&ip)?.into(); - let ip_addr: Ipv4Addr = ip_str.parse() - .context("Invalid IP address")?; + let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?; if let Some(loss_info) = api.packet_loss_info(&ip_addr) { let json = serde_json::json!({ @@ -801,9 +769,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetTrafficInfo<'local>( ) -> jstring { let result: anyhow::Result = (|| { let global_state = GLOBAL_STATE.lock(); - let state = global_state - .as_ref() - .context("VNT not initialized")?; + let state = global_state.as_ref().context("VNT not initialized")?; let api = state .vnt_apis @@ -811,8 +777,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetTrafficInfo<'local>( .context("Invalid API handle")?; let ip_str: String = env.get_string(&ip)?.into(); - let ip_addr: Ipv4Addr = ip_str.parse() - .context("Invalid IP address")?; + let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?; if let Some(traffic_info) = api.traffic_info(&ip_addr) { let json = serde_json::json!({ @@ -884,6 +849,8 @@ fn parse_config_from_json(json_str: &str) -> anyhow::Result { udp_stun: Vec, #[serde(default)] tcp_stun: Vec, + #[serde(default)] + tunnel_port: Option, } let cfg: ConfigJson = serde_json::from_str(json_str)?; @@ -962,5 +929,6 @@ fn parse_config_from_json(json_str: &str) -> anyhow::Result { udp_stun, tcp_stun, fec: cfg.fec, + tunnel_port: cfg.tunnel_port, }) } diff --git a/vnt-web/src/service_http.rs b/vnt-web/src/service_http.rs index 74a7c2d..8e416e1 100644 --- a/vnt-web/src/service_http.rs +++ b/vnt-web/src/service_http.rs @@ -195,6 +195,7 @@ pub struct StartConfig { pub udp_stun: Vec, #[serde(default)] pub tcp_stun: Vec, + pub tunnel_port: Option, } #[derive(Deserialize)] @@ -955,6 +956,7 @@ fn convert_config(cfg: StartConfig) -> anyhow::Result { udp_stun, tcp_stun, fec: cfg.fec, + tunnel_port: cfg.tunnel_port, }) } diff --git a/vnt-web/static/index.html b/vnt-web/static/index.html index 444b568..bdbe32b 100644 --- a/vnt-web/static/index.html +++ b/vnt-web/static/index.html @@ -985,6 +985,11 @@ +
+ + +
@@ -1742,7 +1747,8 @@ cert_mode: "skip", fingerprint: "", udp_stun: [], - tcp_stun: [] + tcp_stun: [], + tunnel_port: null }); // 从TOML解析到表单 @@ -1770,7 +1776,8 @@ cert_mode: "skip", fingerprint: "", udp_stun: [], - tcp_stun: [] + tcp_stun: [], + tunnel_port: null }; const lines = toml.split('\n'); @@ -2106,7 +2113,8 @@ cert_mode: "skip", fingerprint: "", udp_stun: [], - tcp_stun: [] + tcp_stun: [], + tunnel_port: null }; editorContent.value = `# config_name = "配置名称" # --- 网络配置 ---