支持设置端口
This commit is contained in:
@@ -35,6 +35,7 @@ pub struct FileConfig {
|
|||||||
pub cert_mode: Option<String>,
|
pub cert_mode: Option<String>,
|
||||||
pub udp_stun: Option<Vec<String>>,
|
pub udp_stun: Option<Vec<String>>,
|
||||||
pub tcp_stun: Option<Vec<String>>,
|
pub tcp_stun: Option<Vec<String>>,
|
||||||
|
pub tunnel_port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileConfig {
|
impl FileConfig {
|
||||||
@@ -144,6 +145,9 @@ pub struct Args {
|
|||||||
/// 控制端口,设置0时禁用控制服务
|
/// 控制端口,设置0时禁用控制服务
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub ctrl_port: Option<u16>,
|
pub ctrl_port: Option<u16>,
|
||||||
|
/// 隧道端口,用于P2P通信
|
||||||
|
#[clap(long)]
|
||||||
|
pub tunnel_port: Option<u16>,
|
||||||
/// 读取配置文件
|
/// 读取配置文件
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub conf: Option<PathBuf>,
|
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),
|
allow_port_mapping: args.allow_mapping || file.allow_mapping.unwrap_or(false),
|
||||||
udp_stun,
|
udp_stun,
|
||||||
tcp_stun,
|
tcp_stun,
|
||||||
|
tunnel_port: args.tunnel_port.or(file.tunnel_port),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ctrl_config = CtrlConfig {
|
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),
|
allow_port_mapping: file.allow_mapping.unwrap_or(false),
|
||||||
udp_stun,
|
udp_stun,
|
||||||
tcp_stun,
|
tcp_stun,
|
||||||
|
tunnel_port: file.tunnel_port,
|
||||||
};
|
};
|
||||||
let ctrl_config = CtrlConfig {
|
let ctrl_config = CtrlConfig {
|
||||||
ctrl_port: file.ctrl_port,
|
ctrl_port: file.ctrl_port,
|
||||||
@@ -424,6 +430,9 @@ server = ["quic://1.2.3.4:29872"]
|
|||||||
# 控制服务的 tcp 端口
|
# 控制服务的 tcp 端口
|
||||||
# ctrl_port = 11233
|
# ctrl_port = 11233
|
||||||
|
|
||||||
|
# 隧道端口,用于P2P通信 (默认为0,自动分配)
|
||||||
|
# tunnel_port = 0
|
||||||
|
|
||||||
# MTU 设置
|
# MTU 设置
|
||||||
# mtu = 1400
|
# mtu = 1400
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ pub struct Config {
|
|||||||
pub allow_port_mapping: bool,
|
pub allow_port_mapping: bool,
|
||||||
pub udp_stun: Vec<String>,
|
pub udp_stun: Vec<String>,
|
||||||
pub tcp_stun: Vec<String>,
|
pub tcp_stun: Vec<String>,
|
||||||
|
pub tunnel_port: Option<u16>,
|
||||||
}
|
}
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn check(&self) -> anyhow::Result<()> {
|
pub fn check(&self) -> anyhow::Result<()> {
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ impl NetworkManager {
|
|||||||
app_state.clone(),
|
app_state.clone(),
|
||||||
tunnel_to_server.clone(),
|
tunnel_to_server.clone(),
|
||||||
packet_crypto.clone(),
|
packet_crypto.clone(),
|
||||||
|
config.tunnel_port,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,18 @@ pub async fn init_tunnel(
|
|||||||
app_state: AppState,
|
app_state: AppState,
|
||||||
tunnel_to_server: ServerOutbound,
|
tunnel_to_server: ServerOutbound,
|
||||||
packet_crypto: PacketCrypto,
|
packet_crypto: PacketCrypto,
|
||||||
|
tunnel_port: Option<u16>,
|
||||||
) -> anyhow::Result<(Puncher, P2pOutbound, P2pTask)> {
|
) -> anyhow::Result<(Puncher, P2pOutbound, P2pTask)> {
|
||||||
|
let tunnel_port = tunnel_port.unwrap_or(0);
|
||||||
let udp_config = rust_p2p_core::tunnel::config::UdpTunnelConfig::default()
|
let udp_config = rust_p2p_core::tunnel::config::UdpTunnelConfig::default()
|
||||||
.set_main_udp_count(2)
|
.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(
|
let tcp_config = rust_p2p_core::tunnel::config::TcpTunnelConfig::new(Box::new(
|
||||||
rust_p2p_core::tunnel::tcp::LengthPrefixedInitCodec,
|
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()
|
let config = rust_p2p_core::tunnel::config::TunnelConfig::empty()
|
||||||
.set_udp_tunnel_config(udp_config)
|
.set_udp_tunnel_config(udp_config)
|
||||||
.set_tcp_tunnel_config(tcp_config);
|
.set_tcp_tunnel_config(tcp_config);
|
||||||
|
|||||||
+48
-80
@@ -71,10 +71,7 @@ pub extern "system" fn Java_com_vnt_VntManager_nativeInit(
|
|||||||
|
|
||||||
/// 销毁JNI模块
|
/// 销毁JNI模块
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "system" fn Java_com_vnt_VntManager_nativeDestroy(
|
pub extern "system" fn Java_com_vnt_VntManager_nativeDestroy(_env: JNIEnv, _class: JClass) {
|
||||||
_env: JNIEnv,
|
|
||||||
_class: JClass,
|
|
||||||
) {
|
|
||||||
let mut state = GLOBAL_STATE.lock();
|
let mut state = GLOBAL_STATE.lock();
|
||||||
*state = None;
|
*state = None;
|
||||||
}
|
}
|
||||||
@@ -88,14 +85,10 @@ pub extern "system" fn Java_com_vnt_VntManager_nativeCreateNetwork<'local>(
|
|||||||
) -> jlong {
|
) -> jlong {
|
||||||
let result: anyhow::Result<i64> = (|| {
|
let result: anyhow::Result<i64> = (|| {
|
||||||
let mut global_state = GLOBAL_STATE.lock();
|
let mut global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_mut().context("VNT not initialized")?;
|
||||||
.as_mut()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
// 解析配置JSON
|
// 解析配置JSON
|
||||||
let config_str: String = env
|
let config_str: String = env.get_string(&config_json)?.into();
|
||||||
.get_string(&config_json)?
|
|
||||||
.into();
|
|
||||||
let config = parse_config_from_json(&config_str)?;
|
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.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);
|
state.task_group_managers.insert(id, task_group_manager);
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
@@ -142,9 +137,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeRegister<'local>(
|
|||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let (network_manager_arc, runtime) = {
|
let (network_manager_arc, runtime) = {
|
||||||
let mut global_state = GLOBAL_STATE.lock();
|
let mut global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_mut().context("VNT not initialized")?;
|
||||||
.as_mut()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let network_manager_arc = state
|
let network_manager_arc = state
|
||||||
.network_managers
|
.network_managers
|
||||||
@@ -162,9 +155,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeRegister<'local>(
|
|||||||
.as_mut()
|
.as_mut()
|
||||||
.context("Network manager already destroyed")?;
|
.context("Network manager already destroyed")?;
|
||||||
|
|
||||||
runtime.block_on(async {
|
runtime.block_on(async { manager.register().await })?
|
||||||
manager.register().await
|
|
||||||
})?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match response {
|
match response {
|
||||||
@@ -211,9 +202,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeStartTun(
|
|||||||
let result: anyhow::Result<()> = (|| {
|
let result: anyhow::Result<()> = (|| {
|
||||||
let (network_manager_arc, runtime) = {
|
let (network_manager_arc, runtime) = {
|
||||||
let mut global_state = GLOBAL_STATE.lock();
|
let mut global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_mut().context("VNT not initialized")?;
|
||||||
.as_mut()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let network_manager_arc = state
|
let network_manager_arc = state
|
||||||
.network_managers
|
.network_managers
|
||||||
@@ -233,17 +222,13 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeStartTun(
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
let tun_fd = if tun_fd < 0 { None } else { Some(tun_fd) };
|
let tun_fd = if tun_fd < 0 { None } else { Some(tun_fd) };
|
||||||
runtime.block_on(async {
|
runtime.block_on(async { manager.start_tun_fd(tun_fd).await })?;
|
||||||
manager.start_tun_fd(tun_fd).await
|
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
{
|
{
|
||||||
let _ = tun_fd; // 避免未使用警告
|
let _ = tun_fd; // 避免未使用警告
|
||||||
runtime.block_on(async {
|
runtime.block_on(async { manager.start_tun().await })?;
|
||||||
manager.start_tun().await
|
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -270,9 +255,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeSetNetworkIp<'local>(
|
|||||||
let result: anyhow::Result<()> = (|| {
|
let result: anyhow::Result<()> = (|| {
|
||||||
let (network_manager_arc, runtime) = {
|
let (network_manager_arc, runtime) = {
|
||||||
let mut global_state = GLOBAL_STATE.lock();
|
let mut global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_mut().context("VNT not initialized")?;
|
||||||
.as_mut()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let network_manager_arc = state
|
let network_manager_arc = state
|
||||||
.network_managers
|
.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_str: String = env.get_string(&ip)?.into();
|
||||||
let ip_addr: Ipv4Addr = ip_str.parse()
|
let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?;
|
||||||
.context("Invalid IP address")?;
|
|
||||||
|
|
||||||
let manager_lock = network_manager_arc.lock();
|
let manager_lock = network_manager_arc.lock();
|
||||||
let manager = manager_lock
|
let manager = manager_lock
|
||||||
@@ -295,9 +277,8 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeSetNetworkIp<'local>(
|
|||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
{
|
{
|
||||||
runtime.block_on(async {
|
runtime
|
||||||
manager.set_tun_network_ip(ip_addr, prefix_len as u8).await
|
.block_on(async { manager.set_tun_network_ip(ip_addr, prefix_len as u8).await })?;
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
@@ -327,9 +308,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeGetApi(
|
|||||||
) -> jlong {
|
) -> jlong {
|
||||||
let result: anyhow::Result<i64> = (|| {
|
let result: anyhow::Result<i64> = (|| {
|
||||||
let mut global_state = GLOBAL_STATE.lock();
|
let mut global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_mut().context("VNT not initialized")?;
|
||||||
.as_mut()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let network_manager_arc = state
|
let network_manager_arc = state
|
||||||
.network_managers
|
.network_managers
|
||||||
@@ -367,9 +346,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeIsNoTun(
|
|||||||
) -> jboolean {
|
) -> jboolean {
|
||||||
let result: anyhow::Result<bool> = (|| {
|
let result: anyhow::Result<bool> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let network_manager_arc = state
|
let network_manager_arc = state
|
||||||
.network_managers
|
.network_managers
|
||||||
@@ -386,7 +363,13 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeIsNoTun(
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
match result {
|
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) => {
|
Err(e) => {
|
||||||
let _ = env.throw(format!("Failed to check no_tun: {:?}", e));
|
let _ = env.throw(format!("Failed to check no_tun: {:?}", e));
|
||||||
0
|
0
|
||||||
@@ -403,9 +386,7 @@ pub extern "system" fn Java_com_vnt_VntNetwork_nativeStop(
|
|||||||
) -> jboolean {
|
) -> jboolean {
|
||||||
let result: anyhow::Result<()> = (|| {
|
let result: anyhow::Result<()> = (|| {
|
||||||
let mut global_state = GLOBAL_STATE.lock();
|
let mut global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_mut().context("VNT not initialized")?;
|
||||||
.as_mut()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
// 停止任务组
|
// 停止任务组
|
||||||
if let Some(task_group_manager) = state.task_group_managers.get(&handle) {
|
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 {
|
) -> jstring {
|
||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -483,9 +462,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetNetwork<'local>(
|
|||||||
) -> jstring {
|
) -> jstring {
|
||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -526,9 +503,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetNatInfo<'local>(
|
|||||||
) -> jstring {
|
) -> jstring {
|
||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -568,9 +543,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetServerList<'local>(
|
|||||||
) -> jstring {
|
) -> jstring {
|
||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -615,9 +588,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetRouteTable<'local>(
|
|||||||
) -> jstring {
|
) -> jstring {
|
||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -671,9 +642,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeIsDirect<'local>(
|
|||||||
) -> jboolean {
|
) -> jboolean {
|
||||||
let result: anyhow::Result<bool> = (|| {
|
let result: anyhow::Result<bool> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -681,14 +650,19 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeIsDirect<'local>(
|
|||||||
.context("Invalid API handle")?;
|
.context("Invalid API handle")?;
|
||||||
|
|
||||||
let ip_str: String = env.get_string(&ip)?.into();
|
let ip_str: String = env.get_string(&ip)?.into();
|
||||||
let ip_addr: Ipv4Addr = ip_str.parse()
|
let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?;
|
||||||
.context("Invalid IP address")?;
|
|
||||||
|
|
||||||
Ok(api.is_direct(&ip_addr))
|
Ok(api.is_direct(&ip_addr))
|
||||||
})();
|
})();
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(is_direct) => if is_direct { 1 } else { 0 },
|
Ok(is_direct) => {
|
||||||
|
if is_direct {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let _ = env.throw(format!("Failed to check direct: {:?}", e));
|
let _ = env.throw(format!("Failed to check direct: {:?}", e));
|
||||||
0
|
0
|
||||||
@@ -706,9 +680,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetPeerNatInfo<'local>(
|
|||||||
) -> jstring {
|
) -> jstring {
|
||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -716,8 +688,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetPeerNatInfo<'local>(
|
|||||||
.context("Invalid API handle")?;
|
.context("Invalid API handle")?;
|
||||||
|
|
||||||
let ip_str: String = env.get_string(&ip)?.into();
|
let ip_str: String = env.get_string(&ip)?.into();
|
||||||
let ip_addr: Ipv4Addr = ip_str.parse()
|
let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?;
|
||||||
.context("Invalid IP address")?;
|
|
||||||
|
|
||||||
if let Some(nat_info) = api.peer_nat_info(&ip_addr) {
|
if let Some(nat_info) = api.peer_nat_info(&ip_addr) {
|
||||||
let json = serde_json::json!({
|
let json = serde_json::json!({
|
||||||
@@ -753,9 +724,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetPacketLoss<'local>(
|
|||||||
) -> jstring {
|
) -> jstring {
|
||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -763,8 +732,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetPacketLoss<'local>(
|
|||||||
.context("Invalid API handle")?;
|
.context("Invalid API handle")?;
|
||||||
|
|
||||||
let ip_str: String = env.get_string(&ip)?.into();
|
let ip_str: String = env.get_string(&ip)?.into();
|
||||||
let ip_addr: Ipv4Addr = ip_str.parse()
|
let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?;
|
||||||
.context("Invalid IP address")?;
|
|
||||||
|
|
||||||
if let Some(loss_info) = api.packet_loss_info(&ip_addr) {
|
if let Some(loss_info) = api.packet_loss_info(&ip_addr) {
|
||||||
let json = serde_json::json!({
|
let json = serde_json::json!({
|
||||||
@@ -801,9 +769,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetTrafficInfo<'local>(
|
|||||||
) -> jstring {
|
) -> jstring {
|
||||||
let result: anyhow::Result<String> = (|| {
|
let result: anyhow::Result<String> = (|| {
|
||||||
let global_state = GLOBAL_STATE.lock();
|
let global_state = GLOBAL_STATE.lock();
|
||||||
let state = global_state
|
let state = global_state.as_ref().context("VNT not initialized")?;
|
||||||
.as_ref()
|
|
||||||
.context("VNT not initialized")?;
|
|
||||||
|
|
||||||
let api = state
|
let api = state
|
||||||
.vnt_apis
|
.vnt_apis
|
||||||
@@ -811,8 +777,7 @@ pub extern "system" fn Java_com_vnt_VntApi_nativeGetTrafficInfo<'local>(
|
|||||||
.context("Invalid API handle")?;
|
.context("Invalid API handle")?;
|
||||||
|
|
||||||
let ip_str: String = env.get_string(&ip)?.into();
|
let ip_str: String = env.get_string(&ip)?.into();
|
||||||
let ip_addr: Ipv4Addr = ip_str.parse()
|
let ip_addr: Ipv4Addr = ip_str.parse().context("Invalid IP address")?;
|
||||||
.context("Invalid IP address")?;
|
|
||||||
|
|
||||||
if let Some(traffic_info) = api.traffic_info(&ip_addr) {
|
if let Some(traffic_info) = api.traffic_info(&ip_addr) {
|
||||||
let json = serde_json::json!({
|
let json = serde_json::json!({
|
||||||
@@ -884,6 +849,8 @@ fn parse_config_from_json(json_str: &str) -> anyhow::Result<Config> {
|
|||||||
udp_stun: Vec<String>,
|
udp_stun: Vec<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
tcp_stun: Vec<String>,
|
tcp_stun: Vec<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
tunnel_port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg: ConfigJson = serde_json::from_str(json_str)?;
|
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,
|
udp_stun,
|
||||||
tcp_stun,
|
tcp_stun,
|
||||||
fec: cfg.fec,
|
fec: cfg.fec,
|
||||||
|
tunnel_port: cfg.tunnel_port,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ pub struct StartConfig {
|
|||||||
pub udp_stun: Vec<String>,
|
pub udp_stun: Vec<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub tcp_stun: Vec<String>,
|
pub tcp_stun: Vec<String>,
|
||||||
|
pub tunnel_port: Option<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@@ -955,6 +956,7 @@ fn convert_config(cfg: StartConfig) -> anyhow::Result<CoreConfig> {
|
|||||||
udp_stun,
|
udp_stun,
|
||||||
tcp_stun,
|
tcp_stun,
|
||||||
fec: cfg.fec,
|
fec: cfg.fec,
|
||||||
|
tunnel_port: cfg.tunnel_port,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -985,6 +985,11 @@
|
|||||||
<input v-model.number="formData.mtu" type="number" placeholder="1380"
|
<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">
|
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>
|
||||||
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1742,7 +1747,8 @@
|
|||||||
cert_mode: "skip",
|
cert_mode: "skip",
|
||||||
fingerprint: "",
|
fingerprint: "",
|
||||||
udp_stun: [],
|
udp_stun: [],
|
||||||
tcp_stun: []
|
tcp_stun: [],
|
||||||
|
tunnel_port: null
|
||||||
});
|
});
|
||||||
|
|
||||||
// 从TOML解析到表单
|
// 从TOML解析到表单
|
||||||
@@ -1770,7 +1776,8 @@
|
|||||||
cert_mode: "skip",
|
cert_mode: "skip",
|
||||||
fingerprint: "",
|
fingerprint: "",
|
||||||
udp_stun: [],
|
udp_stun: [],
|
||||||
tcp_stun: []
|
tcp_stun: [],
|
||||||
|
tunnel_port: null
|
||||||
};
|
};
|
||||||
|
|
||||||
const lines = toml.split('\n');
|
const lines = toml.split('\n');
|
||||||
@@ -2106,7 +2113,8 @@
|
|||||||
cert_mode: "skip",
|
cert_mode: "skip",
|
||||||
fingerprint: "",
|
fingerprint: "",
|
||||||
udp_stun: [],
|
udp_stun: [],
|
||||||
tcp_stun: []
|
tcp_stun: [],
|
||||||
|
tunnel_port: null
|
||||||
};
|
};
|
||||||
editorContent.value = `# config_name = "配置名称"
|
editorContent.value = `# config_name = "配置名称"
|
||||||
# --- 网络配置 ---
|
# --- 网络配置 ---
|
||||||
|
|||||||
Reference in New Issue
Block a user