调整默认网卡的逻辑
This commit is contained in:
@@ -58,10 +58,14 @@ pub fn create_tcp0(
|
|||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
if v4 {
|
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 {
|
if bind_port != 0 {
|
||||||
socket.set_reuse_address(true)?;
|
socket
|
||||||
|
.set_reuse_address(true)
|
||||||
|
.context("set_reuse_address")?;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
if let Err(e) = socket.set_reuse_port(true) {
|
if let Err(e) = socket.set_reuse_port(true) {
|
||||||
log::warn!("set_reuse_port {:?}", e)
|
log::warn!("set_reuse_port {:?}", e)
|
||||||
@@ -90,7 +94,9 @@ pub fn bind_udp_ops(
|
|||||||
socket2::Type::DGRAM,
|
socket2::Type::DGRAM,
|
||||||
Some(Protocol::UDP),
|
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
|
socket
|
||||||
} else {
|
} else {
|
||||||
let socket = socket2::Socket::new(
|
let socket = socket2::Socket::new(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use crate::channel::socket::{get_interface, LocalInterface, VntSocketTrait};
|
|||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(target_os = "linux")]
|
||||||
impl VntSocketTrait for socket2::Socket {
|
impl VntSocketTrait for socket2::Socket {
|
||||||
fn set_ip_unicast_if(&self, interface: &LocalInterface) -> anyhow::Result<()> {
|
fn set_ip_unicast_if(&self, interface: &LocalInterface) -> anyhow::Result<()> {
|
||||||
if let Some(name) = &interface.name {
|
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> {
|
pub fn get_best_interface(dest_ip: Ipv4Addr) -> anyhow::Result<LocalInterface> {
|
||||||
match get_interface(dest_ip) {
|
match get_interface(dest_ip) {
|
||||||
Ok(iface) => return Ok(iface),
|
Ok(iface) => return Ok(iface),
|
||||||
@@ -33,3 +34,7 @@ pub fn get_best_interface(dest_ip: Ipv4Addr) -> anyhow::Result<LocalInterface> {
|
|||||||
// 应该再查路由表找到默认路由的
|
// 应该再查路由表找到默认路由的
|
||||||
Ok(LocalInterface::default())
|
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::idle::Idle;
|
||||||
use crate::channel::punch::{NatInfo, Punch};
|
use crate::channel::punch::{NatInfo, Punch};
|
||||||
use crate::channel::sender::IpPacketSender;
|
use crate::channel::sender::IpPacketSender;
|
||||||
use crate::channel::socket::LocalInterface;
|
|
||||||
use crate::channel::{init_channel, init_context, Route, RouteKey};
|
use crate::channel::{init_channel, init_context, Route, RouteKey};
|
||||||
use crate::cipher::Cipher;
|
use crate::cipher::Cipher;
|
||||||
#[cfg(feature = "server_encrypt")]
|
#[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::tun_tap_device::vnt_device::DeviceWrite;
|
||||||
use crate::util::limit::TrafficMeterMultiAddress;
|
use crate::util::limit::TrafficMeterMultiAddress;
|
||||||
use crate::util::{Scheduler, StopManager};
|
use crate::util::{Scheduler, StopManager};
|
||||||
use crate::{channel, nat, VntCallback};
|
use crate::{nat, VntCallback};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Vnt {
|
pub struct Vnt {
|
||||||
@@ -139,16 +138,8 @@ impl VntInner {
|
|||||||
nat::local_ipv4()
|
nat::local_ipv4()
|
||||||
};
|
};
|
||||||
|
|
||||||
let default_interface = if config.in_ips.is_empty() {
|
let default_interface = config.local_interface.clone();
|
||||||
//没有改变路由,不需要绑定网卡
|
log::info!("default_interface = {:?}", default_interface);
|
||||||
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 config_info = BaseConfigInfo::new(
|
let config_info = BaseConfigInfo::new(
|
||||||
|
|||||||
+13
-5
@@ -5,6 +5,7 @@ use std::str::FromStr;
|
|||||||
pub use conn::Vnt;
|
pub use conn::Vnt;
|
||||||
|
|
||||||
use crate::channel::punch::PunchModel;
|
use crate::channel::punch::PunchModel;
|
||||||
|
use crate::channel::socket::LocalInterface;
|
||||||
use crate::channel::{ConnectProtocol, UseChannelType};
|
use crate::channel::{ConnectProtocol, UseChannelType};
|
||||||
use crate::cipher::CipherModel;
|
use crate::cipher::CipherModel;
|
||||||
use crate::compression::Compressor;
|
use crate::compression::Compressor;
|
||||||
@@ -53,6 +54,7 @@ pub struct Config {
|
|||||||
pub enable_traffic: bool,
|
pub enable_traffic: bool,
|
||||||
pub allow_wire_guard: bool,
|
pub allow_wire_guard: bool,
|
||||||
pub local_ipv4: Option<Ipv4Addr>,
|
pub local_ipv4: Option<Ipv4Addr>,
|
||||||
|
pub local_interface: LocalInterface,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@@ -148,8 +150,11 @@ impl Config {
|
|||||||
server_address_str = s.to_string();
|
server_address_str = s.to_string();
|
||||||
protocol = ConnectProtocol::TCP;
|
protocol = ConnectProtocol::TCP;
|
||||||
}
|
}
|
||||||
server_address =
|
server_address = address_choose(dns_query_all(
|
||||||
address_choose(dns_query_all(&server_address_str, name_servers.clone())?)?;
|
&server_address_str,
|
||||||
|
name_servers.clone(),
|
||||||
|
&LocalInterface::default(),
|
||||||
|
)?)?;
|
||||||
}
|
}
|
||||||
#[cfg(feature = "port_mapping")]
|
#[cfg(feature = "port_mapping")]
|
||||||
let port_mapping_list = crate::port_mapping::convert(port_mapping_list)?;
|
let port_mapping_list = crate::port_mapping::convert(port_mapping_list)?;
|
||||||
@@ -158,9 +163,11 @@ impl Config {
|
|||||||
*dest = *mask & *dest;
|
*dest = *mask & *dest;
|
||||||
}
|
}
|
||||||
in_ips.sort_by(|(dest1, _, _), (dest2, _, _)| dest2.cmp(dest1));
|
in_ips.sort_by(|(dest1, _, _), (dest2, _, _)| dest2.cmp(dest1));
|
||||||
if let Some(local_ip) = local_ipv4 {
|
let local_interface = if let Some(local_ip) = local_ipv4 {
|
||||||
let _ = crate::channel::socket::get_interface(local_ip)?;
|
crate::channel::socket::get_interface(local_ip)?
|
||||||
}
|
} else {
|
||||||
|
LocalInterface::default()
|
||||||
|
};
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
#[cfg(feature = "integrated_tun")]
|
#[cfg(feature = "integrated_tun")]
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@@ -199,6 +206,7 @@ impl Config {
|
|||||||
enable_traffic,
|
enable_traffic,
|
||||||
allow_wire_guard,
|
allow_wire_guard,
|
||||||
local_ipv4,
|
local_ipv4,
|
||||||
|
local_interface,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ pub enum ErrorType {
|
|||||||
InvalidIp,
|
InvalidIp,
|
||||||
LocalIpExists,
|
LocalIpExists,
|
||||||
FailedToCrateDevice,
|
FailedToCrateDevice,
|
||||||
|
Warn,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,6 +187,7 @@ impl Into<u8> for ErrorType {
|
|||||||
ErrorType::InvalidIp => 5,
|
ErrorType::InvalidIp => 5,
|
||||||
ErrorType::LocalIpExists => 6,
|
ErrorType::LocalIpExists => 6,
|
||||||
ErrorType::FailedToCrateDevice => 101,
|
ErrorType::FailedToCrateDevice => 101,
|
||||||
|
ErrorType::Warn => 102,
|
||||||
ErrorType::Unknown => 255,
|
ErrorType::Unknown => 255,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use crossbeam_utils::atomic::AtomicCell;
|
|||||||
use crate::channel::context::ChannelContext;
|
use crate::channel::context::ChannelContext;
|
||||||
use crate::channel::idle::{Idle, IdleType};
|
use crate::channel::idle::{Idle, IdleType};
|
||||||
use crate::channel::sender::ConnectUtil;
|
use crate::channel::sender::ConnectUtil;
|
||||||
|
use crate::channel::socket::LocalInterface;
|
||||||
use crate::channel::ConnectProtocol;
|
use crate::channel::ConnectProtocol;
|
||||||
use crate::handle::callback::{ConnectInfo, ErrorType};
|
use crate::handle::callback::{ConnectInfo, ErrorType};
|
||||||
use crate::handle::handshaker::Handshake;
|
use crate::handle::handshaker::Handshake;
|
||||||
@@ -130,7 +131,8 @@ fn check_gateway_channel<Call: VntCallback>(
|
|||||||
let connect_protocol = context.main_protocol();
|
let connect_protocol = context.main_protocol();
|
||||||
if connect_protocol.is_transport() {
|
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));
|
call.connect(ConnectInfo::new(*count, current_device.connect_server));
|
||||||
@@ -160,11 +162,16 @@ fn check_gateway_channel<Call: VntCallback>(
|
|||||||
pub fn domain_request0(
|
pub fn domain_request0(
|
||||||
current_device: &AtomicCell<CurrentDeviceInfo>,
|
current_device: &AtomicCell<CurrentDeviceInfo>,
|
||||||
config: &BaseConfigInfo,
|
config: &BaseConfigInfo,
|
||||||
|
default_interface: &LocalInterface,
|
||||||
) -> CurrentDeviceInfo {
|
) -> CurrentDeviceInfo {
|
||||||
let mut current_dev = current_device.load();
|
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) => {
|
Ok(addrs) => {
|
||||||
log::info!(
|
log::info!(
|
||||||
"domain {} dns {:?} addr {:?}",
|
"domain {} dns {:?} addr {:?}",
|
||||||
|
|||||||
@@ -355,7 +355,10 @@ impl<Call: VntCallback, Device: DeviceWrite> ServerPacketHandler<Call, Device> {
|
|||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "macos"
|
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) => {
|
Ok(device) => {
|
||||||
use tun::device::IFace;
|
use tun::device::IFace;
|
||||||
let tun_info = crate::handle::callback::DeviceInfo::new(
|
let tun_info = crate::handle::callback::DeviceInfo::new(
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ impl IcmpProxy {
|
|||||||
.bind(&socket2::SockAddr::from(addr))
|
.bind(&socket2::SockAddr::from(addr))
|
||||||
.context("bind Socket ICMPV4 failed")?;
|
.context("bind Socket ICMPV4 failed")?;
|
||||||
icmp_socket.set_nonblocking(true)?;
|
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 std_socket: std::net::UdpSocket = icmp_socket.into();
|
||||||
|
|
||||||
let tokio_icmp_socket = UdpSocket::from_std(std_socket.try_clone()?)?;
|
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::io;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -10,7 +10,10 @@ const DEFAULT_TUN_NAME: &str = "vnt-tun";
|
|||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
const DEFAULT_TAP_NAME: &str = "vnt-tap";
|
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) {
|
let device = match create_device0(&config) {
|
||||||
Ok(device) => device,
|
Ok(device) => device,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -44,7 +47,14 @@ pub fn create_device(config: DeviceConfig) -> Result<Arc<Device>, ErrorInfo> {
|
|||||||
|
|
||||||
for (dest, mask) in config.external_route {
|
for (dest, mask) in config.external_route {
|
||||||
if let Err(e) = device.add_route(dest, mask, 1) {
|
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)
|
Ok(device)
|
||||||
|
|||||||
+36
-15
@@ -5,6 +5,7 @@ use std::str::FromStr;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
|
|
||||||
|
use crate::channel::socket::LocalInterface;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use dns_parser::{Builder, Packet, QueryClass, QueryType, RData, ResponseCode};
|
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(
|
pub fn dns_query_all(
|
||||||
domain: &str,
|
domain: &str,
|
||||||
mut name_servers: Vec<String>,
|
mut name_servers: Vec<String>,
|
||||||
|
default_interface: &LocalInterface,
|
||||||
) -> anyhow::Result<Vec<SocketAddr>> {
|
) -> anyhow::Result<Vec<SocketAddr>> {
|
||||||
match SocketAddr::from_str(domain) {
|
match SocketAddr::from_str(domain) {
|
||||||
Ok(addr) => Ok(vec![addr]),
|
Ok(addr) => Ok(vec![addr]),
|
||||||
@@ -102,7 +104,7 @@ pub fn dns_query_all(
|
|||||||
let mut err: Option<anyhow::Error> = None;
|
let mut err: Option<anyhow::Error> = None;
|
||||||
for name_server in name_servers {
|
for name_server in name_servers {
|
||||||
if let Some(domain) = txt_domain.as_ref() {
|
if let Some(domain) = txt_domain.as_ref() {
|
||||||
match txt_dns(domain, name_server) {
|
match txt_dns(domain, name_server, default_interface) {
|
||||||
Ok(addr) => {
|
Ok(addr) => {
|
||||||
if !addr.is_empty() {
|
if !addr.is_empty() {
|
||||||
return Ok(addr);
|
return Ok(addr);
|
||||||
@@ -127,12 +129,14 @@ pub fn dns_query_all(
|
|||||||
let th1 = {
|
let th1 = {
|
||||||
let host = host.to_string();
|
let host = host.to_string();
|
||||||
let name_server = name_server.clone();
|
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 th2 = {
|
||||||
let host = host.to_string();
|
let host = host.to_string();
|
||||||
let name_server = name_server.clone();
|
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();
|
let mut addr = Vec::new();
|
||||||
match th1.join().unwrap() {
|
match th1.join().unwrap() {
|
||||||
@@ -230,9 +234,13 @@ fn query<'a>(
|
|||||||
Ok(pkt)
|
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 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 mut buf = [0; 65536];
|
||||||
let message = query(&udp, domain, name_server, QueryType::TXT, &mut buf)?;
|
let message = query(&udp, domain, name_server, QueryType::TXT, &mut buf)?;
|
||||||
let mut rs = Vec::new();
|
let mut rs = Vec::new();
|
||||||
@@ -249,19 +257,28 @@ pub fn txt_dns(domain: &str, name_server: String) -> anyhow::Result<Vec<SocketAd
|
|||||||
Ok(rs)
|
Ok(rs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_udp(name_server: SocketAddr) -> anyhow::Result<UdpSocket> {
|
fn bind_udp(
|
||||||
let udp = if name_server.is_ipv4() {
|
name_server: SocketAddr,
|
||||||
UdpSocket::bind("0.0.0.0:0")?
|
default_interface: &LocalInterface,
|
||||||
|
) -> anyhow::Result<UdpSocket> {
|
||||||
|
let addr: SocketAddr = if name_server.is_ipv4() {
|
||||||
|
"0.0.0.0:0".parse().unwrap()
|
||||||
} else {
|
} else {
|
||||||
UdpSocket::bind("[::]:0")?
|
"[::]:0".parse().unwrap()
|
||||||
};
|
};
|
||||||
udp.set_read_timeout(Some(Duration::from_millis(800)))?;
|
let socket = crate::channel::socket::bind_udp(addr, default_interface)?;
|
||||||
Ok(udp)
|
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 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 mut buf = [0; 65536];
|
||||||
let message = query(&udp, &domain, name_server, QueryType::A, &mut buf)?;
|
let message = query(&udp, &domain, name_server, QueryType::A, &mut buf)?;
|
||||||
let mut rs = Vec::new();
|
let mut rs = Vec::new();
|
||||||
@@ -273,9 +290,13 @@ pub fn a_dns(domain: String, name_server: String) -> anyhow::Result<Vec<Ipv4Addr
|
|||||||
Ok(rs)
|
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 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 mut buf = [0; 65536];
|
||||||
let message = query(&udp, &domain, name_server, QueryType::AAAA, &mut buf)?;
|
let message = query(&udp, &domain, name_server, QueryType::AAAA, &mut buf)?;
|
||||||
let mut rs = Vec::new();
|
let mut rs = Vec::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user