调整默认网卡的逻辑
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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<LocalInterface> {
|
||||
match get_interface(dest_ip) {
|
||||
Ok(iface) => return Ok(iface),
|
||||
@@ -33,3 +34,7 @@ pub fn get_best_interface(dest_ip: Ipv4Addr) -> anyhow::Result<LocalInterface> {
|
||||
// 应该再查路由表找到默认路由的
|
||||
Ok(LocalInterface::default())
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
pub fn get_best_interface(dest_ip: Ipv4Addr) -> anyhow::Result<LocalInterface> {
|
||||
Ok(LocalInterface::default())
|
||||
}
|
||||
|
||||
+3
-12
@@ -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(
|
||||
|
||||
+13
-5
@@ -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<Ipv4Addr>,
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +173,7 @@ pub enum ErrorType {
|
||||
InvalidIp,
|
||||
LocalIpExists,
|
||||
FailedToCrateDevice,
|
||||
Warn,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@@ -186,6 +187,7 @@ impl Into<u8> for ErrorType {
|
||||
ErrorType::InvalidIp => 5,
|
||||
ErrorType::LocalIpExists => 6,
|
||||
ErrorType::FailedToCrateDevice => 101,
|
||||
ErrorType::Warn => 102,
|
||||
ErrorType::Unknown => 255,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Call: VntCallback>(
|
||||
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<Call: VntCallback>(
|
||||
pub fn domain_request0(
|
||||
current_device: &AtomicCell<CurrentDeviceInfo>,
|
||||
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 {:?}",
|
||||
|
||||
@@ -355,7 +355,10 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
|
||||
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(
|
||||
|
||||
@@ -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()?)?;
|
||||
|
||||
@@ -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<Arc<Device>, ErrorInfo> {
|
||||
pub fn create_device<Call: VntCallback>(
|
||||
config: DeviceConfig,
|
||||
call: &Call,
|
||||
) -> Result<Arc<Device>, ErrorInfo> {
|
||||
let device = match create_device0(&config) {
|
||||
Ok(device) => device,
|
||||
Err(e) => {
|
||||
@@ -44,7 +47,14 @@ pub fn create_device(config: DeviceConfig) -> Result<Arc<Device>, 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)
|
||||
|
||||
+36
-15
@@ -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<SocketAddr>) -> anyhow::Result<SocketAddr> {
|
||||
pub fn dns_query_all(
|
||||
domain: &str,
|
||||
mut name_servers: Vec<String>,
|
||||
default_interface: &LocalInterface,
|
||||
) -> anyhow::Result<Vec<SocketAddr>> {
|
||||
match SocketAddr::from_str(domain) {
|
||||
Ok(addr) => Ok(vec![addr]),
|
||||
@@ -102,7 +104,7 @@ pub fn dns_query_all(
|
||||
let mut err: Option<anyhow::Error> = 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<Vec<SocketAddr>> {
|
||||
pub fn txt_dns(
|
||||
domain: &str,
|
||||
name_server: String,
|
||||
default_interface: &LocalInterface,
|
||||
) -> anyhow::Result<Vec<SocketAddr>> {
|
||||
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<Vec<SocketAd
|
||||
Ok(rs)
|
||||
}
|
||||
|
||||
fn bind_udp(name_server: SocketAddr) -> anyhow::Result<UdpSocket> {
|
||||
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<UdpSocket> {
|
||||
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<Vec<Ipv4Addr>> {
|
||||
pub fn a_dns(
|
||||
domain: String,
|
||||
name_server: String,
|
||||
default_interface: &LocalInterface,
|
||||
) -> anyhow::Result<Vec<Ipv4Addr>> {
|
||||
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<Vec<Ipv4Addr
|
||||
Ok(rs)
|
||||
}
|
||||
|
||||
pub fn aaaa_dns(domain: String, name_server: String) -> anyhow::Result<Vec<Ipv6Addr>> {
|
||||
pub fn aaaa_dns(
|
||||
domain: String,
|
||||
name_server: String,
|
||||
default_interface: &LocalInterface,
|
||||
) -> anyhow::Result<Vec<Ipv6Addr>> {
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user