Compare commits

..

No commits in common. "12dda5d35cc4b08105df1b0e3c6b5e53fc86ac78" and "7e7a9ca2e63351c7fe1068e0f94c8d47d42c38e2" have entirely different histories.

7 changed files with 160 additions and 477 deletions

131
Cargo.lock generated
View File

@ -524,16 +524,6 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.10.1" version = "0.10.1"
@ -708,23 +698,6 @@ dependencies = [
"parking_lot_core", "parking_lot_core",
] ]
[[package]]
name = "default-net"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c5a6569a908354d49b10db3c516d69aca1eccd97562fd31c98b13f00b73ca66"
dependencies = [
"dlopen2",
"libc",
"memalloc",
"netlink-packet-core",
"netlink-packet-route",
"netlink-sys",
"once_cell",
"system-configuration",
"windows 0.48.0",
]
[[package]] [[package]]
name = "der" name = "der"
version = "0.7.10" version = "0.7.10"
@ -799,17 +772,6 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "dlopen2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09b4f5f101177ff01b8ec4ecc81eead416a8aa42819a2869311b3420fa114ffa"
dependencies = [
"libc",
"once_cell",
"winapi",
]
[[package]] [[package]]
name = "dns-lookup" name = "dns-lookup"
version = "2.1.1" version = "2.1.1"
@ -1732,12 +1694,6 @@ dependencies = [
"digest", "digest",
] ]
[[package]]
name = "memalloc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df39d232f5c40b0891c10216992c2f250c054105cb1e56f0fc9032db6203ecc1"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.8.0" version = "2.8.0"
@ -1805,54 +1761,6 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "netlink-packet-core"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4"
dependencies = [
"anyhow",
"byteorder",
"netlink-packet-utils",
]
[[package]]
name = "netlink-packet-route"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66"
dependencies = [
"anyhow",
"bitflags 1.3.2",
"byteorder",
"libc",
"netlink-packet-core",
"netlink-packet-utils",
]
[[package]]
name = "netlink-packet-utils"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34"
dependencies = [
"anyhow",
"byteorder",
"paste",
"thiserror 1.0.69",
]
[[package]]
name = "netlink-sys"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd6c30ed10fa69cc491d491b85cc971f6bdeb8e7367b7cde2ee6cc878d583fae"
dependencies = [
"bytes",
"libc",
"log",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@ -2245,7 +2153,6 @@ dependencies = [
"crc32fast", "crc32fast",
"daemonize", "daemonize",
"dashmap 6.1.0", "dashmap 6.1.0",
"default-net",
"dns-lookup", "dns-lookup",
"etherparse", "etherparse",
"futures-util", "futures-util",
@ -2272,13 +2179,11 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"simple-dns", "simple-dns",
"socket2",
"structopt", "structopt",
"tokio", "tokio",
"tokio-util", "tokio-util",
"tracing", "tracing",
"winapi", "winapi",
"windows-sys 0.61.2",
"wintun", "wintun",
] ]
@ -2670,7 +2575,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
dependencies = [ dependencies = [
"core-foundation 0.10.1", "core-foundation",
"core-foundation-sys", "core-foundation-sys",
"jni", "jni",
"log", "log",
@ -2771,7 +2676,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"core-foundation 0.10.1", "core-foundation",
"core-foundation-sys", "core-foundation-sys",
"libc", "libc",
"security-framework-sys", "security-framework-sys",
@ -3288,27 +3193,6 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "system-configuration"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation 0.9.4",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "tar" name = "tar"
version = "0.4.45" version = "0.4.45"
@ -4038,15 +3922,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets 0.48.5",
]
[[package]] [[package]]
name = "windows" name = "windows"
version = "0.52.0" version = "0.52.0"
@ -4447,7 +4322,7 @@ dependencies = [
"libloading", "libloading",
"log", "log",
"thiserror 1.0.69", "thiserror 1.0.69",
"windows 0.52.0", "windows",
] ]
[[package]] [[package]]

View File

@ -44,8 +44,6 @@ ipnet = "2.12.0"
arc-swap = "1.9.0" arc-swap = "1.9.0"
rustls-native-certs = "0.8.3" rustls-native-certs = "0.8.3"
simple-dns = "0.11.2" simple-dns = "0.11.2"
default-net = "0.22.0"
socket2 = "0.6.3"
# rolling-file = { path = "../rolling-file" } # rolling-file = { path = "../rolling-file" }
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
@ -56,7 +54,6 @@ daemonize = "0.5.0"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
wintun = "0.4.0" wintun = "0.4.0"
winapi = "0.3.9" winapi = "0.3.9"
windows-sys = "0.61.2"
[features] [features]
tun = [] tun = []

View File

@ -1,10 +1,10 @@
use arc_swap::ArcSwap; use arc_swap::ArcSwap;
use dashmap::DashMap; use dashmap::DashMap;
use default_net::Interface;
use prost::Message; use prost::Message;
use quinn::Endpoint; use quinn::Endpoint;
use rsa::RsaPrivateKey; use rsa::RsaPrivateKey;
use sdlan_sn_rs::config::{AF_INET, AF_INET6}; use sdlan_sn_rs::config::{AF_INET, AF_INET6};
use tokio::net::UdpSocket;
use std::any::Any; use std::any::Any;
use std::future::Future; use std::future::Future;
use std::net::SocketAddr; use std::net::SocketAddr;
@ -12,22 +12,17 @@ use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, AtomicU8, Ordering};
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use std::time::Duration; use std::time::Duration;
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
use tokio::net::UdpSocket;
use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::Sender;
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
use crate::network::{ArpTable, RouteTable2}; use crate::network::{ArpTable, RouteTable2};
use crate::pb::{
encode_to_tcp_message, encode_to_udp_message, SdlArpRequest, SdlEmpty, SdlStunProbe,
SdlStunProbeReply,
};
use crate::quic::quic_init; use crate::quic::quic_init;
use crate::tcp::{get_quic_write_conn, NatType, PacketType, StunProbeAttr}; use crate::{CommandLine, ConnectionInfo, DNSMatcher, MyEncryptor, RuleCache, get_base_dir};
use crate::utils::Socket; use crate::pb::{
use crate::{ SdlArpRequest, SdlEmpty, SdlStunProbe, SdlStunProbeReply, encode_to_tcp_message, encode_to_udp_message
get_base_dir, get_default_interface, CommandLine, ConnectionInfo, DNSMatcher, MyEncryptor,
RuleCache,
}; };
use crate::tcp::{NatType, PacketType, StunProbeAttr, get_quic_write_conn};
use crate::utils::{Socket};
use sdlan_sn_rs::peer::{IpSubnet, V6Info}; use sdlan_sn_rs::peer::{IpSubnet, V6Info};
@ -37,7 +32,7 @@ use super::device::{DeviceConfig, Mode};
use super::tun::{new_iface, Iface}; use super::tun::{new_iface, Iface};
use tokio::fs::File; use tokio::fs::File;
use sdlan_sn_rs::utils::{gen_rsa_keys, load_private_key_file, save_to_file, Mac}; use sdlan_sn_rs::utils::{Mac, gen_rsa_keys, load_private_key_file, save_to_file};
use sdlan_sn_rs::utils::{Result, SDLanError}; use sdlan_sn_rs::utils::{Result, SDLanError};
static EDGE: OnceCell<Node> = OnceCell::new(); static EDGE: OnceCell<Node> = OnceCell::new();
@ -56,7 +51,7 @@ pub async fn init_edge(
udp_sock_for_global_dns: Arc<UdpSocket>, udp_sock_for_global_dns: Arc<UdpSocket>,
hostname: String, hostname: String,
server_ip: String, server_ip: String,
install_channel: String, install_channel: String
) -> Result<()> { ) -> Result<()> {
// gen public key // gen public key
let rsa_path = format!("{}/.client", get_base_dir()); let rsa_path = format!("{}/.client", get_base_dir());
@ -74,33 +69,13 @@ pub async fn init_edge(
// let edge_uuid = create_or_load_uuid("")?; // let edge_uuid = create_or_load_uuid("")?;
//let node_conf = parse_config(edge_uuid, &args).await?; //let node_conf = parse_config(edge_uuid, &args).await?;
let default_interface = match get_default_interface() { let Ok(sock_v4) = Socket::build(node_conf._local_port, true, false, args.tos).await else {
Ok(interface) => {
println!("get default interface: {:?}", interface);
Some(interface)
}
Err(e) => {
println!("failed to get default net interface: {}", e.as_str());
None
}
};
let Ok(sock_v4) = Socket::build(
node_conf._local_port,
true,
false,
args.tos,
&default_interface,
)
.await
else {
panic!("failed to build sock for sock v4"); panic!("failed to build sock for sock v4");
}; };
let mut sock_multicast = None; let mut sock_multicast = None;
if !node_conf._drop_multicast { if !node_conf._drop_multicast {
sock_multicast = sock_multicast = Some(Socket::build(MULTICAST_PORT, true, true, 0).await?);
Some(Socket::build(MULTICAST_PORT, true, true, 0, &default_interface).await?);
} }
// let sock_multicast = Socket::build(MULTICAST_PORT, true, true, 0).await?; // let sock_multicast = Socket::build(MULTICAST_PORT, true, true, 0).await?;
// allow multicast // allow multicast
@ -113,7 +88,6 @@ pub async fn init_edge(
pubkey, pubkey,
node_conf, node_conf,
sock_v4, sock_v4,
&default_interface,
sock_multicast, sock_multicast,
// token, // token,
// network_code, // network_code,
@ -129,8 +103,7 @@ pub async fn init_edge(
install_channel, install_channel,
); );
edge.route_table edge.route_table.parse_and_add_route(&args.route_file, &args.route_str);
.parse_and_add_route(&args.route_file, &args.route_str);
let matcher = Arc::clone(&edge.dns_matcher); let matcher = Arc::clone(&edge.dns_matcher);
do_init_edge(edge)?; do_init_edge(edge)?;
@ -174,7 +147,7 @@ pub struct StartStopInfo {
pub struct StringToken<T>(RwLock<T>); pub struct StringToken<T>(RwLock<T>);
impl<T: Clone> StringToken<T> { impl <T: Clone> StringToken<T> {
pub fn new(value: T) -> Self { pub fn new(value: T) -> Self {
Self(RwLock::new(value)) Self(RwLock::new(value))
} }
@ -222,7 +195,7 @@ pub struct Node {
pub access_token: StringToken<String>, pub access_token: StringToken<String>,
pub session_token: StringToken<Vec<u8>>, pub session_token: StringToken<Vec<u8>>,
pub hostname: RwLock<String>, pub hostname: RwLock<String>,
pub quic_endpoint: Endpoint, pub quic_endpoint: Endpoint,
@ -241,6 +214,7 @@ pub struct Node {
// user token info // user token info
// pub _token: Mutex<String>, // pub _token: Mutex<String>,
// pub network_code: Mutex<String>, // pub network_code: Mutex<String>,
pub device_config: DeviceConfig, pub device_config: DeviceConfig,
pub device: Iface, pub device: Iface,
@ -248,6 +222,7 @@ pub struct Node {
pub authorized: AtomicBool, pub authorized: AtomicBool,
// pub header_key: RwLock<Arc<Vec<u8>>>, // pub header_key: RwLock<Arc<Vec<u8>>>,
// pub encrypt_key: RwLock<Arc<Vec<u8>>>, // pub encrypt_key: RwLock<Arc<Vec<u8>>>,
pub rsa_pubkey: String, pub rsa_pubkey: String,
pub rsa_private: RsaPrivateKey, pub rsa_private: RsaPrivateKey,
@ -287,6 +262,7 @@ pub struct Node {
//cookie_match: DashMap<u32, oneshot::Sender<SdlStunProbeReply>>, //cookie_match: DashMap<u32, oneshot::Sender<SdlStunProbeReply>>,
pub cookie_match: Queryer, pub cookie_match: Queryer,
// packet_id_match: DashMap<u32, oneshot::Sender<RegisterSuperFeedback>>, // packet_id_match: DashMap<u32, oneshot::Sender<RegisterSuperFeedback>>,
} }
@ -302,14 +278,14 @@ impl Node {
} }
pub async fn start_without_feedback( pub async fn start_without_feedback(
&self, &self,
access_token: String, access_token: String,
network_id: u32, network_id: u32,
network_domain: &String, network_domain: &String,
ip_net: u32, ip_net: u32,
ip_net_bit_len: u8, ip_net_bit_len: u8,
identity_id: u32, identity_id: u32,
hostname: Option<String>, hostname: Option<String>
) -> Result<()> { ) -> Result<()> {
if let Some(host) = hostname { if let Some(host) = hostname {
let idfile = format!("{}/.host", get_base_dir()); let idfile = format!("{}/.host", get_base_dir());
@ -379,30 +355,25 @@ impl Node {
// *self.network_code.lock().unwrap() = network_code; // *self.network_code.lock().unwrap() = network_code;
let id = self.get_next_packet_id(); let id = self.get_next_packet_id();
let res = self let res = self.cookie_match.do_action_and_wait_for(
.cookie_match 0,
.do_action_and_wait_for( || async {
0, let _ = self
|| async { .start_stop_sender
let _ = self .send(StartStopInfo {
.start_stop_sender is_start: true,
.send(StartStopInfo { pkt_id: Some(id),
is_start: true, })
pkt_id: Some(id), .await;
}) debug!("start with feedback");
.await; },
debug!("start with feedback"); timeout
}, ).await?;
timeout,
)
.await?;
if let Ok(res) = res.downcast() { if let Ok(res) = res.downcast() {
Ok(*res) Ok(*res)
} else { } else {
Err(SDLanError::ConvertError( Err(SDLanError::ConvertError("failed to convert feedback to RSFeedback".to_owned()))
"failed to convert feedback to RSFeedback".to_owned(),
))
} }
} }
@ -423,7 +394,6 @@ impl Node {
pubkey: String, pubkey: String,
config: NodeConfig, config: NodeConfig,
sock: Socket, sock: Socket,
iface: &Option<Interface>,
multicast_sock: Option<Socket>, multicast_sock: Option<Socket>,
// tcpsock: TCPSocket, // tcpsock: TCPSocket,
// token: &str, // token: &str,
@ -446,12 +416,14 @@ impl Node {
}; };
Self { Self {
#[cfg(any(feature = "tun", target_os = "windows"))] #[cfg(any(feature = "tun", target_os = "windows"))]
arp_table: ArpTable::new(), arp_table: ArpTable::new(),
packet_id: AtomicU32::new(1), packet_id: AtomicU32::new(1),
encryptor: ArcSwap::from(Arc::new(MyEncryptor::new())), encryptor: ArcSwap::from(Arc::new(MyEncryptor::new())),
// encryptor: RwLock::new(MyEncryptor::new()), // encryptor: RwLock::new(MyEncryptor::new()),
network_id: AtomicU32::new(0), network_id: AtomicU32::new(0),
hostname: RwLock::new(hostname), hostname: RwLock::new(hostname),
@ -465,7 +437,7 @@ impl Node {
udp_sock_for_global_dns: udp_sock_for_global_dns, udp_sock_for_global_dns: udp_sock_for_global_dns,
dns_matcher: Arc::new(DNSMatcher::new()), dns_matcher: Arc::new(DNSMatcher::new()),
quic_endpoint: quic_init(iface), quic_endpoint: quic_init(),
identity_id: IdentityID::new(0), identity_id: IdentityID::new(0),
access_token: StringToken::new(String::new()), access_token: StringToken::new(String::new()),
@ -473,6 +445,7 @@ impl Node {
// _token: Mutex::new(token.to_owned()), // _token: Mutex::new(token.to_owned()),
// network_code: Mutex::new(network_code.to_owned()), // network_code: Mutex::new(network_code.to_owned()),
start_stop_sender: start_stop, start_stop_sender: start_stop,
connection_chan: connecting_chan, connection_chan: connecting_chan,
@ -540,7 +513,7 @@ impl Node {
} }
*/ */
/* /*
pub fn get_encrypt_key(&self) -> Arc<Vec<u8>> { pub fn get_encrypt_key(&self) -> Arc<Vec<u8>> {
self.encrypt_key.read().unwrap().clone() self.encrypt_key.read().unwrap().clone()
} }
@ -595,7 +568,7 @@ impl Node {
} }
*/ */
pub async fn send_arp_request(&self, gw_ip: u32, real_ip: u32) -> Result<()> { pub async fn send_arp_request(&self, gw_ip: u32, real_ip: u32) -> Result<()>{
let arp_request = SdlArpRequest { let arp_request = SdlArpRequest {
// pkt_id: id, // pkt_id: id,
target_ip: gw_ip, target_ip: gw_ip,
@ -693,24 +666,12 @@ impl Node {
step: 0, step: 0,
}; };
let result = self let result = self.cookie_match.send_message_to_udp_and_wait_for(&self.udp_sock_v4, cookie, probe, PacketType::StunProbe as u8, to_server, Duration::from_secs(3)).await?;
.cookie_match
.send_message_to_udp_and_wait_for(
&self.udp_sock_v4,
cookie,
probe,
PacketType::StunProbe as u8,
to_server,
Duration::from_secs(3),
)
.await?;
if let Ok(res) = result.downcast() { if let Ok(res) = result.downcast() {
return Ok(*res); return Ok(*res);
} }
return Err(SDLanError::ConvertError( return Err(SDLanError::ConvertError("failed to convert to StunprobeReply".to_owned()))
"failed to convert to StunprobeReply".to_owned(),
));
// println!("==> sending probe request: {:?}", probe); // println!("==> sending probe request: {:?}", probe);
} }
} }
@ -916,15 +877,7 @@ impl Queryer {
} }
} }
pub async fn send_message_to_udp_and_wait_for<T: Message>( pub async fn send_message_to_udp_and_wait_for<T: Message>(&self, sock: &Socket, id: u32, message: T, packet_type: u8, to_server: &SocketAddr, timeout: Duration) -> Result<BoxedProstMessage> {
&self,
sock: &Socket,
id: u32,
message: T,
packet_type: u8,
to_server: &SocketAddr,
timeout: Duration,
) -> Result<BoxedProstMessage> {
let (tx, rx) = tokio::sync::oneshot::channel(); let (tx, rx) = tokio::sync::oneshot::channel();
self.mailbox.insert(id, tx); self.mailbox.insert(id, tx);
@ -950,15 +903,11 @@ impl Queryer {
Err(SDLanError::IOError("timed out".to_string())) Err(SDLanError::IOError("timed out".to_string()))
} }
} }
} }
pub async fn do_action_and_wait_for<T, F>( pub async fn do_action_and_wait_for<T, F>(&self, id: u32, action: T, timeout: Duration) -> Result<BoxedProstMessage>
&self, where
id: u32,
action: T,
timeout: Duration,
) -> Result<BoxedProstMessage>
where
F: Future<Output = ()>, F: Future<Output = ()>,
T: Fn() -> F, T: Fn() -> F,
{ {
@ -984,13 +933,7 @@ impl Queryer {
} }
} }
pub async fn send_message_to_quic_and_wait_for<T: Message>( pub async fn send_message_to_quic_and_wait_for<T: Message>(&self, id: u32, message: T, packet_type: u8, timeout: Duration) -> Result<BoxedProstMessage> {
&self,
id: u32,
message: T,
packet_type: u8,
timeout: Duration,
) -> Result<BoxedProstMessage> {
let (tx, rx) = tokio::sync::oneshot::channel(); let (tx, rx) = tokio::sync::oneshot::channel();
self.mailbox.insert(id, tx); self.mailbox.insert(id, tx);
@ -1014,4 +957,4 @@ impl Queryer {
} }
} }
} }
} }

View File

@ -2,16 +2,18 @@ use bytes::Bytes;
#[cfg(not(feature = "tun"))] #[cfg(not(feature = "tun"))]
use bytes::BytesMut; use bytes::BytesMut;
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
use bytes::BytesMut; use bytes::{BytesMut};
use etherparse::Ethernet2Header;
#[cfg(not(feature = "tun"))]
use etherparse::{IpSlice, LinkSlice, NetSlice, SlicedPacket, TransportSlice};
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
use etherparse::{NetSlice, PacketBuilder, SlicedPacket, TransportSlice}; use etherparse::{NetSlice, PacketBuilder, SlicedPacket, TransportSlice};
#[cfg(not(feature = "tun"))]
use etherparse::{IpSlice, LinkSlice, NetSlice, SlicedPacket, TransportSlice};
use etherparse::{Ethernet2Header};
use ipnet::Ipv4Net; use ipnet::Ipv4Net;
use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL; use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL;
use sdlan_sn_rs::utils::{ip_to_string, is_ipv6_multicast, net_bit_len_to_mask, Mac, SDLanError}; use sdlan_sn_rs::utils::{
Mac, SDLanError, ip_to_string, is_ipv6_multicast, net_bit_len_to_mask
};
use std::ffi::CStr; use std::ffi::CStr;
use std::ffi::{c_char, c_int}; use std::ffi::{c_char, c_int};
use std::fs::{self, OpenOptions}; use std::fs::{self, OpenOptions};
@ -36,8 +38,8 @@ use crate::get_edge;
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
use crate::network::parse_dns_payload; use crate::network::parse_dns_payload;
#[cfg(not(feature = "tun"))] #[cfg(not(feature = "tun"))]
use crate::network::{parse_dns_payload, ArpHdr, EthHdr, ARP_REPLY}; use crate::network::{ARP_REPLY, ArpHdr, EthHdr, parse_dns_payload};
use crate::network::{send_packet_to_net, Node}; use crate::network::{Node, send_packet_to_net};
#[cfg(not(feature = "tun"))] #[cfg(not(feature = "tun"))]
use crate::pb::SdlArpResponse; use crate::pb::SdlArpResponse;
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
@ -126,12 +128,7 @@ impl Iface {
}; };
let has_resolvectl = check_has_resolvectl(); let has_resolvectl = check_has_resolvectl();
Ok(Iface { Ok(Iface { fd: fs, mode, name, has_resolvectl })
fd: fs,
mode,
name,
has_resolvectl,
})
} else { } else {
Err(SDLanError::NormalError("failed to setup tun")) Err(SDLanError::NormalError("failed to setup tun"))
} }
@ -180,7 +177,7 @@ impl Iface {
} }
} }
node.route_table.apply_system(0); node.route_table.apply_system();
if node.config.allow_routing.load(Ordering::Relaxed) { if node.config.allow_routing.load(Ordering::Relaxed) {
set_allow_routing(); set_allow_routing();
@ -238,7 +235,8 @@ impl TunTapPacketHandler for Iface {
} }
} }
#[cfg(feature = "abc")]
#[cfg(feature="abc")]
async fn handle_packet_from_device( async fn handle_packet_from_device(
&self, &self,
data: BytesMut, data: BytesMut,
@ -261,7 +259,7 @@ impl TunTapPacketHandler for Iface {
use bytes::Bytes; use bytes::Bytes;
if hdr.ether_type == EtherType::ARP { if hdr.ether_type == EtherType::ARP {
use crate::network::{ArpHdr, ARP_REQUEST}; use crate::network::{ARP_REQUEST, ArpHdr};
let arp = ArpHdr::from_slice(&data); let arp = ArpHdr::from_slice(&data);
match arp.opcode { match arp.opcode {
@ -269,14 +267,14 @@ impl TunTapPacketHandler for Iface {
let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32; let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32;
if edge.device_config.contains(&Ipv4Addr::from_bits(dest_ip)) { if edge.device_config.contains(&Ipv4Addr::from_bits(dest_ip)) {
let _ = edge.send_arp_request(dest_ip, dest_ip).await; let _ = edge.send_arp_request(dest_ip, dest_ip).await;
} else { } else {
if let Some((_, real_ip)) = edge.route_table.lookup(dest_ip) { if let Some((_, real_ip)) = edge.route_table.lookup(dest_ip) {
let real_ip = u32::from_be_bytes(real_ip.octets()); let real_ip = u32::from_be_bytes(real_ip.octets());
let _ = edge.send_arp_request(dest_ip, real_ip).await; let _ = edge.send_arp_request(dest_ip, real_ip).await;
} }
} }
/* /*
let request = SdlArpRequest { let request = SdlArpRequest {
pkt_id: edge.get_next_packet_id(), pkt_id: edge.get_next_packet_id(),
target_ip: dest_ip, target_ip: dest_ip,
@ -298,6 +296,7 @@ impl TunTapPacketHandler for Iface {
if let Some(ip) = headers.net { if let Some(ip) = headers.net {
match ip { match ip {
etherparse::NetHeaders::Ipv4(ipv4, _) => { etherparse::NetHeaders::Ipv4(ipv4, _) => {
use crate::FiveTuple; use crate::FiveTuple;
use etherparse::IpNumber; use etherparse::IpNumber;
@ -316,7 +315,7 @@ impl TunTapPacketHandler for Iface {
edge.rule_cache.touch_packet(out_five_tuple); edge.rule_cache.touch_packet(out_five_tuple);
} }
// is tcp // is tcp
} }
IpNumber::UDP => { IpNumber::UDP => {
if let Some(udp) = transport.udp() { if let Some(udp) = transport.udp() {
@ -330,28 +329,27 @@ impl TunTapPacketHandler for Iface {
edge.rule_cache.touch_packet(out_five_tuple); edge.rule_cache.touch_packet(out_five_tuple);
} }
} }
_other => {} _other => {
}
} }
} }
if u32::from_be_bytes(ipv4.destination) == DNS_IP { if u32::from_be_bytes(ipv4.destination) == DNS_IP {
// should send to dns // should send to dns
parse_dns_payload(edge, &headers.payload.slice()); parse_dns_payload(edge, &headers.payload.slice());
if let Err(e) = edge if let Err(e) = edge.udp_sock_for_dns.send_to(&data[14..], format!("{}:15353", edge.server_ip)).await {
.udp_sock_for_dns
.send_to(&data[14..], format!("{}:15353", edge.server_ip))
.await
{
error!("failed to send request to 15353: {}", e); error!("failed to send request to 15353: {}", e);
} }
// edge.udp_sock_for_dns.send_to() // edge.udp_sock_for_dns.send_to()
return Ok(()); return Ok(())
} }
} }
_other => { _other => {
// just ignore // just ignore
} }
} }
} }
let target = hdr.destination; let target = hdr.destination;
@ -361,8 +359,8 @@ impl TunTapPacketHandler for Iface {
let size = data.len(); let size = data.len();
let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else { let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else {
// let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else { // let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else {
// let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else { // let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else {
error!("failed to encrypt packet request"); error!("failed to encrypt packet request");
return Ok(()); return Ok(());
}; };
@ -406,11 +404,11 @@ impl TunTapPacketHandler for Iface {
}; };
// if let Some(eth) = headers.link { // if let Some(eth) = headers.link {
use bytes::Bytes;
use etherparse::EtherType; use etherparse::EtherType;
use bytes::Bytes;
if eth.ether_type == EtherType::ARP { if eth.ether_type == EtherType::ARP {
use crate::network::{ArpHdr, ARP_REQUEST}; use crate::network::{ARP_REQUEST, ArpHdr};
let arp = ArpHdr::from_slice(&data); let arp = ArpHdr::from_slice(&data);
match arp.opcode { match arp.opcode {
@ -424,7 +422,7 @@ impl TunTapPacketHandler for Iface {
} }
if edge.device_config.contains(&Ipv4Addr::from_bits(dest_ip)) { if edge.device_config.contains(&Ipv4Addr::from_bits(dest_ip)) {
let _ = edge.send_arp_request(dest_ip, dest_ip).await; let _ = edge.send_arp_request(dest_ip, dest_ip).await;
} else { } else {
if let Some((_, real_ip)) = edge.route_table.lookup(dest_ip) { if let Some((_, real_ip)) = edge.route_table.lookup(dest_ip) {
let real_ip = u32::from_be_bytes(real_ip.octets()); let real_ip = u32::from_be_bytes(real_ip.octets());
@ -442,7 +440,8 @@ impl TunTapPacketHandler for Iface {
return Ok(()); return Ok(());
}; };
if let Some(ip) = net_slice.net { if let Some(ip) = net_slice.net{
match ip { match ip {
NetSlice::Ipv4(ipv4) => { NetSlice::Ipv4(ipv4) => {
use crate::FiveTuple; use crate::FiveTuple;
@ -468,20 +467,13 @@ impl TunTapPacketHandler for Iface {
proto: IpNumber::UDP.0, proto: IpNumber::UDP.0,
}; };
edge.rule_cache.touch_packet(out_five_tuple); edge.rule_cache.touch_packet(out_five_tuple);
if u32::from_be_bytes(ipv4.header().destination()) == DNS_IP { if u32::from_be_bytes(ipv4.header().destination()) == DNS_IP {
// should send to dns // should send to dns
let source_ip = u32::from_be_bytes(ipv4.header().source()); let source_ip = u32::from_be_bytes(ipv4.header().source());
parse_dns_payload( parse_dns_payload(edge, udp.payload(), layer3, source_ip, udp.source_port()).await;
edge,
udp.payload(),
layer3,
source_ip,
udp.source_port(),
)
.await;
// edge.udp_sock_for_dns.send_to() // edge.udp_sock_for_dns.send_to()
return Ok(()); return Ok(())
} }
} }
_other => { _other => {
@ -496,18 +488,19 @@ impl TunTapPacketHandler for Iface {
// just ignore // just ignore
} }
} }
} }
let target = eth.destination; let target = eth.destination;
if is_ipv6_multicast(&target) { if is_ipv6_multicast(&target) {
return Ok(()); return Ok(());
} }
let size = data.len(); let size = data.len();
let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else { let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else {
// let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else { // let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else {
// let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else { // let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else {
error!("failed to encrypt packet request"); error!("failed to encrypt packet request");
return Ok(()); return Ok(());
}; };
@ -528,6 +521,7 @@ impl TunTapPacketHandler for Iface {
Ok(()) Ok(())
} }
} }
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
@ -595,7 +589,7 @@ impl TunTapPacketHandler for Iface {
edge.arp_table.set(from_ip, arp.shwaddr); edge.arp_table.set(from_ip, arp.shwaddr);
/* /*
use crate::network::{ARP_REPLY, ArpRequestInfo, send_arp_request}; use crate::network::{ARP_REPLY, ArpRequestInfo, send_arp_request};
send_arp_request(ArpRequestInfo::Set { send_arp_request(ArpRequestInfo::Set {
@ -650,9 +644,10 @@ impl TunTapPacketHandler for Iface {
} }
} }
ARP_REPLY => { ARP_REPLY => {
debug!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes()); debug!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes());
if dest_ip == self_ip { if dest_ip == self_ip {
/* /*
use crate::network::{ArpRequestInfo, arp_arrived, send_arp_request}; use crate::network::{ArpRequestInfo, arp_arrived, send_arp_request};
send_arp_request(ArpRequestInfo::Set { send_arp_request(ArpRequestInfo::Set {
@ -717,7 +712,10 @@ impl TunTapPacketHandler for Iface {
Ok(()) Ok(())
} }
async fn handle_packet_from_device(&self, mut header: BytesMut) -> std::io::Result<()> { async fn handle_packet_from_device(
&self,
mut header: BytesMut,
) -> std::io::Result<()> {
use etherparse::IpHeaders; use etherparse::IpHeaders;
let eee = get_edge(); let eee = get_edge();
@ -735,8 +733,10 @@ impl TunTapPacketHandler for Iface {
return Ok(()); return Ok(());
}; };
match net { match net {
NetSlice::Ipv4(ipv4) => { NetSlice::Ipv4(ipv4) => {
let dstip = u32::from_be_bytes(ipv4.header().destination()); let dstip = u32::from_be_bytes(ipv4.header().destination());
// let dstip = u32::from_be_bytes(ipv4hdr.0.destination); // let dstip = u32::from_be_bytes(ipv4hdr.0.destination);
debug!("packet dst ip: {:?}", ip_to_string(&dstip)); debug!("packet dst ip: {:?}", ip_to_string(&dstip));
@ -745,9 +745,7 @@ impl TunTapPacketHandler for Iface {
debug!("packet src ip: {:?}", ip_to_string(&src)); debug!("packet src ip: {:?}", ip_to_string(&src));
// packet should be sent to dev // packet should be sent to dev
debug!("got {} bytes from tun", data.len()); debug!("got {} bytes from tun", data.len());
if (!eee.config.allow_routing.load(Ordering::Relaxed)) if (!eee.config.allow_routing.load(Ordering::Relaxed)) && (src != eee.device_config.get_ip()) {
&& (src != eee.device_config.get_ip())
{
info!("dropping routed packet"); info!("dropping routed packet");
return Ok(()); return Ok(());
} }
@ -766,19 +764,14 @@ impl TunTapPacketHandler for Iface {
// should do the dns request // should do the dns request
// println!("request for dns"); // println!("request for dns");
parse_dns_payload( parse_dns_payload(eee, udp.payload(), &data, src, udp.source_port()).await;
eee,
udp.payload(),
&data,
src,
udp.source_port(),
)
.await;
// edge.udp_sock_for_dns.send_to() // edge.udp_sock_for_dns.send_to()
return Ok(()); return Ok(());
} }
} }
_other => {} _other => {
}
} }
match eee.arp_table.get(dstip) { match eee.arp_table.get(dstip) {
@ -795,6 +788,7 @@ impl TunTapPacketHandler for Iface {
let crc = caculate_crc(&data); let crc = caculate_crc(&data);
header.unsplit(data); header.unsplit(data);
// packet.extend_from_slice(&etherheader.to_bytes()[..]); // packet.extend_from_slice(&etherheader.to_bytes()[..]);
// packet.extend_from_slice(&data); // packet.extend_from_slice(&data);
header.extend_from_slice(&crc.to_be_bytes()); header.extend_from_slice(&crc.to_be_bytes());
@ -832,25 +826,26 @@ impl TunTapPacketHandler for Iface {
src.to_be_bytes(), src.to_be_bytes(),
dstip.to_be_bytes() dstip.to_be_bytes()
); );
debug!( debug!("no mac found for ip {:?}, sending arp request", dstip.to_be_bytes());
"no mac found for ip {:?}, sending arp request",
dstip.to_be_bytes()
);
// let _ = eee.send_arp_request(dstip, dstip).await; // let _ = eee.send_arp_request(dstip, dstip).await;
if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) { if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) {
let _ = eee.send_arp_request(dstip, dstip).await; let _ = eee.send_arp_request(dstip, dstip).await;
} else { } else {
if let Some((_, real_ip)) = eee.route_table.lookup(dstip) { if let Some((_, real_ip)) = eee.route_table.lookup(dstip) {
let real_ip = u32::from_be_bytes(real_ip.octets()); let real_ip = u32::from_be_bytes(real_ip.octets());
let _ = eee.send_arp_request(dstip, real_ip).await; let _ = eee.send_arp_request(dstip, real_ip).await;
} }
} }
} }
} }
} }
} }
NetSlice::Ipv6(ipv6) => {} NetSlice::Ipv6(ipv6) => {
}
} }
Ok(()) Ok(())
} }
@ -862,7 +857,9 @@ pub fn get_install_channel() -> String {
fn check_has_resolvectl() -> bool { fn check_has_resolvectl() -> bool {
return false; return false;
let res = Command::new("resolvectl").arg("status").output(); let res = Command::new("resolvectl")
.arg("status")
.output();
if let Ok(_) = res { if let Ok(_) = res {
true true
} else { } else {
@ -870,7 +867,7 @@ fn check_has_resolvectl() -> bool {
} }
} }
fn add_dns_route(dev_name: &str) -> Result<()> { fn add_dns_route(dev_name: &str) -> Result<()>{
Command::new("route") Command::new("route")
.arg("add") .arg("add")
.arg("-host") .arg("-host")
@ -882,7 +879,10 @@ fn add_dns_route(dev_name: &str) -> Result<()> {
Ok(()) Ok(())
} }
fn add_resolvectl(name: &str, network_domain: &str) -> Result<()> { fn add_resolvectl(
name: &str,
network_domain: &str,
) -> Result<()>{
Command::new("resolvectl") Command::new("resolvectl")
.arg("dns") .arg("dns")
.arg(name) .arg(name)
@ -898,7 +898,12 @@ fn add_resolvectl(name: &str, network_domain: &str) -> Result<()> {
Ok(()) Ok(())
} }
fn set_dns(iface: &Iface, name: &str, network_domain: &str, gw: &str) -> Result<()> { fn set_dns(
iface: &Iface,
name: &str,
network_domain: &str,
gw: &str
) -> Result<()> {
error!("network_domain = {}", network_domain); error!("network_domain = {}", network_domain);
if iface.has_resolvectl { if iface.has_resolvectl {
add_resolvectl(name, network_domain)?; add_resolvectl(name, network_domain)?;
@ -924,17 +929,10 @@ pub fn restore_dns() -> Result<()> {
/// ///
/// - `new_nameservers`: 新的 nameserver 列表IPv4/IPv6 字符串) /// - `new_nameservers`: 新的 nameserver 列表IPv4/IPv6 字符串)
/// - `keep_other_ns`: 是否保留原有的 nameservertrue = 追加到新列表后false = 完全替换) /// - `keep_other_ns`: 是否保留原有的 nameservertrue = 追加到新列表后false = 完全替换)
pub fn modify_resolv_conf( pub fn modify_resolv_conf(new_nameservers: &[String], search_domain: &str, keep_other_ns: bool) -> Result<()> {
new_nameservers: &[String],
search_domain: &str,
keep_other_ns: bool,
) -> Result<()> {
let path = Path::new(RESOLV_FILE); let path = Path::new(RESOLV_FILE);
if !path.exists() { if !path.exists() {
return Err(SDLanError::IOError(format!( return Err(SDLanError::IOError(format!("{} does not exists", RESOLV_FILE)));
"{} does not exists",
RESOLV_FILE
)));
} }
// 读取原文件权限和元数据 // 读取原文件权限和元数据
@ -952,7 +950,7 @@ pub fn modify_resolv_conf(
lines.push(format!("nameserver {}", ns)) lines.push(format!("nameserver {}", ns))
} }
lines.push(format!("search {}", search_domain)); lines.push(format!("search {}", search_domain));
/* /*
let mut inserted = false; let mut inserted = false;
let mut encounted_nameserver = false; let mut encounted_nameserver = false;
let mut search_added = false; let mut search_added = false;
@ -1022,10 +1020,7 @@ fn backup_resolv_conf() -> Result<()> {
let dst = Path::new(RESOLV_FILE_BACKUP); let dst = Path::new(RESOLV_FILE_BACKUP);
if !src.exists() { if !src.exists() {
return Err(SDLanError::IOError(format!( return Err(SDLanError::IOError(format!("{} does not exists", RESOLV_FILE)));
"{} does not exists",
RESOLV_FILE
)));
// anyhow::bail!("Source /etc/resolv.conf does not exist"); // anyhow::bail!("Source /etc/resolv.conf does not exist");
} }
@ -1059,10 +1054,7 @@ fn restore_resolv_conf() -> Result<()> {
let dst = Path::new(RESOLV_FILE); let dst = Path::new(RESOLV_FILE);
if !src.exists() { if !src.exists() {
return Err(SDLanError::IOError(format!( return Err(SDLanError::IOError(format!("{} does not exists", RESOLV_FILE_BACKUP)));
"{} does not exists",
RESOLV_FILE_BACKUP
)));
} }
// 如果目标是符号链接,先删除链接再复制(避免写入到链接指向位置) // 如果目标是符号链接,先删除链接再复制(避免写入到链接指向位置)
@ -1102,7 +1094,7 @@ pub fn del_route(net: &Ipv4Net, gw: &Ipv4Addr) -> Result<()> {
Ok(()) Ok(())
} }
pub fn add_route(net: &Ipv4Net, gw: &Ipv4Addr, _ifidx: u32) -> Result<()> { pub fn add_route(net: &Ipv4Net, gw: &Ipv4Addr) -> Result<()> {
let res = Command::new("route") let res = Command::new("route")
.arg("add") .arg("add")
.arg("-net") .arg("-net")
@ -1160,17 +1152,13 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) {
debug!("got arp response: {:?}", data); debug!("got arp response: {:?}", data);
if data.target_mac.len() != 6 { if data.target_mac.len() != 6 {
// invalid target_mac // invalid target_mac
error!( error!("invalid target_mac: {:?}, ip={}", data.target_mac, ip_to_string(&data.target_ip));
"invalid target_mac: {:?}, ip={}",
data.target_mac,
ip_to_string(&data.target_ip)
);
return; return;
} }
let ip = data.origin_ip; let ip = data.origin_ip;
let mac = data.target_mac.try_into().unwrap(); let mac = data.target_mac.try_into().unwrap();
edge.arp_table.set(ip, mac); edge.arp_table.set(ip, mac);
edge.arp_table.arp_arrived(ip, mac).await; edge.arp_table.arp_arrived(ip, mac).await;
} }
@ -1180,11 +1168,7 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) {
debug!("got arp response: {:?}", data); debug!("got arp response: {:?}", data);
if data.target_mac.len() != 6 { if data.target_mac.len() != 6 {
// invalid target_mac // invalid target_mac
error!( error!("invalid target_mac: {:?}, ip={}", data.target_mac, ip_to_string(&data.target_ip));
"invalid target_mac: {:?}, ip={}",
data.target_mac,
ip_to_string(&data.target_ip)
);
return; return;
} }
// TODO: construct the arp reply, and write to tun; // TODO: construct the arp reply, and write to tun;
@ -1195,12 +1179,12 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) {
write_arp_to_device(edge, src_mac, src_ip); write_arp_to_device(edge, src_mac, src_ip);
} }
#[cfg(not(feature = "tun"))] #[cfg(not(feature="tun"))]
pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) { pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) {
let dst_mac = edge.device_config.get_mac(); let dst_mac = edge.device_config.get_mac();
let dst_ip = edge.device_config.get_ip(); let dst_ip = edge.device_config.get_ip();
let hdr = ArpHdr { let hdr = ArpHdr{
ethhdr: EthHdr { ethhdr: EthHdr {
dest: dst_mac, dest: dst_mac,
src: src_mac, src: src_mac,
@ -1214,14 +1198,11 @@ pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) {
shwaddr: src_mac, shwaddr: src_mac,
sipaddr: [((src_ip >> 16) as u16) & 0xffff, (src_ip as u16) & 0xffff], sipaddr: [((src_ip >> 16) as u16) & 0xffff, (src_ip as u16) & 0xffff],
dhwaddr: dst_mac, dhwaddr: dst_mac,
dipaddr: [ dipaddr: [((dst_ip >> 16) & 0x0000ffff) as u16, (dst_ip & 0x0000ffff) as u16]
((dst_ip >> 16) & 0x0000ffff) as u16,
(dst_ip & 0x0000ffff) as u16,
],
}; };
let data = hdr.marshal_to_bytes(); let data = hdr.marshal_to_bytes();
if let Err(_e) = edge.device.send(&data) { if let Err(_e) = edge.device.send(&data) {
error!("failed to write arp response to device"); error!("failed to write arp response to device");
} }
} }

View File

@ -1,34 +1,23 @@
use std::fs::File; use std::fs::File;
use std::io::BufReader; use std::io::BufReader;
use std::net::SocketAddr;
use std::net::UdpSocket;
use std::os::windows::io::FromRawSocket;
use std::os::windows::io::IntoRawSocket;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
use default_net::Interface;
use quinn::crypto::rustls::QuicClientConfig;
use quinn::Endpoint; use quinn::Endpoint;
use quinn::TokioRuntime; use quinn::crypto::rustls::QuicClientConfig;
use rustls::crypto::ring;
use rustls::crypto::CryptoProvider; use rustls::crypto::CryptoProvider;
use rustls::crypto::ring;
use rustls::pki_types::CertificateDer; use rustls::pki_types::CertificateDer;
use rustls::pki_types::PrivateKeyDer; use rustls::pki_types::PrivateKeyDer;
use rustls::pki_types::ServerName; use rustls::pki_types::ServerName;
use rustls_pemfile::{certs, private_key}; use rustls_pemfile::{certs, private_key};
use socket2::Domain;
use socket2::Protocol;
use crate::get_default_interface; pub fn quic_init() -> Endpoint {
use crate::set_unicast_if_v4;
pub fn quic_init(iface: &Option<Interface>) -> Endpoint {
let default_provider = ring::default_provider(); let default_provider = ring::default_provider();
CryptoProvider::install_default(default_provider).unwrap(); CryptoProvider::install_default(default_provider).unwrap();
/* /*
let certificate_chain = load_certs_from_pem("./ca/ca.crt").unwrap(); let certificate_chain = load_certs_from_pem("./ca/ca.crt").unwrap();
let mut root_store = rustls::RootCertStore::empty(); let mut root_store = rustls::RootCertStore::empty();
for cert in certificate_chain { for cert in certificate_chain {
@ -37,12 +26,9 @@ pub fn quic_init(iface: &Option<Interface>) -> Endpoint {
*/ */
let mut root_store = rustls::RootCertStore::empty(); let mut root_store = rustls::RootCertStore::empty();
rustls_native_certs::load_native_certs() rustls_native_certs::load_native_certs().expect("could not load platform certs").into_iter().for_each(|cert| {
.expect("could not load platform certs") root_store.add(cert).unwrap();
.into_iter() });
.for_each(|cert| {
root_store.add(cert).unwrap();
});
let mut rustls_config = rustls::ClientConfig::builder() let mut rustls_config = rustls::ClientConfig::builder()
// .with_root_certificates(rustls::RootCertStore::empty()) // .with_root_certificates(rustls::RootCertStore::empty())
@ -50,41 +36,18 @@ pub fn quic_init(iface: &Option<Interface>) -> Endpoint {
.with_root_certificates(root_store) .with_root_certificates(root_store)
.with_no_client_auth(); .with_no_client_auth();
/* /*
let mut rustls_config = rustls::ClientConfig::builder() let mut rustls_config = rustls::ClientConfig::builder()
.dangerous() .dangerous()
.with_custom_certificate_verifier(Arc::new(SkipServerVerification{})) .with_custom_certificate_verifier(Arc::new(SkipServerVerification{}))
.with_no_client_auth(); .with_no_client_auth();
*/ */
let socket2 =
socket2::Socket::new(Domain::IPV4, socket2::Type::DGRAM, Some(Protocol::UDP)).unwrap();
socket2
.bind(&"0.0.0.0:0".parse::<SocketAddr>().unwrap().into())
.unwrap();
if let Some(iface) = iface {
set_unicast_if_v4(&socket2, iface);
}
let std_socket = unsafe { UdpSocket::from_raw_socket(socket2.into_raw_socket()) };
std_socket.set_nonblocking(true);
rustls_config.alpn_protocols = vec![b"punchnet/1.0".to_vec()]; rustls_config.alpn_protocols = vec![b"punchnet/1.0".to_vec()];
let quinn_client_config = let quinn_client_config = quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(rustls_config).unwrap()));
quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(rustls_config).unwrap()));
let quinn_endpoint_config = quinn::EndpointConfig::default();
let mut endpoint = Endpoint::new(
quinn_endpoint_config,
None,
std_socket,
Arc::new(TokioRuntime),
)
.unwrap();
let mut endpoint = Endpoint::client("0.0.0.0:0".parse().unwrap()).unwrap();
endpoint.set_default_client_config(quinn_client_config); endpoint.set_default_client_config(quinn_client_config);
endpoint endpoint
@ -93,53 +56,32 @@ pub fn quic_init(iface: &Option<Interface>) -> Endpoint {
#[derive(Debug)] #[derive(Debug)]
struct SkipServerVerification; struct SkipServerVerification;
impl rustls::client::danger::ServerCertVerifier for SkipServerVerification { impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
fn verify_server_cert( fn verify_server_cert(&self, _: &CertificateDer<'_>, _: &[CertificateDer<'_>], _: &ServerName<'_>, _: &[u8], _: rustls::pki_types::UnixTime) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
&self,
_: &CertificateDer<'_>,
_: &[CertificateDer<'_>],
_: &ServerName<'_>,
_: &[u8],
_: rustls::pki_types::UnixTime,
) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
Ok(rustls::client::danger::ServerCertVerified::assertion()) Ok(rustls::client::danger::ServerCertVerified::assertion())
} }
fn verify_tls12_signature( fn verify_tls12_signature(&self, _: &[u8], _: &CertificateDer<'_>, _: &rustls::DigitallySignedStruct) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
&self,
_: &[u8],
_: &CertificateDer<'_>,
_: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
} }
fn verify_tls13_signature( fn verify_tls13_signature(&self, _: &[u8], _: &CertificateDer<'_>, _: &rustls::DigitallySignedStruct) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
&self,
_: &[u8],
_: &CertificateDer<'_>,
_: &rustls::DigitallySignedStruct,
) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
Ok(rustls::client::danger::HandshakeSignatureValid::assertion()) Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
} }
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> { fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
rustls::crypto::ring::default_provider() rustls::crypto::ring::default_provider().signature_verification_algorithms.supported_schemes()
.signature_verification_algorithms
.supported_schemes()
} }
} }
pub fn load_certs_from_pem( pub fn load_certs_from_pem(path: impl AsRef<Path>) -> Result<Vec<CertificateDer<'static>>, Box<dyn std::error::Error>> {
path: impl AsRef<Path>,
) -> Result<Vec<CertificateDer<'static>>, Box<dyn std::error::Error>> {
let file = File::open(path.as_ref())?; let file = File::open(path.as_ref())?;
let mut reader = BufReader::new(file); let mut reader = BufReader::new(file);
let certs = certs(&mut reader) let certs = certs(&mut reader)
.into_iter() .into_iter()
.map(|it| it.unwrap()) .map(|it| it.unwrap())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Ok(certs) Ok(certs)
} }
pub fn load_private_key_from_pem(path: impl AsRef<Path>) -> Option<PrivateKeyDer<'static>> { pub fn load_private_key_from_pem(path: impl AsRef<Path>) -> Option<PrivateKeyDer<'static>>{
let Ok(file) = File::open(path.as_ref()) else { let Ok(file) = File::open(path.as_ref()) else {
return None; return None;
}; };

View File

@ -1,10 +1,8 @@
use default_net::Interface;
use sdlan_sn_rs::{ use sdlan_sn_rs::{
config::{AF_INET, AF_INET6}, config::{AF_INET, AF_INET6},
utils::{Result, SDLanError}, utils::{Result, SDLanError},
}; };
use socket2::{Domain, Protocol, SockAddr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4};
use tokio::net::ToSocketAddrs; use tokio::net::ToSocketAddrs;
use tracing::{debug, error}; use tracing::{debug, error};
@ -63,34 +61,13 @@ impl Socket {
Ok(Self { udp }) Ok(Self { udp })
} }
pub async fn build( pub async fn build(port: u16, bind_any: bool, join_multicast: bool, tos: u32) -> Result<Self> {
port: u16,
bind_any: bool,
join_multicast: bool,
tos: u32,
default_interface: &Option<Interface>,
) -> Result<Self> {
let addr = match bind_any { let addr = match bind_any {
true => "0.0.0.0", true => "0.0.0.0",
false => "127.0.0.1", false => "127.0.0.1",
}; };
let addr = format!("{}:{}", addr, port); let addr = format!("{}:{}", addr, port);
let udp = UdpSocket::bind(&addr).await?;
let socket2 =
socket2::Socket::new(Domain::IPV4, socket2::Type::DGRAM, Some(Protocol::UDP))?;
socket2.bind(&addr.parse::<SocketAddr>()?.into());
if let Some(iface) = default_interface {
set_unicast_if_v4(&socket2, iface);
}
let std_socket: std::net::UdpSocket = socket2.into();
std_socket.set_nonblocking(true);
let udp = UdpSocket::from_std(std_socket)?;
// let udp = UdpSocket::bind(&addr).await?;
if join_multicast { if join_multicast {
if let Err(e) = if let Err(e) =
udp.join_multicast_v4(Ipv4Addr::new(224, 0, 0, 69), Ipv4Addr::new(0, 0, 0, 0)) udp.join_multicast_v4(Ipv4Addr::new(224, 0, 0, 69), Ipv4Addr::new(0, 0, 0, 0))
@ -109,29 +86,6 @@ impl Socket {
} }
} }
pub fn set_unicast_if_v4(sock: &socket2::Socket, interface: &Interface) -> Result<()> {
use std::os::windows::io::AsRawSocket;
use windows_sys::Win32::Networking::WinSock::{setsockopt, IPPROTO_IP, IP_UNICAST_IF, SOCKET};
let idx = interface.index.to_be();
let ret = unsafe {
setsockopt(
sock.as_raw_socket() as SOCKET,
IPPROTO_IP as i32,
IP_UNICAST_IF as i32,
&idx as *const _ as *const _,
std::mem::size_of_val(&idx) as i32,
)
};
if ret == 0 {
Ok(())
} else {
Err(SDLanError::IOError(
std::io::Error::last_os_error().to_string(),
))
}
}
/* /*
pub async fn send_to_sock_v4_and_v6( pub async fn send_to_sock_v4_and_v6(
// sk: &Socket, // sk: &Socket,

View File

@ -1,8 +1,6 @@
use std::{net::Ipv4Addr, sync::Arc}; use std::{net::Ipv4Addr, sync::Arc};
use arc_swap::ArcSwap; use arc_swap::ArcSwap;
use default_net::Interface;
use sdlan_sn_rs::utils::{Result, SDLanError};
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct TrieNode { pub struct TrieNode {
@ -65,13 +63,6 @@ impl IpTrie {
} }
} }
pub fn get_default_interface() -> Result<Interface> {
match default_net::get_default_interface() {
Ok(interface) => Ok(interface),
Err(e) => Err(SDLanError::IOError(e)),
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::net::Ipv4Addr; use std::net::Ipv4Addr;