支持指定dns
This commit is contained in:
@@ -121,6 +121,8 @@ first_latency: false #是否优先低延迟通道,默认为false,表示优
|
|||||||
device_name: vnt-tun #网卡名称
|
device_name: vnt-tun #网卡名称
|
||||||
packet_loss: 0 #指定丢包率 取值0~1之间的数 用于模拟弱网
|
packet_loss: 0 #指定丢包率 取值0~1之间的数 用于模拟弱网
|
||||||
packet_delay: 0 #指定延迟 单位毫秒 用于模拟弱网
|
packet_delay: 0 #指定延迟 单位毫秒 用于模拟弱网
|
||||||
|
dns:
|
||||||
|
- 8.8.8.8:53
|
||||||
```
|
```
|
||||||
|
|
||||||
或者需要哪个配置就加哪个,当然token是必须的
|
或者需要哪个配置就加哪个,当然token是必须的
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::net::{Ipv4Addr, ToSocketAddrs};
|
use std::net::Ipv4Addr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -19,6 +19,7 @@ pub struct FileConfig {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub server_address: String,
|
pub server_address: String,
|
||||||
pub stun_server: Vec<String>,
|
pub stun_server: Vec<String>,
|
||||||
|
pub dns: Vec<String>,
|
||||||
pub in_ips: Vec<String>,
|
pub in_ips: Vec<String>,
|
||||||
pub out_ips: Vec<String>,
|
pub out_ips: Vec<String>,
|
||||||
pub password: Option<String>,
|
pub password: Option<String>,
|
||||||
@@ -55,6 +56,7 @@ impl Default for FileConfig {
|
|||||||
"stun2.l.google.com:19302".to_string(),
|
"stun2.l.google.com:19302".to_string(),
|
||||||
"stun.qq.com:3478".to_string(),
|
"stun.qq.com:3478".to_string(),
|
||||||
],
|
],
|
||||||
|
dns: vec![],
|
||||||
in_ips: vec![],
|
in_ips: vec![],
|
||||||
out_ips: vec![],
|
out_ips: vec![],
|
||||||
password: None,
|
password: None,
|
||||||
@@ -91,24 +93,7 @@ pub fn read_config(file_path: &str) -> io::Result<(Config, bool)> {
|
|||||||
if file_conf.token.is_empty() {
|
if file_conf.token.is_empty() {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "token is_empty"));
|
return Err(io::Error::new(io::ErrorKind::Other, "token is_empty"));
|
||||||
}
|
}
|
||||||
let server_address = match file_conf.server_address.to_socket_addrs() {
|
|
||||||
Ok(mut addr) => {
|
|
||||||
if let Some(addr) = addr.next() {
|
|
||||||
addr
|
|
||||||
} else {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("server_address {:?} error", &file_conf.server_address),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("server_address {:?} error:{}", &file_conf.server_address, e),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let in_ips = match common::args_parse::ips_parse(&file_conf.in_ips) {
|
let in_ips = match common::args_parse::ips_parse(&file_conf.in_ips) {
|
||||||
Ok(in_ips) => in_ips,
|
Ok(in_ips) => in_ips,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -150,8 +135,8 @@ pub fn read_config(file_path: &str) -> io::Result<(Config, bool)> {
|
|||||||
file_conf.token,
|
file_conf.token,
|
||||||
file_conf.device_id,
|
file_conf.device_id,
|
||||||
file_conf.name,
|
file_conf.name,
|
||||||
server_address,
|
|
||||||
file_conf.server_address,
|
file_conf.server_address,
|
||||||
|
file_conf.dns,
|
||||||
file_conf.stun_server,
|
file_conf.stun_server,
|
||||||
in_ips,
|
in_ips,
|
||||||
out_ips,
|
out_ips,
|
||||||
|
|||||||
+7
-18
@@ -1,4 +1,4 @@
|
|||||||
use std::net::{Ipv4Addr, ToSocketAddrs};
|
use std::net::Ipv4Addr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::{io, thread};
|
use std::{io, thread};
|
||||||
@@ -72,6 +72,7 @@ fn main() {
|
|||||||
opts.optopt("", "use-channel", "使用通道 relay/p2p", "<use-channel>");
|
opts.optopt("", "use-channel", "使用通道 relay/p2p", "<use-channel>");
|
||||||
opts.optopt("", "packet-loss", "丢包率", "<packet-loss>");
|
opts.optopt("", "packet-loss", "丢包率", "<packet-loss>");
|
||||||
opts.optopt("", "packet-delay", "延迟", "<packet-delay>");
|
opts.optopt("", "packet-delay", "延迟", "<packet-delay>");
|
||||||
|
opts.optmulti("", "dns", "dns", "<dns>");
|
||||||
opts.optopt("f", "", "配置文件", "<conf>");
|
opts.optopt("f", "", "配置文件", "<conf>");
|
||||||
//"后台运行时,查看其他设备列表"
|
//"后台运行时,查看其他设备列表"
|
||||||
opts.optflag("", "list", "后台运行时,查看其他设备列表");
|
opts.optflag("", "list", "后台运行时,查看其他设备列表");
|
||||||
@@ -150,27 +151,14 @@ fn main() {
|
|||||||
let server_address_str = matches
|
let server_address_str = matches
|
||||||
.opt_get_default("s", "nat1.wherewego.top:29872".to_string())
|
.opt_get_default("s", "nat1.wherewego.top:29872".to_string())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let server_address = match server_address_str.to_socket_addrs() {
|
|
||||||
Ok(mut addr) => {
|
|
||||||
if let Some(addr) = addr.next() {
|
|
||||||
addr
|
|
||||||
} else {
|
|
||||||
println!("parameter '-s {}' error .", server_address_str);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
println!("parameter '-s {}' error {}.", server_address_str, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut stun_server = matches.opt_strs("e");
|
let mut stun_server = matches.opt_strs("e");
|
||||||
if stun_server.is_empty() {
|
if stun_server.is_empty() {
|
||||||
stun_server.push("stun1.l.google.com:19302".to_string());
|
stun_server.push("stun1.l.google.com:19302".to_string());
|
||||||
stun_server.push("stun2.l.google.com:19302".to_string());
|
stun_server.push("stun2.l.google.com:19302".to_string());
|
||||||
stun_server.push("stun.qq.com:3478".to_string());
|
stun_server.push("stun.qq.com:3478".to_string());
|
||||||
}
|
}
|
||||||
|
let dns = matches.opt_strs("dns");
|
||||||
let in_ip = matches.opt_strs("i");
|
let in_ip = matches.opt_strs("i");
|
||||||
let in_ip = match ips_parse(&in_ip) {
|
let in_ip = match ips_parse(&in_ip) {
|
||||||
Ok(in_ip) => in_ip,
|
Ok(in_ip) => in_ip,
|
||||||
@@ -305,8 +293,8 @@ fn main() {
|
|||||||
token,
|
token,
|
||||||
device_id,
|
device_id,
|
||||||
name,
|
name,
|
||||||
server_address,
|
|
||||||
server_address_str,
|
server_address_str,
|
||||||
|
dns,
|
||||||
stun_server,
|
stun_server,
|
||||||
in_ip,
|
in_ip,
|
||||||
out_ip,
|
out_ip,
|
||||||
@@ -423,7 +411,7 @@ fn print_usage(program: &str, _opts: Options) {
|
|||||||
);
|
);
|
||||||
println!(" -n <name> 给设备一个名字,便于区分不同设备,默认使用系统版本");
|
println!(" -n <name> 给设备一个名字,便于区分不同设备,默认使用系统版本");
|
||||||
println!(" -d <id> 设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复");
|
println!(" -d <id> 设备唯一标识符,不使用--ip参数时,服务端凭此参数分配虚拟ip,注意不能重复");
|
||||||
println!(" -s <server> 注册和中继服务器地址");
|
println!(" -s <server> 注册和中继服务器地址,以'TXT:'开头表示解析TXT记录");
|
||||||
println!(" -e <stun-server> stun服务器,用于探测NAT类型,可多次指定,如-e addr1 -e addr2");
|
println!(" -e <stun-server> stun服务器,用于探测NAT类型,可多次指定,如-e addr1 -e addr2");
|
||||||
println!(" -a 使用tap模式,默认使用tun模式");
|
println!(" -a 使用tap模式,默认使用tun模式");
|
||||||
println!(" -i <in-ip> 配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据");
|
println!(" -i <in-ip> 配置点对网(IP代理)时使用,-i 192.168.0.0/24,10.26.0.3表示允许接收网段192.168.0.0/24的数据");
|
||||||
@@ -486,6 +474,7 @@ fn print_usage(program: &str, _opts: Options) {
|
|||||||
println!(
|
println!(
|
||||||
" --packet-delay <0> 模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网"
|
" --packet-delay <0> 模拟延迟,整数,单位毫秒(ms),程序会按设定的值延迟发包,可用于模拟弱网"
|
||||||
);
|
);
|
||||||
|
println!(" --dns <host:port> DNS服务器地址,可使用多个dns,默认使用8.8.8.8:53");
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
println!(
|
println!(
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ public class Config {
|
|||||||
* 服务端地址
|
* 服务端地址
|
||||||
*/
|
*/
|
||||||
private String server;
|
private String server;
|
||||||
|
/**
|
||||||
|
* 服务端地址
|
||||||
|
*/
|
||||||
|
private String[] dns;
|
||||||
/**
|
/**
|
||||||
* stun服务地址
|
* stun服务地址
|
||||||
*/
|
*/
|
||||||
|
|||||||
+2
-20
@@ -21,6 +21,7 @@ pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
|
|||||||
let password = to_string(env, &config, "password")?;
|
let password = to_string(env, &config, "password")?;
|
||||||
let server_address_str = to_string_not_null(env, &config, "server")?;
|
let server_address_str = to_string_not_null(env, &config, "server")?;
|
||||||
let stun_server = to_string_array_not_null(env, &config, "stunServer")?;
|
let stun_server = to_string_array_not_null(env, &config, "stunServer")?;
|
||||||
|
let dns = to_string_array_not_null(env, &config, "dns")?;
|
||||||
let cipher_model = to_string_not_null(env, &config, "cipherModel")?;
|
let cipher_model = to_string_not_null(env, &config, "cipherModel")?;
|
||||||
let punch_model = to_string(env, &config, "punchModel")?;
|
let punch_model = to_string(env, &config, "punchModel")?;
|
||||||
let mtu = to_integer(env, &config, "mtu")?.map(|v| v as u32);
|
let mtu = to_integer(env, &config, "mtu")?.map(|v| v as u32);
|
||||||
@@ -78,25 +79,6 @@ pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
|
|||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
let server_address = match server_address_str.to_socket_addrs() {
|
|
||||||
Ok(mut rs) => {
|
|
||||||
if let Some(addr) = rs.next() {
|
|
||||||
addr
|
|
||||||
} else {
|
|
||||||
env.throw_new("java/lang/RuntimeException", "server address err")
|
|
||||||
.expect("throw");
|
|
||||||
return Err(Error::JavaException);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
env.throw_new(
|
|
||||||
"java/lang/RuntimeException",
|
|
||||||
format!("server address {}", e),
|
|
||||||
)
|
|
||||||
.expect("throw");
|
|
||||||
return Err(Error::JavaException);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let cipher_model = match CipherModel::from_str(&cipher_model) {
|
let cipher_model = match CipherModel::from_str(&cipher_model) {
|
||||||
Ok(cipher_model) => cipher_model,
|
Ok(cipher_model) => cipher_model,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -113,8 +95,8 @@ pub fn new_config(env: &mut JNIEnv, config: JObject) -> Result<Config, Error> {
|
|||||||
token,
|
token,
|
||||||
device_id,
|
device_id,
|
||||||
name,
|
name,
|
||||||
server_address,
|
|
||||||
server_address_str,
|
server_address_str,
|
||||||
|
dns,
|
||||||
stun_server,
|
stun_server,
|
||||||
in_ips,
|
in_ips,
|
||||||
out_ips,
|
out_ips,
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ impl Vnt {
|
|||||||
config.server_encrypt,
|
config.server_encrypt,
|
||||||
config.device_id.clone(),
|
config.device_id.clone(),
|
||||||
config.server_address_str.clone(),
|
config.server_address_str.clone(),
|
||||||
|
config.name_servers.clone(),
|
||||||
);
|
);
|
||||||
let ports = config.ports.as_ref().map_or(vec![0, 0], |v| {
|
let ports = config.ports.as_ref().map_or(vec![0, 0], |v| {
|
||||||
if v.is_empty() {
|
if v.is_empty() {
|
||||||
|
|||||||
+24
-12
@@ -1,12 +1,13 @@
|
|||||||
use std::io;
|
use anyhow::anyhow;
|
||||||
use std::net::{Ipv4Addr, SocketAddr};
|
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||||
|
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::UseChannelType;
|
use crate::channel::UseChannelType;
|
||||||
use crate::cipher::CipherModel;
|
use crate::cipher::CipherModel;
|
||||||
use crate::util::RecordPriority;
|
use crate::util::{address_choose, dns_query_all};
|
||||||
|
|
||||||
mod conn;
|
mod conn;
|
||||||
|
|
||||||
@@ -17,9 +18,9 @@ pub struct Config {
|
|||||||
pub token: String,
|
pub token: String,
|
||||||
pub device_id: String,
|
pub device_id: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub server_address: SocketAddr,
|
||||||
pub server_address_str: String,
|
pub server_address_str: String,
|
||||||
pub name_servers:Vec<SocketAddr>,
|
pub name_servers: Vec<String>,
|
||||||
pub record_priority:RecordPriority,
|
|
||||||
pub stun_server: Vec<String>,
|
pub stun_server: Vec<String>,
|
||||||
pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
|
pub in_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||||
pub out_ips: Vec<(u32, u32)>,
|
pub out_ips: Vec<(u32, u32)>,
|
||||||
@@ -51,8 +52,7 @@ impl Config {
|
|||||||
device_id: String,
|
device_id: String,
|
||||||
name: String,
|
name: String,
|
||||||
server_address_str: String,
|
server_address_str: String,
|
||||||
name_servers:Vec<SocketAddr>,
|
mut name_servers: Vec<String>,
|
||||||
record_priority:RecordPriority,
|
|
||||||
mut stun_server: Vec<String>,
|
mut stun_server: Vec<String>,
|
||||||
in_ips: Vec<(u32, u32, Ipv4Addr)>,
|
in_ips: Vec<(u32, u32, Ipv4Addr)>,
|
||||||
out_ips: Vec<(u32, u32)>,
|
out_ips: Vec<(u32, u32)>,
|
||||||
@@ -72,30 +72,42 @@ impl Config {
|
|||||||
use_channel_type: UseChannelType,
|
use_channel_type: UseChannelType,
|
||||||
packet_loss_rate: Option<f64>,
|
packet_loss_rate: Option<f64>,
|
||||||
packet_delay: u32,
|
packet_delay: u32,
|
||||||
) -> io::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
for x in stun_server.iter_mut() {
|
for x in stun_server.iter_mut() {
|
||||||
if !x.contains(":") {
|
if !x.contains(":") {
|
||||||
x.push_str(":3478");
|
x.push_str(":3478");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for x in name_servers.iter_mut() {
|
||||||
|
if Ipv6Addr::from_str(x).is_ok() {
|
||||||
|
x.push_str(":53");
|
||||||
|
} else if !x.contains(":") {
|
||||||
|
x.push_str(":53");
|
||||||
|
}
|
||||||
|
}
|
||||||
if token.is_empty() || token.len() > 128 {
|
if token.is_empty() || token.len() > 128 {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "token too long"));
|
return Err(anyhow!("token too long"));
|
||||||
}
|
}
|
||||||
if device_id.is_empty() || device_id.len() > 128 {
|
if device_id.is_empty() || device_id.len() > 128 {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "device_id too long"));
|
return Err(anyhow!("device_id too long"));
|
||||||
}
|
}
|
||||||
if name.is_empty() || name.len() > 128 {
|
if name.is_empty() || name.len() > 128 {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "name too long"));
|
return Err(anyhow!("name too long"));
|
||||||
}
|
}
|
||||||
|
if name_servers.is_empty() {
|
||||||
|
name_servers.push("8.8.8.8:53".to_string());
|
||||||
|
}
|
||||||
|
let server_address =
|
||||||
|
address_choose(dns_query_all(&server_address_str, name_servers.clone())?)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
tap,
|
tap,
|
||||||
token,
|
token,
|
||||||
device_id,
|
device_id,
|
||||||
name,
|
name,
|
||||||
|
server_address,
|
||||||
server_address_str,
|
server_address_str,
|
||||||
name_servers,
|
name_servers,
|
||||||
record_priority,
|
|
||||||
stun_server,
|
stun_server,
|
||||||
in_ips,
|
in_ips,
|
||||||
out_ips,
|
out_ips,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::net::{SocketAddr, ToSocketAddrs};
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ use crate::channel::sender::AcceptSocketSender;
|
|||||||
use crate::handle::callback::{ConnectInfo, ErrorType};
|
use crate::handle::callback::{ConnectInfo, ErrorType};
|
||||||
use crate::handle::handshaker::Handshake;
|
use crate::handle::handshaker::Handshake;
|
||||||
use crate::handle::{BaseConfigInfo, ConnectStatus, CurrentDeviceInfo};
|
use crate::handle::{BaseConfigInfo, ConnectStatus, CurrentDeviceInfo};
|
||||||
use crate::util::{dns_query_all, Scheduler};
|
use crate::util::{address_choose, dns_query_all, Scheduler};
|
||||||
use crate::{ErrorInfo, VntCallback};
|
use crate::{ErrorInfo, VntCallback};
|
||||||
|
|
||||||
pub fn idle_route<Call: VntCallback>(
|
pub fn idle_route<Call: VntCallback>(
|
||||||
@@ -164,32 +164,35 @@ pub fn domain_request0(
|
|||||||
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()) {
|
||||||
Ok(mut addrs) => {
|
Ok(addrs) => {
|
||||||
for x in &addrs {
|
log::info!(
|
||||||
//选出一个能用的地址
|
"domain {} dns {:?} addr {:?}",
|
||||||
if x.is_ipv4(){
|
config.server_addr,
|
||||||
}
|
config.name_servers,
|
||||||
todo!()
|
addrs
|
||||||
|
);
|
||||||
|
|
||||||
}
|
match address_choose(addrs) {
|
||||||
if let Some(addr) = addrs.pop() {
|
Ok(addr) => {
|
||||||
if addr != current_dev.connect_server {
|
if addr != current_dev.connect_server {
|
||||||
let mut tmp = current_dev.clone();
|
let mut tmp = current_dev.clone();
|
||||||
tmp.connect_server = addr;
|
tmp.connect_server = addr;
|
||||||
let rs = current_device.compare_exchange(current_dev, tmp);
|
let rs = current_device.compare_exchange(current_dev, tmp);
|
||||||
log::info!(
|
log::info!(
|
||||||
"服务端地址变化,旧地址:{},新地址:{},替换结果:{}",
|
"服务端地址变化,旧地址:{},新地址:{},替换结果:{}",
|
||||||
current_dev.connect_server,
|
current_dev.connect_server,
|
||||||
addr,
|
addr,
|
||||||
rs.is_ok()
|
rs.is_ok()
|
||||||
);
|
);
|
||||||
if rs.is_ok() {
|
if rs.is_ok() {
|
||||||
current_dev.connect_server = addr;
|
current_dev.connect_server = addr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
Err(e) => {
|
||||||
log::error!("域名解析值为空,domain={}", config.server_addr);
|
log::error!("域名地址选择失败:{:?},domain={}", e, config.server_addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ pub struct BaseConfigInfo {
|
|||||||
pub server_secret: bool,
|
pub server_secret: bool,
|
||||||
pub device_id: String,
|
pub device_id: String,
|
||||||
pub server_addr: String,
|
pub server_addr: String,
|
||||||
pub name_servers:Vec<SocketAddr>,
|
pub name_servers: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BaseConfigInfo {
|
impl BaseConfigInfo {
|
||||||
@@ -74,7 +74,7 @@ impl BaseConfigInfo {
|
|||||||
server_secret: bool,
|
server_secret: bool,
|
||||||
device_id: String,
|
device_id: String,
|
||||||
server_addr: String,
|
server_addr: String,
|
||||||
name_servers:Vec<SocketAddr>,
|
name_servers: Vec<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
|
|||||||
+43
-40
@@ -1,38 +1,40 @@
|
|||||||
use std::{io, thread};
|
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, UdpSocket};
|
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, UdpSocket};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use std::{io, thread};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use trust_dns_proto::op::{Edns, Message, MessageType, OpCode, Query};
|
use trust_dns_proto::op::{Edns, Message, MessageType, OpCode, Query};
|
||||||
use trust_dns_proto::rr::{Name, RecordType};
|
use trust_dns_proto::rr::{Name, RecordType};
|
||||||
use trust_dns_proto::xfer::DnsRequestOptions;
|
use trust_dns_proto::xfer::DnsRequestOptions;
|
||||||
|
|
||||||
/// 解析记录优先级
|
/// 后续实现选择延迟最低的可用地址,需要服务端配合
|
||||||
pub enum RecordPriority{
|
/// 现在是选择第一个地址,优先ipv6
|
||||||
Ipv4,
|
pub fn address_choose(addrs: Vec<SocketAddr>) -> anyhow::Result<SocketAddr> {
|
||||||
Ipv6,
|
let v4: Vec<SocketAddr> = addrs.iter().filter(|v| v.is_ipv4()).map(|v| *v).collect();
|
||||||
}
|
let v6: Vec<SocketAddr> = addrs.iter().filter(|v| v.is_ipv6()).map(|v| *v).collect();
|
||||||
impl FromStr for RecordPriority {
|
let check_addr = |addrs: &Vec<SocketAddr>| -> anyhow::Result<SocketAddr> {
|
||||||
type Err = String;
|
if !addrs.is_empty() {
|
||||||
|
let udp = if addrs[0].is_ipv6() {
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
UdpSocket::bind("[::]:0")?
|
||||||
match s.to_lowercase().trim() {
|
} else {
|
||||||
"ipv4" => Ok(RecordPriority::Ipv4),
|
UdpSocket::bind("0.0.0.0:0")?
|
||||||
"ipv6" => Ok(RecordPriority::Ipv6),
|
};
|
||||||
_ => Err(format!("not match '{}', enum: ipv4/ipv6", s)),
|
for addr in addrs {
|
||||||
|
if udp.connect(addr).is_ok() {
|
||||||
|
return Ok(*addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Err(anyhow::anyhow!("not connect address"))
|
||||||
|
};
|
||||||
|
if let Ok(addr) = check_addr(&v6) {
|
||||||
|
return Ok(addr);
|
||||||
}
|
}
|
||||||
|
check_addr(&v4)
|
||||||
}
|
}
|
||||||
impl Default for RecordPriority {
|
|
||||||
fn default() -> Self {
|
pub fn dns_query_all(domain: &str, name_servers: Vec<String>) -> anyhow::Result<Vec<SocketAddr>> {
|
||||||
RecordPriority::Ipv6
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn dns_query_all(
|
|
||||||
domain: &str,
|
|
||||||
name_servers: Vec<SocketAddr>,
|
|
||||||
) -> anyhow::Result<Vec<SocketAddr>> {
|
|
||||||
match SocketAddr::from_str(domain) {
|
match SocketAddr::from_str(domain) {
|
||||||
Ok(addr) => {
|
Ok(addr) => {
|
||||||
return Ok(vec![addr]);
|
return Ok(vec![addr]);
|
||||||
@@ -43,7 +45,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) = domain.strip_prefix("txt:") {
|
if let Some(domain) = domain.to_lowercase().strip_prefix("txt:") {
|
||||||
return txt_dns(domain, name_server);
|
return txt_dns(domain, name_server);
|
||||||
}
|
}
|
||||||
let end_index = domain
|
let end_index = domain
|
||||||
@@ -54,10 +56,12 @@ pub fn dns_query_all(
|
|||||||
.with_context(|| format!("{:?} not port", domain))?;
|
.with_context(|| format!("{:?} not port", domain))?;
|
||||||
let th1 = {
|
let th1 = {
|
||||||
let host = host.to_string();
|
let host = host.to_string();
|
||||||
|
let name_server = name_server.clone();
|
||||||
thread::spawn(move || a_dns(host, name_server))
|
thread::spawn(move || a_dns(host, name_server))
|
||||||
};
|
};
|
||||||
let th2 = {
|
let th2 = {
|
||||||
let host = host.to_string();
|
let host = host.to_string();
|
||||||
|
let name_server = name_server.clone();
|
||||||
thread::spawn(move || aaaa_dns(host, name_server))
|
thread::spawn(move || aaaa_dns(host, name_server))
|
||||||
};
|
};
|
||||||
let mut addr = Vec::new();
|
let mut addr = Vec::new();
|
||||||
@@ -68,7 +72,7 @@ pub fn dns_query_all(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
err.replace(anyhow::anyhow!("{}",e));
|
err.replace(anyhow::anyhow!("{}", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match th2.join().unwrap() {
|
match th2.join().unwrap() {
|
||||||
@@ -80,9 +84,9 @@ pub fn dns_query_all(
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
if addr.is_empty() {
|
if addr.is_empty() {
|
||||||
if let Some(err) = &mut err {
|
if let Some(err) = &mut err {
|
||||||
*err = anyhow::anyhow!("{},{}",err,e);
|
*err = anyhow::anyhow!("{},{}", err, e);
|
||||||
} else {
|
} else {
|
||||||
err.replace(anyhow::anyhow!("{}",e));
|
err.replace(anyhow::anyhow!("{}", e));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -102,10 +106,6 @@ pub fn dns_query_all(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dns_query(domain: &str, name_server: SocketAddr) -> anyhow::Result<Vec<SocketAddr>> {
|
|
||||||
dns_query_all(domain, vec![name_server])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn query(
|
fn query(
|
||||||
udp: &UdpSocket,
|
udp: &UdpSocket,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
@@ -120,7 +120,7 @@ fn query(
|
|||||||
|
|
||||||
let request = request.to_vec()?;
|
let request = request.to_vec()?;
|
||||||
udp.connect(name_server)
|
udp.connect(name_server)
|
||||||
.with_context(|| format!("name server {:?} error ", name_server));
|
.with_context(|| format!("name server {:?} error ", name_server))?;
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let mut buf = [0; 65536];
|
let mut buf = [0; 65536];
|
||||||
let len = loop {
|
let len = loop {
|
||||||
@@ -150,8 +150,9 @@ fn query(
|
|||||||
Ok(message)
|
Ok(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn txt_dns(domain: &str, name_server: SocketAddr) -> anyhow::Result<Vec<SocketAddr>> {
|
pub fn txt_dns(domain: &str, name_server: String) -> anyhow::Result<Vec<SocketAddr>> {
|
||||||
let udp = bind_udp(name_server.is_ipv4())?;
|
let name_server: SocketAddr = name_server.parse()?;
|
||||||
|
let udp = bind_udp(name_server)?;
|
||||||
let message = query(&udp, domain, name_server, RecordType::TXT)?;
|
let message = query(&udp, domain, name_server, RecordType::TXT)?;
|
||||||
let mut rs = Vec::new();
|
let mut rs = Vec::new();
|
||||||
for record in message.answers() {
|
for record in message.answers() {
|
||||||
@@ -166,8 +167,8 @@ pub fn txt_dns(domain: &str, name_server: SocketAddr) -> anyhow::Result<Vec<Sock
|
|||||||
Ok(rs)
|
Ok(rs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_udp(is_ipv4: bool) -> io::Result<UdpSocket> {
|
fn bind_udp(name_server: SocketAddr) -> anyhow::Result<UdpSocket> {
|
||||||
let udp = if is_ipv4 {
|
let udp = if name_server.is_ipv4() {
|
||||||
UdpSocket::bind("0.0.0.0:0")?
|
UdpSocket::bind("0.0.0.0:0")?
|
||||||
} else {
|
} else {
|
||||||
UdpSocket::bind("[::]:0")?
|
UdpSocket::bind("[::]:0")?
|
||||||
@@ -176,8 +177,9 @@ fn bind_udp(is_ipv4: bool) -> io::Result<UdpSocket> {
|
|||||||
Ok(udp)
|
Ok(udp)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn a_dns(domain: String, name_server: SocketAddr) -> anyhow::Result<Vec<Ipv4Addr>> {
|
pub fn a_dns(domain: String, name_server: String) -> anyhow::Result<Vec<Ipv4Addr>> {
|
||||||
let udp = bind_udp(name_server.is_ipv4())?;
|
let name_server: SocketAddr = name_server.parse()?;
|
||||||
|
let udp = bind_udp(name_server)?;
|
||||||
let message = query(&udp, &domain, name_server, RecordType::A)?;
|
let message = query(&udp, &domain, name_server, RecordType::A)?;
|
||||||
let mut rs = Vec::new();
|
let mut rs = Vec::new();
|
||||||
for record in message.answers() {
|
for record in message.answers() {
|
||||||
@@ -191,8 +193,9 @@ pub fn a_dns(domain: String, name_server: SocketAddr) -> anyhow::Result<Vec<Ipv4
|
|||||||
Ok(rs)
|
Ok(rs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aaaa_dns(domain: String, name_server: SocketAddr) -> anyhow::Result<Vec<Ipv6Addr>> {
|
pub fn aaaa_dns(domain: String, name_server: String) -> anyhow::Result<Vec<Ipv6Addr>> {
|
||||||
let udp = bind_udp(name_server.is_ipv4())?;
|
let name_server: SocketAddr = name_server.parse()?;
|
||||||
|
let udp = bind_udp(name_server)?;
|
||||||
let message = query(&udp, &domain, name_server, RecordType::AAAA)?;
|
let message = query(&udp, &domain, name_server, RecordType::AAAA)?;
|
||||||
let mut rs = Vec::new();
|
let mut rs = Vec::new();
|
||||||
for record in message.answers() {
|
for record in message.answers() {
|
||||||
|
|||||||
Reference in New Issue
Block a user