diff --git a/vnt/src/channel/socket/mod.rs b/vnt/src/channel/socket/mod.rs index dd854cd..55e495f 100644 --- a/vnt/src/channel/socket/mod.rs +++ b/vnt/src/channel/socket/mod.rs @@ -58,10 +58,14 @@ pub fn create_tcp0( )? }; if v4 { - socket.set_ip_unicast_if(default_interface)?; + if let Err(e) = socket.set_ip_unicast_if(default_interface) { + log::warn!("set_ip_unicast_if {:?}", e) + } } if bind_port != 0 { - socket.set_reuse_address(true)?; + socket + .set_reuse_address(true) + .context("set_reuse_address")?; #[cfg(unix)] if let Err(e) = socket.set_reuse_port(true) { log::warn!("set_reuse_port {:?}", e) @@ -90,7 +94,9 @@ pub fn bind_udp_ops( socket2::Type::DGRAM, Some(Protocol::UDP), )?; - socket.set_ip_unicast_if(default_interface)?; + if let Err(e) = socket.set_ip_unicast_if(default_interface) { + log::warn!("set_ip_unicast_if {:?}", e) + } socket } else { let socket = socket2::Socket::new( diff --git a/vnt/src/channel/socket/unix.rs b/vnt/src/channel/socket/unix.rs index d638cf6..cea3262 100644 --- a/vnt/src/channel/socket/unix.rs +++ b/vnt/src/channel/socket/unix.rs @@ -2,7 +2,7 @@ use crate::channel::socket::{get_interface, LocalInterface, VntSocketTrait}; use anyhow::Context; use std::net::Ipv4Addr; -#[cfg(any(target_os = "linux", target_os = "android"))] +#[cfg(target_os = "linux")] impl VntSocketTrait for socket2::Socket { fn set_ip_unicast_if(&self, interface: &LocalInterface) -> anyhow::Result<()> { if let Some(name) = &interface.name { @@ -23,6 +23,7 @@ impl VntSocketTrait for socket2::Socket { } } +#[cfg(any(target_os = "linux", target_os = "macos"))] pub fn get_best_interface(dest_ip: Ipv4Addr) -> anyhow::Result { match get_interface(dest_ip) { Ok(iface) => return Ok(iface), @@ -33,3 +34,7 @@ pub fn get_best_interface(dest_ip: Ipv4Addr) -> anyhow::Result { // 应该再查路由表找到默认路由的 Ok(LocalInterface::default()) } +#[cfg(target_os = "android")] +pub fn get_best_interface(dest_ip: Ipv4Addr) -> anyhow::Result { + Ok(LocalInterface::default()) +} diff --git a/vnt/src/core/conn.rs b/vnt/src/core/conn.rs index a2e749d..5aa4755 100644 --- a/vnt/src/core/conn.rs +++ b/vnt/src/core/conn.rs @@ -12,7 +12,6 @@ use crate::channel::context::ChannelContext; use crate::channel::idle::Idle; use crate::channel::punch::{NatInfo, Punch}; use crate::channel::sender::IpPacketSender; -use crate::channel::socket::LocalInterface; use crate::channel::{init_channel, init_context, Route, RouteKey}; use crate::cipher::Cipher; #[cfg(feature = "server_encrypt")] @@ -30,7 +29,7 @@ use crate::tun_tap_device::tun_create_helper::{DeviceAdapter, TunDeviceHelper}; use crate::tun_tap_device::vnt_device::DeviceWrite; use crate::util::limit::TrafficMeterMultiAddress; use crate::util::{Scheduler, StopManager}; -use crate::{channel, nat, VntCallback}; +use crate::{nat, VntCallback}; #[derive(Clone)] pub struct Vnt { @@ -139,16 +138,8 @@ impl VntInner { nat::local_ipv4() }; - let default_interface = if config.in_ips.is_empty() { - //没有改变路由,不需要绑定网卡 - LocalInterface::default() - } else { - //vnt的流量都走这个接口 - let default_interface = - channel::socket::get_best_interface(local_ipv4.unwrap_or(Ipv4Addr::UNSPECIFIED))?; - log::info!("default_interface = {:?}", default_interface); - default_interface - }; + let default_interface = config.local_interface.clone(); + log::info!("default_interface = {:?}", default_interface); //基础信息 let config_info = BaseConfigInfo::new( diff --git a/vnt/src/core/mod.rs b/vnt/src/core/mod.rs index 8477584..89a578b 100644 --- a/vnt/src/core/mod.rs +++ b/vnt/src/core/mod.rs @@ -5,6 +5,7 @@ use std::str::FromStr; pub use conn::Vnt; use crate::channel::punch::PunchModel; +use crate::channel::socket::LocalInterface; use crate::channel::{ConnectProtocol, UseChannelType}; use crate::cipher::CipherModel; use crate::compression::Compressor; @@ -53,6 +54,7 @@ pub struct Config { pub enable_traffic: bool, pub allow_wire_guard: bool, pub local_ipv4: Option, + pub local_interface: LocalInterface, } impl Config { @@ -148,8 +150,11 @@ impl Config { server_address_str = s.to_string(); protocol = ConnectProtocol::TCP; } - server_address = - address_choose(dns_query_all(&server_address_str, name_servers.clone())?)?; + server_address = address_choose(dns_query_all( + &server_address_str, + name_servers.clone(), + &LocalInterface::default(), + )?)?; } #[cfg(feature = "port_mapping")] let port_mapping_list = crate::port_mapping::convert(port_mapping_list)?; @@ -158,9 +163,11 @@ impl Config { *dest = *mask & *dest; } in_ips.sort_by(|(dest1, _, _), (dest2, _, _)| dest2.cmp(dest1)); - if let Some(local_ip) = local_ipv4 { - let _ = crate::channel::socket::get_interface(local_ip)?; - } + let local_interface = if let Some(local_ip) = local_ipv4 { + crate::channel::socket::get_interface(local_ip)? + } else { + LocalInterface::default() + }; Ok(Self { #[cfg(feature = "integrated_tun")] #[cfg(target_os = "windows")] @@ -199,6 +206,7 @@ impl Config { enable_traffic, allow_wire_guard, local_ipv4, + local_interface, }) } } diff --git a/vnt/src/handle/callback.rs b/vnt/src/handle/callback.rs index d0bf8a7..7f32eb4 100644 --- a/vnt/src/handle/callback.rs +++ b/vnt/src/handle/callback.rs @@ -173,6 +173,7 @@ pub enum ErrorType { InvalidIp, LocalIpExists, FailedToCrateDevice, + Warn, Unknown, } @@ -186,6 +187,7 @@ impl Into for ErrorType { ErrorType::InvalidIp => 5, ErrorType::LocalIpExists => 6, ErrorType::FailedToCrateDevice => 101, + ErrorType::Warn => 102, ErrorType::Unknown => 255, } } diff --git a/vnt/src/handle/maintain/idle.rs b/vnt/src/handle/maintain/idle.rs index d610018..f36a26a 100644 --- a/vnt/src/handle/maintain/idle.rs +++ b/vnt/src/handle/maintain/idle.rs @@ -7,6 +7,7 @@ use crossbeam_utils::atomic::AtomicCell; use crate::channel::context::ChannelContext; use crate::channel::idle::{Idle, IdleType}; use crate::channel::sender::ConnectUtil; +use crate::channel::socket::LocalInterface; use crate::channel::ConnectProtocol; use crate::handle::callback::{ConnectInfo, ErrorType}; use crate::handle::handshaker::Handshake; @@ -130,7 +131,8 @@ fn check_gateway_channel( let connect_protocol = context.main_protocol(); if connect_protocol.is_transport() { // 传输层的协议需要探测服务器地址 - current_device = domain_request0(current_device_info, config); + current_device = + domain_request0(current_device_info, config, context.default_interface()); } //需要重连 call.connect(ConnectInfo::new(*count, current_device.connect_server)); @@ -160,11 +162,16 @@ fn check_gateway_channel( pub fn domain_request0( current_device: &AtomicCell, config: &BaseConfigInfo, + default_interface: &LocalInterface, ) -> CurrentDeviceInfo { let mut current_dev = current_device.load(); // 探测服务端地址变化 - match dns_query_all(&config.server_addr, config.name_servers.clone()) { + match dns_query_all( + &config.server_addr, + config.name_servers.clone(), + default_interface, + ) { Ok(addrs) => { log::info!( "domain {} dns {:?} addr {:?}", diff --git a/vnt/src/handle/recv_data/server.rs b/vnt/src/handle/recv_data/server.rs index b1bb37b..c3adf7b 100644 --- a/vnt/src/handle/recv_data/server.rs +++ b/vnt/src/handle/recv_data/server.rs @@ -355,7 +355,10 @@ impl ServerPacketHandler { target_os = "linux", target_os = "macos" ))] - match crate::tun_tap_device::create_device(device_config) { + match crate::tun_tap_device::create_device( + device_config, + &self.callback, + ) { Ok(device) => { use tun::device::IFace; let tun_info = crate::handle::callback::DeviceInfo::new( diff --git a/vnt/src/ip_proxy/icmp_proxy.rs b/vnt/src/ip_proxy/icmp_proxy.rs index 60353df..9afca4b 100644 --- a/vnt/src/ip_proxy/icmp_proxy.rs +++ b/vnt/src/ip_proxy/icmp_proxy.rs @@ -52,7 +52,9 @@ impl IcmpProxy { .bind(&socket2::SockAddr::from(addr)) .context("bind Socket ICMPV4 failed")?; icmp_socket.set_nonblocking(true)?; - icmp_socket.set_ip_unicast_if(default_interface)?; + if let Err(e) = icmp_socket.set_ip_unicast_if(default_interface) { + log::warn!("set_ip_unicast_if {:?}", e) + } let std_socket: std::net::UdpSocket = icmp_socket.into(); let tokio_icmp_socket = UdpSocket::from_std(std_socket.try_clone()?)?; diff --git a/vnt/src/tun_tap_device/create_device.rs b/vnt/src/tun_tap_device/create_device.rs index 652fd7e..2514c47 100644 --- a/vnt/src/tun_tap_device/create_device.rs +++ b/vnt/src/tun_tap_device/create_device.rs @@ -1,4 +1,4 @@ -use crate::{DeviceConfig, ErrorInfo, ErrorType}; +use crate::{DeviceConfig, ErrorInfo, ErrorType, VntCallback}; use std::io; use std::net::Ipv4Addr; use std::sync::Arc; @@ -10,7 +10,10 @@ const DEFAULT_TUN_NAME: &str = "vnt-tun"; #[cfg(target_os = "windows")] const DEFAULT_TAP_NAME: &str = "vnt-tap"; -pub fn create_device(config: DeviceConfig) -> Result, ErrorInfo> { +pub fn create_device( + config: DeviceConfig, + call: &Call, +) -> Result, ErrorInfo> { let device = match create_device0(&config) { Ok(device) => device, Err(e) => { @@ -44,7 +47,14 @@ pub fn create_device(config: DeviceConfig) -> Result, ErrorInfo> { for (dest, mask) in config.external_route { if let Err(e) = device.add_route(dest, mask, 1) { - log::warn!("添加路由失败 ={:?}", e); + log::warn!("添加路由失败,请检查-i参数是否和现有路由冲突 ={:?}", e); + call.error(ErrorInfo::new_msg( + ErrorType::Warn, + format!( + "警告! 添加路由失败,请检查-i参数是否和现有路由冲突 ={:?}", + e + ), + )) } } Ok(device) diff --git a/vnt/src/util/dns_query.rs b/vnt/src/util/dns_query.rs index 4b7300c..04314f3 100644 --- a/vnt/src/util/dns_query.rs +++ b/vnt/src/util/dns_query.rs @@ -5,6 +5,7 @@ use std::str::FromStr; use std::time::Duration; use std::{io, thread}; +use crate::channel::socket::LocalInterface; use anyhow::Context; use dns_parser::{Builder, Packet, QueryClass, QueryType, RData, ResponseCode}; @@ -79,6 +80,7 @@ fn address_choose0(addrs: Vec) -> anyhow::Result { pub fn dns_query_all( domain: &str, mut name_servers: Vec, + default_interface: &LocalInterface, ) -> anyhow::Result> { match SocketAddr::from_str(domain) { Ok(addr) => Ok(vec![addr]), @@ -102,7 +104,7 @@ pub fn dns_query_all( let mut err: Option = None; for name_server in name_servers { if let Some(domain) = txt_domain.as_ref() { - match txt_dns(domain, name_server) { + match txt_dns(domain, name_server, default_interface) { Ok(addr) => { if !addr.is_empty() { return Ok(addr); @@ -127,12 +129,14 @@ pub fn dns_query_all( let th1 = { let host = host.to_string(); let name_server = name_server.clone(); - thread::spawn(move || a_dns(host, name_server)) + let default_interface = default_interface.clone(); + thread::spawn(move || a_dns(host, name_server, &default_interface)) }; let th2 = { let host = host.to_string(); let name_server = name_server.clone(); - thread::spawn(move || aaaa_dns(host, name_server)) + let default_interface = default_interface.clone(); + thread::spawn(move || aaaa_dns(host, name_server, &default_interface)) }; let mut addr = Vec::new(); match th1.join().unwrap() { @@ -230,9 +234,13 @@ fn query<'a>( Ok(pkt) } -pub fn txt_dns(domain: &str, name_server: String) -> anyhow::Result> { +pub fn txt_dns( + domain: &str, + name_server: String, + default_interface: &LocalInterface, +) -> anyhow::Result> { let name_server: SocketAddr = name_server.parse()?; - let udp = bind_udp(name_server)?; + let udp = bind_udp(name_server, default_interface)?; let mut buf = [0; 65536]; let message = query(&udp, domain, name_server, QueryType::TXT, &mut buf)?; let mut rs = Vec::new(); @@ -249,19 +257,28 @@ pub fn txt_dns(domain: &str, name_server: String) -> anyhow::Result anyhow::Result { - let udp = if name_server.is_ipv4() { - UdpSocket::bind("0.0.0.0:0")? +fn bind_udp( + name_server: SocketAddr, + default_interface: &LocalInterface, +) -> anyhow::Result { + let addr: SocketAddr = if name_server.is_ipv4() { + "0.0.0.0:0".parse().unwrap() } else { - UdpSocket::bind("[::]:0")? + "[::]:0".parse().unwrap() }; - udp.set_read_timeout(Some(Duration::from_millis(800)))?; - Ok(udp) + let socket = crate::channel::socket::bind_udp(addr, default_interface)?; + socket.set_nonblocking(false)?; + socket.set_read_timeout(Some(Duration::from_millis(800)))?; + Ok(socket.into()) } -pub fn a_dns(domain: String, name_server: String) -> anyhow::Result> { +pub fn a_dns( + domain: String, + name_server: String, + default_interface: &LocalInterface, +) -> anyhow::Result> { let name_server: SocketAddr = name_server.parse()?; - let udp = bind_udp(name_server)?; + let udp = bind_udp(name_server, default_interface)?; let mut buf = [0; 65536]; let message = query(&udp, &domain, name_server, QueryType::A, &mut buf)?; let mut rs = Vec::new(); @@ -273,9 +290,13 @@ pub fn a_dns(domain: String, name_server: String) -> anyhow::Result anyhow::Result> { +pub fn aaaa_dns( + domain: String, + name_server: String, + default_interface: &LocalInterface, +) -> anyhow::Result> { let name_server: SocketAddr = name_server.parse()?; - let udp = bind_udp(name_server)?; + let udp = bind_udp(name_server, default_interface)?; let mut buf = [0; 65536]; let message = query(&udp, &domain, name_server, QueryType::AAAA, &mut buf)?; let mut rs = Vec::new();