添加dns解析,如果dns是punchsky.com(punchnet内部的域名),就转发给15353端口解析;其他的,就直接转发给ali dns 223.5.5.5:53解析
This commit is contained in:
parent
150d1c8e67
commit
5136e9427b
200
Cargo.lock
generated
200
Cargo.lock
generated
@ -149,15 +149,6 @@ version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[package]]
|
||||
name = "aok"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a8746a6637032084d12397dcd4b1f93d7c5e27dab4a2abe37515e5dadb7cdad"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ar"
|
||||
version = "0.9.0"
|
||||
@ -284,15 +275,6 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boxleak"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "313d0a9cc1832e6636eec848805ab5471a546dc68dcfc058eea4d4602892cf64"
|
||||
dependencies = [
|
||||
"aok",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.20.2"
|
||||
@ -402,12 +384,6 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
@ -462,15 +438,6 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "citer"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe4fe42a458d9c1b72d540bb4bb0226bcfc2136c53b4407af5e23c9f7532f3ea"
|
||||
dependencies = [
|
||||
"aok",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
@ -535,17 +502,6 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "coarsetime"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e58eb270476aa4fc7843849f8a35063e8743b4dbcdf6dd0f8ea0886980c204c2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasix",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.5"
|
||||
@ -828,18 +784,6 @@ dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dns_parse"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3943bb4aeaf3b6b8f9b8a8fa04609423ee8ab803e81c55385a18a7f86da339a9"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hex",
|
||||
"idns",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dotenvy"
|
||||
version = "0.15.7"
|
||||
@ -931,19 +875,6 @@ version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "expire_cache"
|
||||
version = "0.1.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d65c4482fb3725e7d25768dd33864b29dcb1f9ad365742649a8eae8b6bec43ed"
|
||||
dependencies = [
|
||||
"boxleak",
|
||||
"papaya",
|
||||
"parking_lot",
|
||||
"sendptr",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastbloom"
|
||||
version = "0.14.1"
|
||||
@ -1528,22 +1459,6 @@ dependencies = [
|
||||
"icu_properties",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idns"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45ddb9b2206e9ff4b548671e4372986ca71f90efbef3d74c3e9c5893c7eec869"
|
||||
dependencies = [
|
||||
"expire_cache",
|
||||
"ip_set",
|
||||
"log",
|
||||
"papaya",
|
||||
"pick_fast",
|
||||
"race",
|
||||
"static_init",
|
||||
"ts_",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.13.0"
|
||||
@ -1566,12 +1481,6 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ip_set"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33f71689e048d8568faba23fdc3a0822cd10738515b1c0b3851d84221663fec5"
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.12.0"
|
||||
@ -1969,16 +1878,6 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
|
||||
|
||||
[[package]]
|
||||
name = "papaya"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "997ee03cd38c01469a7046643714f0ad28880bcb9e6679ff0666e24817ca19b7"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"seize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.5"
|
||||
@ -2033,17 +1932,6 @@ dependencies = [
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pick_fast"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8e330233974b83cda2e28df3ddf3e0d1675f1d4496f031e00a7a4a0b67d0506"
|
||||
dependencies = [
|
||||
"citer",
|
||||
"fastrand",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.17"
|
||||
@ -2266,7 +2154,6 @@ dependencies = [
|
||||
"daemonize",
|
||||
"dashmap 6.1.0",
|
||||
"dns-lookup",
|
||||
"dns_parse",
|
||||
"etherparse",
|
||||
"futures-util",
|
||||
"hex",
|
||||
@ -2291,6 +2178,7 @@ dependencies = [
|
||||
"sdlan-sn-rs",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"simple-dns",
|
||||
"structopt",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@ -2312,7 +2200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cfg_aliases 0.2.1",
|
||||
"cfg_aliases",
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
@ -2354,7 +2242,7 @@ version = "0.5.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
|
||||
dependencies = [
|
||||
"cfg_aliases 0.2.1",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2",
|
||||
@ -2383,17 +2271,6 @@ version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "race"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402085c832dd003de54bfa3b728c8b4b69632dc32a402c0c70cae8361bc2ec79"
|
||||
dependencies = [
|
||||
"coarsetime",
|
||||
"futures",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@ -2815,28 +2692,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "seize"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b55fb86dfd3a2f5f76ea78310a88f96c4ea21a3031f8d212443d56123fd0521"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "sendptr"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ada566c72d62f4c53e5d0e593f4bab893dfb7d14b505a130b148189928f0988"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
@ -2975,6 +2836,15 @@ version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||
|
||||
[[package]]
|
||||
name = "simple-dns"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df350943049174c4ae8ced56c604e28270258faec12a6a48637a7655287c9ce0"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.2"
|
||||
@ -3228,34 +3098,6 @@ version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "static_init"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bae1df58c5fea7502e8e352ec26b5579f6178e1fdb311e088580c980dee25ed"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg_aliases 0.2.1",
|
||||
"libc",
|
||||
"parking_lot",
|
||||
"parking_lot_core",
|
||||
"static_init_macro",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_init_macro"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1389c88ddd739ec6d3f8f83343764a0e944cd23cfbf126a9796a714b0b6edd6f"
|
||||
dependencies = [
|
||||
"cfg_aliases 0.1.1",
|
||||
"memchr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.5"
|
||||
@ -3721,15 +3563,6 @@ version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "ts_"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2d4270cf460c46e2cafb448d9abebc506dff81e15148f19b2fc97686bfe8d4f"
|
||||
dependencies = [
|
||||
"coarsetime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
@ -3917,15 +3750,6 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
|
||||
|
||||
[[package]]
|
||||
name = "wasix"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1757e0d1f8456693c7e5c6c629bdb54884e032aa0bb53c155f6a39f94440d332"
|
||||
dependencies = [
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.114"
|
||||
|
||||
@ -43,7 +43,7 @@ ahash = "0.8.12"
|
||||
ipnet = "2.12.0"
|
||||
arc-swap = "1.9.0"
|
||||
rustls-native-certs = "0.8.3"
|
||||
dns_parse = "0.1.2"
|
||||
simple-dns = "0.11.2"
|
||||
# rolling-file = { path = "../rolling-file" }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
|
||||
@ -81,6 +81,11 @@ pub struct LoginResponse {
|
||||
pub data: Option<LoginData>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NetworkListInfo {
|
||||
pub network_id: u32,
|
||||
pub network_name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct LoginData {
|
||||
@ -90,7 +95,8 @@ pub struct LoginData {
|
||||
pub audit: u32,
|
||||
pub network_id: u32,
|
||||
pub network_name: String,
|
||||
// pub network_domain: String,
|
||||
pub network_domain: String,
|
||||
pub my_network_list: Vec<NetworkListInfo>,
|
||||
// pub exit_node: Vec<ExitNode>,
|
||||
}
|
||||
|
||||
@ -125,6 +131,7 @@ where T: Serialize + HMacCalculator,
|
||||
// println!("status: {}", response.status());
|
||||
let text = response.text().await.unwrap();
|
||||
|
||||
println!("got test: {}", text);
|
||||
let data = serde_json::from_str(&text).unwrap();
|
||||
|
||||
// println!("response: {}", response.text().await.unwrap());
|
||||
|
||||
@ -101,6 +101,7 @@ fn parse_login_result(res: Result<LoginResponse>) -> LoginData {
|
||||
audit: data.audit,
|
||||
network_id: data.network_id,
|
||||
network_name: data.network_name.clone(),
|
||||
network_domain: data.network_domain.clone(),
|
||||
}) {
|
||||
eprintln!("failed to save access_token");
|
||||
}
|
||||
@ -226,7 +227,7 @@ async fn daemonize_me(
|
||||
remembered.access_token.clone(),
|
||||
// String::new(),
|
||||
remembered.network_id,
|
||||
&"".to_owned(),
|
||||
&remembered.network_domain,
|
||||
ip_net,
|
||||
connect_info.mask_len,
|
||||
connect_info.identity_id,
|
||||
@ -460,6 +461,7 @@ fn run_it(cmd: CommandLineInput2, client_id: String, allow_routing: bool, mac: M
|
||||
audit: data.audit,
|
||||
network_id: data.network_id,
|
||||
network_name: data.network_name,
|
||||
network_domain: data.network_domain,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -73,7 +73,8 @@ pub async fn run_sdlan(
|
||||
let hostname = hostname.unwrap_or(host);
|
||||
let _ = save_to_file(&hostfile, &hostname);
|
||||
|
||||
let sock = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
||||
let sock_dns = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
||||
let udp_sock_for_global_dns = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
||||
|
||||
if let Err(e) = init_edge(
|
||||
// &args.token,
|
||||
@ -85,7 +86,8 @@ pub async fn run_sdlan(
|
||||
start_stop_sender,
|
||||
// args.mtu,
|
||||
connecting_chan.clone(),
|
||||
sock,
|
||||
sock_dns,
|
||||
udp_sock_for_global_dns,
|
||||
hostname,
|
||||
server_ip,
|
||||
install_channel.to_owned(),
|
||||
|
||||
@ -11,8 +11,9 @@ use crate::tcp::{init_quic_conn, send_stun_request};
|
||||
use crate::utils::{send_to_sock, CommandLine};
|
||||
use crate::{ConnectionInfo};
|
||||
use bytes::BytesMut;
|
||||
use etherparse::{PacketBuilder, SlicedPacket};
|
||||
use sdlan_sn_rs::peer::{SdlanSock};
|
||||
use sdlan_sn_rs::utils::{get_current_timestamp, is_multi_broadcast};
|
||||
use sdlan_sn_rs::utils::{get_current_timestamp, ip_to_string, is_multi_broadcast};
|
||||
use sdlan_sn_rs::utils::{Mac, Result};
|
||||
use tokio::net::{UdpSocket};
|
||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||
@ -21,7 +22,7 @@ use tokio_util::sync::CancellationToken;
|
||||
use super::{Node, StartStopInfo};
|
||||
use crate::utils::Socket;
|
||||
|
||||
use tracing::{debug, error};
|
||||
use tracing::{debug, error, warn};
|
||||
|
||||
pub async fn async_main(
|
||||
args: CommandLine,
|
||||
@ -224,12 +225,45 @@ async fn loop_tap(eee: &'static Node, cancel: CancellationToken) {
|
||||
drop(rx);
|
||||
break;
|
||||
}
|
||||
global_reply_global = receive_dns_reply(&eee.udp_sock_for_global_dns) => {
|
||||
// global reply, only dns payload
|
||||
if let Some(data) = global_reply_global {
|
||||
if let Ok(mut dns) = simple_dns::Packet::parse(&data) {
|
||||
let transaction_id = dns.id();
|
||||
if let Some((ip, port, origin_transaction_id)) = eee.dns_matcher.get_client_info(transaction_id) {
|
||||
warn!("got dns reply from global 223.5.5.5: {:?}, will send to {}:{}",
|
||||
data, ip_to_string(&ip), port);
|
||||
|
||||
let dstmac = eee.device_config.get_mac();
|
||||
let srcmac = eee.device_config.dns_mac;
|
||||
|
||||
dns.set_id(origin_transaction_id);
|
||||
let builder = PacketBuilder::ethernet2(srcmac, dstmac)
|
||||
.ipv4([100, 100, 100, 100], ip.to_be_bytes(), 64)
|
||||
.udp(53, port);
|
||||
|
||||
let new_dns_resp = dns.build_bytes_vec().unwrap();
|
||||
let mut response_packet = Vec::with_capacity(builder.size(new_dns_resp.len()));
|
||||
if let Ok(_) = builder.write(&mut response_packet, &new_dns_resp) {
|
||||
warn!("will send to tun with packet: {:?}", response_packet);
|
||||
if let Err(_e) = eee.device.handle_packet_from_net(&response_packet).await {
|
||||
error!("failed to write dns packet to device");
|
||||
}
|
||||
} else {
|
||||
error!("failed to write dns body");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reply = receive_dns_reply(&eee.udp_sock_for_dns) => {
|
||||
if reply.is_none() {
|
||||
drop(rx);
|
||||
break;
|
||||
}
|
||||
let reply = reply.unwrap();
|
||||
warn!("got packet from 15353: {:?}", reply);
|
||||
let dstmac = eee.device_config.get_mac();
|
||||
let srcmac = eee.device_config.dns_mac;
|
||||
let mut packet = Vec::with_capacity(14+reply.len());
|
||||
|
||||
@ -17,7 +17,7 @@ use tracing::{debug, error, warn};
|
||||
|
||||
use crate::network::{ArpTable, RouteTable2};
|
||||
use crate::quic::quic_init;
|
||||
use crate::{CommandLine, ConnectionInfo, MyEncryptor, RuleCache, get_base_dir};
|
||||
use crate::{CommandLine, ConnectionInfo, DNSMatcher, MyEncryptor, RuleCache, get_base_dir};
|
||||
use crate::pb::{
|
||||
SdlArpRequest, SdlEmpty, SdlStunProbe, SdlStunProbeReply, encode_to_tcp_message, encode_to_udp_message
|
||||
};
|
||||
@ -48,6 +48,7 @@ pub async fn init_edge(
|
||||
// mtu: u32,
|
||||
connecting_chan: Option<Sender<ConnectionInfo>>,
|
||||
udpsock_for_dns: Arc<UdpSocket>,
|
||||
udp_sock_for_global_dns: Arc<UdpSocket>,
|
||||
hostname: String,
|
||||
server_ip: String,
|
||||
install_channel: String
|
||||
@ -97,13 +98,23 @@ pub async fn init_edge(
|
||||
connecting_chan,
|
||||
hostname,
|
||||
udpsock_for_dns,
|
||||
udp_sock_for_global_dns,
|
||||
server_ip,
|
||||
install_channel,
|
||||
);
|
||||
|
||||
edge.route_table.parse_and_add_route(&args.route_file, &args.route_str);
|
||||
let matcher = Arc::clone(&edge.dns_matcher);
|
||||
|
||||
do_init_edge(edge)?;
|
||||
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
matcher.retain();
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -172,7 +183,7 @@ pub struct Node {
|
||||
pub encryptor: ArcSwap<MyEncryptor>,
|
||||
|
||||
pub network_id: AtomicU32,
|
||||
pub network_domain: RwLock<String>,
|
||||
pub network_domain: ArcSwap<String>,
|
||||
|
||||
pub identity_id: IdentityID,
|
||||
|
||||
@ -190,6 +201,9 @@ pub struct Node {
|
||||
pub quic_endpoint: Endpoint,
|
||||
|
||||
pub udp_sock_for_dns: Arc<UdpSocket>,
|
||||
pub udp_sock_for_global_dns: Arc<UdpSocket>,
|
||||
pub dns_matcher: Arc<DNSMatcher>,
|
||||
|
||||
pub server_ip: String,
|
||||
|
||||
pub tcp_pong: Arc<AtomicU64>,
|
||||
@ -288,7 +302,8 @@ impl Node {
|
||||
// self.device_config.ip.net_bit_len.store(ip_net_bit_len, Ordering::Relaxed);
|
||||
// *self.device_config.mac.write().unwrap() = create_or_load_mac();
|
||||
self.network_id.store(network_id, Ordering::Relaxed);
|
||||
self.network_domain.write().unwrap().clone_from(network_domain);
|
||||
self.network_domain.store(Arc::new(network_domain.clone()));
|
||||
// self.network_domain.write().unwrap().clone_from(network_domain);
|
||||
// self.network_domain = network_domain;
|
||||
|
||||
self.identity_id.store(identity_id);
|
||||
@ -332,7 +347,8 @@ impl Node {
|
||||
}
|
||||
// *self.device_config.mac.write().unwrap() = create_or_load_mac();
|
||||
self.network_id.store(network_id, Ordering::Relaxed);
|
||||
self.network_domain.write().unwrap().clone_from(network_domain);
|
||||
// self.network_domain.write().unwrap().clone_from(network_domain);
|
||||
self.network_domain.store(Arc::new(network_domain.clone()));
|
||||
|
||||
self.identity_id.store(identity_id);
|
||||
// *self._token.lock().unwrap() = token;
|
||||
@ -389,6 +405,7 @@ impl Node {
|
||||
connecting_chan: Option<Sender<ConnectionInfo>>,
|
||||
hostname: String,
|
||||
udpsock_for_dns: Arc<UdpSocket>,
|
||||
udp_sock_for_global_dns: Arc<UdpSocket>,
|
||||
server_ip: String,
|
||||
install_channel: String,
|
||||
) -> Self {
|
||||
@ -414,9 +431,11 @@ impl Node {
|
||||
|
||||
route_table: RouteTable2::new(),
|
||||
|
||||
network_domain: RwLock::new(String::new()),
|
||||
network_domain: ArcSwap::new(Arc::new(String::new())),
|
||||
|
||||
udp_sock_for_dns: udpsock_for_dns,
|
||||
udp_sock_for_global_dns: udp_sock_for_global_dns,
|
||||
dns_matcher: Arc::new(DNSMatcher::new()),
|
||||
|
||||
quic_endpoint: quic_init(),
|
||||
|
||||
|
||||
@ -4,16 +4,19 @@ use bytes::BytesMut;
|
||||
#[cfg(feature = "tun")]
|
||||
use bytes::{BytesMut};
|
||||
|
||||
#[cfg(not(feature = "tun"))]
|
||||
use etherparse::{IpSlice, LinkSlice, NetSlice, SlicedPacket, TransportSlice};
|
||||
use etherparse::{Ethernet2Header};
|
||||
use ipnet::Ipv4Net;
|
||||
use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL;
|
||||
use sdlan_sn_rs::utils::{
|
||||
ip_to_string, is_ipv6_multicast, net_bit_len_to_mask,
|
||||
SDLanError,
|
||||
Mac, SDLanError, ip_to_string, is_ipv6_multicast, net_bit_len_to_mask
|
||||
};
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::{c_char, c_int};
|
||||
use std::fs::{self, OpenOptions};
|
||||
#[cfg(not(feature = "tun"))]
|
||||
use std::net::IpAddr;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||
use std::path::Path;
|
||||
@ -25,13 +28,13 @@ use std::io::{BufRead, BufReader, Read, Write};
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::process::Command;
|
||||
|
||||
use tracing::{debug, error, info};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
use crate::caculate_crc;
|
||||
use crate::get_edge;
|
||||
#[cfg(not(feature = "tun"))]
|
||||
use crate::network::{ARP_REPLY, ArpHdr, EthHdr};
|
||||
use crate::network::{ARP_REPLY, ArpHdr, EthHdr, parse_dns_payload};
|
||||
use crate::network::{Node, send_packet_to_net};
|
||||
#[cfg(not(feature = "tun"))]
|
||||
use crate::pb::SdlArpResponse;
|
||||
@ -228,6 +231,8 @@ impl TunTapPacketHandler for Iface {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature="abc")]
|
||||
async fn handle_packet_from_device(
|
||||
&self,
|
||||
data: BytesMut,
|
||||
@ -378,6 +383,141 @@ impl TunTapPacketHandler for Iface {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_packet_from_device(
|
||||
&self,
|
||||
data: BytesMut,
|
||||
// encrypt_key: &[u8],
|
||||
) -> std::io::Result<()> {
|
||||
use etherparse::PacketHeaders;
|
||||
|
||||
debug!("in tap mode2");
|
||||
let edge = get_edge();
|
||||
|
||||
let Ok((eth, layer3)) = Ethernet2Header::from_slice(&data) else {
|
||||
error!("failed to parse packet");
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// if let Some(eth) = headers.link {
|
||||
use etherparse::EtherType;
|
||||
use bytes::Bytes;
|
||||
|
||||
if eth.ether_type == EtherType::ARP {
|
||||
use crate::network::{ARP_REQUEST, ArpHdr};
|
||||
|
||||
let arp = ArpHdr::from_slice(&data);
|
||||
match arp.opcode {
|
||||
ARP_REQUEST => {
|
||||
let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32;
|
||||
if dest_ip == DNS_IP {
|
||||
error!("got dns ip");
|
||||
edge.device_config.dns_mac;
|
||||
write_arp_to_device(edge, edge.device_config.dns_mac, DNS_IP);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if edge.device_config.contains(&Ipv4Addr::from_bits(dest_ip)) {
|
||||
let _ = edge.send_arp_request(dest_ip, dest_ip).await;
|
||||
} else {
|
||||
if let Some((_, real_ip)) = edge.route_table.lookup(dest_ip) {
|
||||
let real_ip = u32::from_be_bytes(real_ip.octets());
|
||||
let _ = edge.send_arp_request(dest_ip, real_ip).await;
|
||||
}
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
_other => {
|
||||
// just do the following logic
|
||||
}
|
||||
}
|
||||
}
|
||||
let Ok(net_slice) = SlicedPacket::from_ip(layer3) else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if let Some(ip) = net_slice.net{
|
||||
|
||||
match ip {
|
||||
NetSlice::Ipv4(ipv4) => {
|
||||
use crate::FiveTuple;
|
||||
use etherparse::IpNumber;
|
||||
if let Some(transport) = net_slice.transport {
|
||||
match transport {
|
||||
TransportSlice::Tcp(tcp) => {
|
||||
let out_five_tuple = FiveTuple {
|
||||
src_ip: IpAddr::V4(ipv4.header().source_addr()),
|
||||
dst_ip: IpAddr::V4(ipv4.header().destination_addr()),
|
||||
src_port: tcp.source_port(),
|
||||
dst_port: tcp.destination_port(),
|
||||
proto: IpNumber::TCP.0,
|
||||
};
|
||||
edge.rule_cache.touch_packet(out_five_tuple);
|
||||
}
|
||||
TransportSlice::Udp(udp) => {
|
||||
let out_five_tuple = FiveTuple {
|
||||
src_ip: IpAddr::V4(ipv4.header().source_addr()),
|
||||
dst_ip: IpAddr::V4(ipv4.header().destination_addr()),
|
||||
src_port: udp.source_port(),
|
||||
dst_port: udp.destination_port(),
|
||||
proto: IpNumber::UDP.0,
|
||||
};
|
||||
edge.rule_cache.touch_packet(out_five_tuple);
|
||||
|
||||
if u32::from_be_bytes(ipv4.header().destination()) == DNS_IP {
|
||||
// should send to dns
|
||||
let source_ip = u32::from_be_bytes(ipv4.header().source());
|
||||
parse_dns_payload(edge, udp.payload(), layer3, source_ip, udp.source_port()).await;
|
||||
// edge.udp_sock_for_dns.send_to()
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
_other => {
|
||||
// ignore icmp and icmpv6
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NetSlice::Ipv6(_ipv6) => {
|
||||
// not handling the ipv6 packet
|
||||
// return Ok(())
|
||||
// just ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let target = eth.destination;
|
||||
if is_ipv6_multicast(&target) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let size = data.len();
|
||||
|
||||
let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else {
|
||||
// let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else {
|
||||
// let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else {
|
||||
error!("failed to encrypt packet request");
|
||||
return Ok(());
|
||||
};
|
||||
let data_bytes = Bytes::from(encrypted);
|
||||
let data = SdlData {
|
||||
is_p2p: true,
|
||||
network_id: edge.network_id.load(Ordering::Relaxed),
|
||||
ttl: SDLAN_DEFAULT_TTL as u32,
|
||||
src_mac: Vec::from(edge.device_config.get_mac()),
|
||||
dst_mac: Vec::from(target),
|
||||
data: data_bytes,
|
||||
identity_id: edge.identity_id.load(),
|
||||
session_token: edge.session_token.get(),
|
||||
};
|
||||
let msg = encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
|
||||
|
||||
send_packet_to_net(edge, target, &msg, size as u64).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(feature = "tun")]
|
||||
@ -704,13 +844,13 @@ fn check_has_resolvectl() -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_dns_route(gw: &str) -> Result<()>{
|
||||
fn add_dns_route(dev_name: &str) -> Result<()>{
|
||||
Command::new("route")
|
||||
.arg("add")
|
||||
.arg("-host")
|
||||
.arg("100.100.100.100")
|
||||
.arg("gw")
|
||||
.arg(gw)
|
||||
.arg("dev")
|
||||
.arg(dev_name)
|
||||
.output()?;
|
||||
|
||||
Ok(())
|
||||
@ -741,13 +881,14 @@ fn set_dns(
|
||||
network_domain: &str,
|
||||
gw: &str
|
||||
) -> Result<()> {
|
||||
error!("network_domain = {}", network_domain);
|
||||
if iface.has_resolvectl {
|
||||
add_resolvectl(name, network_domain)?;
|
||||
} else {
|
||||
backup_resolv_conf()?;
|
||||
modify_resolv_conf(&vec!["100.100.100.100".to_owned()], network_domain, true)?;
|
||||
}
|
||||
add_dns_route(gw)?;
|
||||
add_dns_route(name)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -998,14 +1139,18 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) {
|
||||
error!("invalid target_mac: {:?}, ip={}", data.target_mac, ip_to_string(&data.target_ip));
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: construct the arp reply, and write to tun;
|
||||
let src_mac = data.target_mac.try_into().unwrap();
|
||||
let dst_mac = edge.device_config.get_mac();
|
||||
let dst_ip = edge.device_config.get_ip();
|
||||
|
||||
let src_ip = data.origin_ip;
|
||||
|
||||
write_arp_to_device(edge, src_mac, src_ip);
|
||||
}
|
||||
|
||||
pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) {
|
||||
let dst_mac = edge.device_config.get_mac();
|
||||
let dst_ip = edge.device_config.get_ip();
|
||||
|
||||
let hdr = ArpHdr{
|
||||
ethhdr: EthHdr {
|
||||
dest: dst_mac,
|
||||
@ -1027,7 +1172,5 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) {
|
||||
if let Err(_e) = edge.device.send(&data) {
|
||||
error!("failed to write arp response to device");
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_dns_payload(edge: &Node, payload: &[u8]) {
|
||||
}
|
||||
@ -9,12 +9,12 @@ use sdlan_sn_rs::{
|
||||
utils::{Mac, Result, get_current_timestamp, ip_to_string},
|
||||
};
|
||||
|
||||
use tracing::debug;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use tracing::error;
|
||||
|
||||
use crate::{
|
||||
network::{RouteInfo, form_ethernet_packet, send_packet_to_net},
|
||||
network::{Node, RouteInfo, form_ethernet_packet, send_packet_to_net},
|
||||
pb::{SdlData, encode_to_udp_message},
|
||||
tcp::PacketType,
|
||||
utils::mac_to_string,
|
||||
@ -24,6 +24,8 @@ use super::get_edge;
|
||||
|
||||
pub const MAX_WAIT_PACKETS: usize = 100;
|
||||
|
||||
const DEFAULT_DNS_SERVER: u32 = (223<<24) + (5<<16) + (5<<8) + 5; // ali dns
|
||||
|
||||
pub trait TunTapPacketHandler {
|
||||
async fn handle_packet_from_net(&self, data: &[u8]) -> std::io::Result<()>;
|
||||
async fn handle_packet_from_device(&self, data: BytesMut) -> std::io::Result<()>;
|
||||
@ -137,3 +139,65 @@ pub async fn arp_arrived(ip: u32, mac: Mac) {
|
||||
waitlist.arp_arrived(ip, mac).await;
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn get_dns_gateway(edge: &Node, payload: &[u8]) -> Option<String> {
|
||||
let dns_packet = match simple_dns::Packet::parse(payload) {
|
||||
Err(e) => {
|
||||
error!("failed to parse dns packet: {}", e);
|
||||
return None;
|
||||
}
|
||||
Ok(p) => p,
|
||||
};
|
||||
|
||||
|
||||
let mut target_dns: &str = "";
|
||||
if !dns_packet.has_flags(simple_dns::PacketFlag::RESPONSE) && !dns_packet.questions.is_empty() {
|
||||
let question = &dns_packet.questions[0];
|
||||
let domain = question.qname.to_string();
|
||||
|
||||
let self_domain = &edge.network_domain.load();
|
||||
if self_domain.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if domain.ends_with(self_domain.as_str()) {
|
||||
debug!("got dns request for domain {}, which ends with our network domain {}, should send to dns server", domain, self_domain);
|
||||
return Some(domain);
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
pub async fn parse_dns_payload(edge: &Node, layer7: &[u8], layer3: &[u8], source_ip: u32, source_port: u16) {
|
||||
match simple_dns::Packet::parse(layer7) {
|
||||
Ok(mut dns) => {
|
||||
if !dns.has_flags(simple_dns::PacketFlag::RESPONSE) && !dns.questions.is_empty() {
|
||||
let question = &dns.questions[0];
|
||||
let qname = question.qname.to_string();
|
||||
if qname.ends_with(edge.network_domain.load().as_str()) {
|
||||
warn!("question 15353 for {} from {}:{} with transaction_id = {}",
|
||||
qname, ip_to_string(&source_ip), source_port, dns.id());
|
||||
// should send to our socket
|
||||
if let Err(e) = edge.udp_sock_for_dns.send_to(layer3, format!("{}:15353", edge.server_ip)).await {
|
||||
error!("failed to send request to 15353: {}", e);
|
||||
}
|
||||
} else {
|
||||
let origin_transaction_id = dns.id();
|
||||
let transaction_id = edge.dns_matcher.generate_transaction_id(source_ip, source_port, origin_transaction_id);
|
||||
dns.set_id(transaction_id);
|
||||
warn!("question 223.5.5.5 for {} from {}:{} with transaction_id = {}",
|
||||
qname, ip_to_string(&source_ip), source_port, dns.id());
|
||||
if let Ok(res) = dns.build_bytes_vec() {
|
||||
if let Err(e) = edge.udp_sock_for_global_dns.send_to(&res, "223.5.5.5:53").await {
|
||||
error!("failed to query for global dns: {}", e);
|
||||
}
|
||||
}
|
||||
// edge.udp_sock_for_global_dns.send_to()
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("failed to parse dns packet");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -188,7 +188,7 @@ async fn handle_tcp_message(msg: SdlanTcp) {
|
||||
edge.network_id.store(dev.network_id, Ordering::Relaxed);
|
||||
*/
|
||||
// edge.device.reload_config(&edge.device_config, &dev.network_domain);
|
||||
edge.device.reload_config(edge, &edge.device_config, &edge.network_domain.read().unwrap().clone());
|
||||
edge.device.reload_config(edge, &edge.device_config, &edge.network_domain.load());
|
||||
|
||||
edge.set_authorized(true);
|
||||
|
||||
|
||||
47
src/utils/dns.rs
Normal file
47
src/utils/dns.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use std::sync::{Arc, atomic::AtomicU16};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use sdlan_sn_rs::utils::get_current_timestamp;
|
||||
|
||||
pub struct DNSCacheInfo {
|
||||
pub src_ip: u32,
|
||||
pub src_port: u16,
|
||||
pub origin_transaction_id: u16,
|
||||
pub added: u64,
|
||||
}
|
||||
|
||||
pub struct DNSMatcher {
|
||||
current_transaction_id: AtomicU16,
|
||||
// match transaction_id to (client ip, client port)
|
||||
matcher: DashMap<u16, DNSCacheInfo>,
|
||||
}
|
||||
|
||||
impl DNSMatcher {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
current_transaction_id: AtomicU16::new(0),
|
||||
matcher: DashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn retain(&self) {
|
||||
let now = get_current_timestamp();
|
||||
self.matcher.retain(|_, v| (now - v.added) < 10);
|
||||
}
|
||||
|
||||
pub fn generate_transaction_id(&self, client_ip: u32, client_port: u16, origin_transaction_id: u16) -> u16 {
|
||||
let transaction_id = self.current_transaction_id.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
self.matcher.insert(transaction_id, DNSCacheInfo{
|
||||
src_ip: client_ip,
|
||||
src_port: client_port,
|
||||
origin_transaction_id,
|
||||
added: get_current_timestamp(),
|
||||
});
|
||||
transaction_id
|
||||
}
|
||||
|
||||
pub fn get_client_info(&self, transaction_id: u16) -> Option<(u32, u16, u16)> {
|
||||
let res = self.matcher.remove(&transaction_id)?;
|
||||
Some((res.1.src_ip, res.1.src_port, res.1.origin_transaction_id))
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ mod acl_session;
|
||||
mod encrypter;
|
||||
mod system_action;
|
||||
mod file_configuration;
|
||||
mod dns;
|
||||
|
||||
use std::{fs::OpenOptions, io::Write, net::Ipv4Addr, path::Path};
|
||||
|
||||
@ -10,6 +11,7 @@ pub use encrypter::*;
|
||||
pub use command::*;
|
||||
pub use acl_session::*;
|
||||
pub use system_action::*;
|
||||
pub use dns::*;
|
||||
|
||||
mod socks;
|
||||
use rand::Rng;
|
||||
@ -30,6 +32,7 @@ pub struct CachedLoginInfo {
|
||||
pub audit: u32,
|
||||
pub network_id: u32,
|
||||
pub network_name: String,
|
||||
pub network_domain: String,
|
||||
}
|
||||
|
||||
// pub const CRC_HASH: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_XFER);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user