From 073c820da61a1b52eb0cf22b6fa8b62573df6180 Mon Sep 17 00:00:00 2001 From: lubeilin <1791778603@qq.com> Date: Mon, 4 Sep 2023 20:34:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=93=E6=B4=9E=E9=80=89?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnt-cli/src/main.rs | 18 ++++++++++++++++-- vnt-jni/src/vnt_util.rs | 2 ++ vnt/src/channel/punch.rs | 32 ++++++++++++++++++++++++++++++-- vnt/src/core/mod.rs | 9 +++++---- vnt/src/handle/punch_handler.rs | 3 ++- 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/vnt-cli/src/main.rs b/vnt-cli/src/main.rs index f010bb8..8bf2001 100644 --- a/vnt-cli/src/main.rs +++ b/vnt-cli/src/main.rs @@ -11,6 +11,7 @@ use tokio::signal; use tokio::signal::unix::{signal, SignalKind}; use common::args_parse::{ips_parse, out_ips_parse}; +use vnt::channel::punch::PunchModel; use vnt::cipher::CipherModel; use vnt::core::{Config, Vnt, VntUtil}; use vnt::handle::handshake_handler::HandshakeEnum; @@ -55,6 +56,12 @@ fn main() { opts.optopt("", "thread", "线程数(必须为正整数)", ""); opts.optopt("", "model", "加密模式", ""); opts.optflag("", "finger", "指纹校验"); + opts.optopt( + "", + "punch", + "取值ipv4/ipv6,表示仅使用ipv4或ipv6打洞", + "", + ); //"后台运行时,查看其他设备列表" opts.optflag("", "list", "后台运行时,查看其他设备列表"); opts.optflag("", "all", "后台运行时,查看其他设备完整信息"); @@ -220,6 +227,10 @@ fn main() { return; } let finger = matches.opt_present("finger"); + let punch_model = matches + .opt_get::("punch") + .unwrap() + .unwrap_or(PunchModel::All); println!("version {}", vnt::VNT_VERSION); let config = Config::new( tap, @@ -241,6 +252,7 @@ fn main() { parallel, cipher_model, finger, + punch_model, ); let runtime = tokio::runtime::Builder::new_multi_thread() .enable_all() @@ -361,12 +373,12 @@ async fn main0(config: Config, show_cmd: bool) { println!("command error :{}", e); } }); + #[cfg(unix)] + let mut sigterm = signal(SignalKind::terminate()).expect("Error setting SIGTERM handler"); if show_cmd { let stdin = tokio::io::stdin(); let mut cmd = String::new(); let mut reader = BufReader::new(stdin); - #[cfg(unix)] - let mut sigterm = signal(SignalKind::terminate()).expect("Error setting SIGTERM handler"); loop { cmd.clear(); println!("input:list,info,route,all,stop"); @@ -504,6 +516,8 @@ fn print_usage(program: &str, _opts: Options) { println!(" --thread 线程数(必须为正整数),默认为核心数乘2"); println!(" --model 加密模式(默认aes_gcm),可选值aes_gcm/aes_cbc/aes_ecb,通常性能aes_ecb>aes_cbc>aes_gcm,安全性则相反"); println!(" --finger 增加数据指纹校验,可增加安全性,如果服务端开启指纹校验,则客户端也必须开启"); + println!(" --punch 取值ipv4/ipv6,ipv4表示仅使用ipv4打洞"); + println!(); println!( " --list {}", diff --git a/vnt-jni/src/vnt_util.rs b/vnt-jni/src/vnt_util.rs index 2f99724..97574bf 100644 --- a/vnt-jni/src/vnt_util.rs +++ b/vnt-jni/src/vnt_util.rs @@ -8,6 +8,7 @@ use jni::objects::{JClass, JObject, JString, JValue}; use jni::sys::jboolean; use jni::sys::{jint, jlong, jobject}; use jni::JNIEnv; +use vnt::channel::punch::PunchModel; use vnt::cipher::CipherModel; use vnt::core::sync::VntUtilSync; use vnt::core::Config; @@ -117,6 +118,7 @@ fn new_sync(env: &mut JNIEnv, config: JObject) -> Result { 1, cipher_model, finger, + PunchModel::All, ); match VntUtilSync::new(config) { Ok(vnt_util) => Ok(vnt_util), diff --git a/vnt/src/channel/punch.rs b/vnt/src/channel/punch.rs index b093152..42e78af 100644 --- a/vnt/src/channel/punch.rs +++ b/vnt/src/channel/punch.rs @@ -1,12 +1,32 @@ use std::collections::HashMap; use std::io; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; +use std::str::FromStr; use std::time::Duration; use rand::prelude::SliceRandom; use crate::channel::channel::Context; +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub enum PunchModel { + IPv4, + IPv6, + All, +} + +impl FromStr for PunchModel { + type Err = String; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().trim() { + "ipv4" => Ok(PunchModel::IPv4), + "ipv6" => Ok(PunchModel::IPv6), + _ => Ok(PunchModel::All), + } + } +} + #[derive(Clone, Debug)] pub struct NatInfo { pub public_ips: Vec, @@ -49,10 +69,11 @@ pub struct Punch { context: Context, port_vec: Vec, port_index: HashMap, + punch_model: PunchModel, } impl Punch { - pub fn new(context: Context) -> Self { + pub fn new(context: Context, punch_model: PunchModel) -> Self { let mut port_vec: Vec = (1..65535).collect(); port_vec.push(65535); let mut rng = rand::thread_rng(); @@ -61,6 +82,7 @@ impl Punch { context, port_vec, port_index: HashMap::new(), + punch_model, } } } @@ -76,12 +98,18 @@ impl Punch { .send_main_udp(buf, SocketAddr::V4(nat_info.local_ipv4_addr)) .await; } - if !nat_info.ipv6_addr.ip().is_unspecified() && nat_info.ipv6_addr.port() != 0 { + if self.punch_model != PunchModel::IPv4 + && !nat_info.ipv6_addr.ip().is_unspecified() + && nat_info.ipv6_addr.port() != 0 + { let rs = self .context .send_main_udp(buf, SocketAddr::V6(nat_info.ipv6_addr)) .await; log::info!("发送到ipv6地址:{:?},rs={:?}", nat_info.ipv6_addr, rs); + if rs.is_ok() && self.punch_model == PunchModel::IPv6 { + return Ok(()); + } } match nat_info.nat_type { NatType::Symmetric => { diff --git a/vnt/src/core/mod.rs b/vnt/src/core/mod.rs index b8f2d23..5755dbe 100644 --- a/vnt/src/core/mod.rs +++ b/vnt/src/core/mod.rs @@ -12,7 +12,7 @@ use tokio::sync::mpsc::channel; use crate::channel::channel::{Channel, Context}; use crate::channel::idle::Idle; -use crate::channel::punch::{NatInfo, Punch}; +use crate::channel::punch::{NatInfo, Punch, PunchModel}; use crate::channel::sender::ChannelSender; use crate::channel::{Route, RouteKey}; use crate::cipher::{Cipher, CipherModel, RsaCipher}; @@ -164,14 +164,12 @@ impl VntUtil { Some(res) => res, }; let device_type = if self.config.tap { - #[cfg(windows)] { //删除tun网卡避免ip冲突,因为非正常退出会保留网卡 tun_tap_device::delete_device(tun_tap_device::DeviceType::Tun); } tun_tap_device::DeviceType::Tap } else { - #[cfg(windows)] { //删除tap网卡避免ip冲突,非正常退出会保留网卡 tun_tap_device::delete_device(tun_tap_device::DeviceType::Tap); @@ -253,7 +251,7 @@ impl VntUtil { current_device.clone(), 1, ); - let punch = Punch::new(context.clone()); + let punch = Punch::new(context.clone(), config.punch_model); let idle = Idle::new(Duration::from_secs(16), context.clone()); let channel_sender = ChannelSender::new(context.clone()); @@ -553,6 +551,7 @@ pub struct Config { pub parallel: usize, pub cipher_model: CipherModel, pub finger: bool, + pub punch_model: PunchModel, } impl Config { @@ -576,6 +575,7 @@ impl Config { parallel: usize, cipher_model: CipherModel, finger: bool, + punch_model: PunchModel, ) -> Self { for x in stun_server.iter_mut() { if !x.contains(":") { @@ -602,6 +602,7 @@ impl Config { parallel, cipher_model, finger, + punch_model, } } } diff --git a/vnt/src/handle/punch_handler.rs b/vnt/src/handle/punch_handler.rs index 4b5f39b..8483cf1 100644 --- a/vnt/src/handle/punch_handler.rs +++ b/vnt/src/handle/punch_handler.rs @@ -135,7 +135,8 @@ async fn start_punch_( current_device.virtual_ip(), &nat_info, info.virtual_ip, - )?; + ) + .unwrap(); let _ = sender .send_main(packet.buffer(), current_device.connect_server) .await;