支持设置端口

This commit is contained in:
lbl
2026-02-28 17:49:11 +08:00
parent 5a31ad89f4
commit 2aa423062e
7 changed files with 78 additions and 85 deletions
+9
View File
@@ -35,6 +35,7 @@ pub struct FileConfig {
pub cert_mode: Option<String>,
pub udp_stun: Option<Vec<String>>,
pub tcp_stun: Option<Vec<String>>,
pub tunnel_port: Option<u16>,
}
impl FileConfig {
@@ -144,6 +145,9 @@ pub struct Args {
/// 控制端口,设置0时禁用控制服务
#[clap(long)]
pub ctrl_port: Option<u16>,
/// 隧道端口,用于P2P通信
#[clap(long)]
pub tunnel_port: Option<u16>,
/// 读取配置文件
#[arg(long)]
pub conf: Option<PathBuf>,
@@ -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
+1
View File
@@ -37,6 +37,7 @@ pub struct Config {
pub allow_port_mapping: bool,
pub udp_stun: Vec<String>,
pub tcp_stun: Vec<String>,
pub tunnel_port: Option<u16>,
}
impl Config {
pub fn check(&self) -> anyhow::Result<()> {
+1
View File
@@ -74,6 +74,7 @@ impl NetworkManager {
app_state.clone(),
tunnel_to_server.clone(),
packet_crypto.clone(),
config.tunnel_port,
)
.await?;
@@ -23,14 +23,18 @@ pub async fn init_tunnel(
app_state: AppState,
tunnel_to_server: ServerOutbound,
packet_crypto: PacketCrypto,
tunnel_port: Option<u16>,
) -> 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);
+48 -80
View File
@@ -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<i64> = (|| {
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<String> = (|| {
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<i64> = (|| {
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<bool> = (|| {
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<String> = (|| {
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<String> = (|| {
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<String> = (|| {
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<String> = (|| {
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<String> = (|| {
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<bool> = (|| {
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<String> = (|| {
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<String> = (|| {
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<String> = (|| {
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<Config> {
udp_stun: Vec<String>,
#[serde(default)]
tcp_stun: Vec<String>,
#[serde(default)]
tunnel_port: Option<u16>,
}
let cfg: ConfigJson = serde_json::from_str(json_str)?;
@@ -962,5 +929,6 @@ fn parse_config_from_json(json_str: &str) -> anyhow::Result<Config> {
udp_stun,
tcp_stun,
fec: cfg.fec,
tunnel_port: cfg.tunnel_port,
})
}
+2
View File
@@ -195,6 +195,7 @@ pub struct StartConfig {
pub udp_stun: Vec<String>,
#[serde(default)]
pub tcp_stun: Vec<String>,
pub tunnel_port: Option<u16>,
}
#[derive(Deserialize)]
@@ -955,6 +956,7 @@ fn convert_config(cfg: StartConfig) -> anyhow::Result<CoreConfig> {
udp_stun,
tcp_stun,
fec: cfg.fec,
tunnel_port: cfg.tunnel_port,
})
}
+11 -3
View File
@@ -985,6 +985,11 @@
<input v-model.number="formData.mtu" type="number" placeholder="1380"
class="w-full bg-slate-800 border border-slate-600 rounded-lg px-3 py-2 text-white placeholder-slate-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-2">隧道端口</label>
<input v-model.number="formData.tunnel_port" type="number" placeholder="0 (自动分配)"
class="w-full bg-slate-800 border border-slate-600 rounded-lg px-3 py-2 text-white placeholder-slate-500 focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
</div>
</div>
@@ -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 = "配置名称"
# --- 网络配置 ---