Compare commits
2 Commits
7e7a9ca2e6
...
12dda5d35c
| Author | SHA1 | Date | |
|---|---|---|---|
| 12dda5d35c | |||
| 6874bc5291 |
131
Cargo.lock
generated
131
Cargo.lock
generated
@ -524,6 +524,16 @@ 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"
|
||||||
@ -698,6 +708,23 @@ 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"
|
||||||
@ -772,6 +799,17 @@ 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"
|
||||||
@ -1694,6 +1732,12 @@ 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"
|
||||||
@ -1761,6 +1805,54 @@ 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"
|
||||||
@ -2153,6 +2245,7 @@ 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",
|
||||||
@ -2179,11 +2272,13 @@ 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",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2575,7 +2670,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",
|
"core-foundation 0.10.1",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"jni",
|
"jni",
|
||||||
"log",
|
"log",
|
||||||
@ -2676,7 +2771,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",
|
"core-foundation 0.10.1",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"security-framework-sys",
|
"security-framework-sys",
|
||||||
@ -3193,6 +3288,27 @@ 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"
|
||||||
@ -3922,6 +4038,15 @@ 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"
|
||||||
@ -4322,7 +4447,7 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
"log",
|
"log",
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
"windows",
|
"windows 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@ -44,6 +44,8 @@ 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]
|
||||||
@ -54,6 +56,7 @@ 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 = []
|
||||||
|
|||||||
@ -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,17 +12,22 @@ 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::quic::quic_init;
|
|
||||||
use crate::{CommandLine, ConnectionInfo, DNSMatcher, MyEncryptor, RuleCache, get_base_dir};
|
|
||||||
use crate::pb::{
|
use crate::pb::{
|
||||||
SdlArpRequest, SdlEmpty, SdlStunProbe, SdlStunProbeReply, encode_to_tcp_message, encode_to_udp_message
|
encode_to_tcp_message, encode_to_udp_message, SdlArpRequest, SdlEmpty, SdlStunProbe,
|
||||||
|
SdlStunProbeReply,
|
||||||
|
};
|
||||||
|
use crate::quic::quic_init;
|
||||||
|
use crate::tcp::{get_quic_write_conn, NatType, PacketType, StunProbeAttr};
|
||||||
|
use crate::utils::Socket;
|
||||||
|
use crate::{
|
||||||
|
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};
|
||||||
|
|
||||||
@ -32,7 +37,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::{Mac, gen_rsa_keys, load_private_key_file, save_to_file};
|
use sdlan_sn_rs::utils::{gen_rsa_keys, load_private_key_file, save_to_file, Mac};
|
||||||
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();
|
||||||
@ -51,7 +56,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());
|
||||||
@ -69,13 +74,33 @@ 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 Ok(sock_v4) = Socket::build(node_conf._local_port, true, false, args.tos).await else {
|
let default_interface = match get_default_interface() {
|
||||||
|
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 = Some(Socket::build(MULTICAST_PORT, true, true, 0).await?);
|
sock_multicast =
|
||||||
|
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
|
||||||
@ -88,6 +113,7 @@ 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,
|
||||||
@ -103,7 +129,8 @@ pub async fn init_edge(
|
|||||||
install_channel,
|
install_channel,
|
||||||
);
|
);
|
||||||
|
|
||||||
edge.route_table.parse_and_add_route(&args.route_file, &args.route_str);
|
edge.route_table
|
||||||
|
.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)?;
|
||||||
@ -214,7 +241,6 @@ 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,
|
||||||
|
|
||||||
@ -222,7 +248,6 @@ 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,
|
||||||
|
|
||||||
@ -262,7 +287,6 @@ 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>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +309,7 @@ impl Node {
|
|||||||
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());
|
||||||
@ -355,7 +379,9 @@ 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.cookie_match.do_action_and_wait_for(
|
let res = self
|
||||||
|
.cookie_match
|
||||||
|
.do_action_and_wait_for(
|
||||||
0,
|
0,
|
||||||
|| async {
|
|| async {
|
||||||
let _ = self
|
let _ = self
|
||||||
@ -367,13 +393,16 @@ impl Node {
|
|||||||
.await;
|
.await;
|
||||||
debug!("start with feedback");
|
debug!("start with feedback");
|
||||||
},
|
},
|
||||||
timeout
|
timeout,
|
||||||
).await?;
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
if let Ok(res) = res.downcast() {
|
if let Ok(res) = res.downcast() {
|
||||||
Ok(*res)
|
Ok(*res)
|
||||||
} else {
|
} else {
|
||||||
Err(SDLanError::ConvertError("failed to convert feedback to RSFeedback".to_owned()))
|
Err(SDLanError::ConvertError(
|
||||||
|
"failed to convert feedback to RSFeedback".to_owned(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,6 +423,7 @@ 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,
|
||||||
@ -416,14 +446,12 @@ 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),
|
||||||
|
|
||||||
@ -437,7 +465,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(),
|
quic_endpoint: quic_init(iface),
|
||||||
|
|
||||||
identity_id: IdentityID::new(0),
|
identity_id: IdentityID::new(0),
|
||||||
access_token: StringToken::new(String::new()),
|
access_token: StringToken::new(String::new()),
|
||||||
@ -445,7 +473,6 @@ 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,
|
||||||
|
|
||||||
@ -666,12 +693,24 @@ impl Node {
|
|||||||
step: 0,
|
step: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
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?;
|
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?;
|
||||||
|
|
||||||
if let Ok(res) = result.downcast() {
|
if let Ok(res) = result.downcast() {
|
||||||
return Ok(*res);
|
return Ok(*res);
|
||||||
}
|
}
|
||||||
return Err(SDLanError::ConvertError("failed to convert to StunprobeReply".to_owned()))
|
return Err(SDLanError::ConvertError(
|
||||||
|
"failed to convert to StunprobeReply".to_owned(),
|
||||||
|
));
|
||||||
// println!("==> sending probe request: {:?}", probe);
|
// println!("==> sending probe request: {:?}", probe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -877,7 +916,15 @@ impl Queryer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
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> {
|
||||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||||
self.mailbox.insert(id, tx);
|
self.mailbox.insert(id, tx);
|
||||||
|
|
||||||
@ -903,10 +950,14 @@ 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>(&self, id: u32, action: T, timeout: Duration) -> Result<BoxedProstMessage>
|
pub async fn do_action_and_wait_for<T, F>(
|
||||||
|
&self,
|
||||||
|
id: u32,
|
||||||
|
action: T,
|
||||||
|
timeout: Duration,
|
||||||
|
) -> Result<BoxedProstMessage>
|
||||||
where
|
where
|
||||||
F: Future<Output = ()>,
|
F: Future<Output = ()>,
|
||||||
T: Fn() -> F,
|
T: Fn() -> F,
|
||||||
@ -933,7 +984,13 @@ impl Queryer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_message_to_quic_and_wait_for<T: Message>(&self, id: u32, message: T, packet_type: u8, timeout: Duration) -> Result<BoxedProstMessage> {
|
pub async fn send_message_to_quic_and_wait_for<T: Message>(
|
||||||
|
&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);
|
||||||
|
|
||||||
|
|||||||
@ -2,18 +2,16 @@ 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;
|
||||||
|
|
||||||
#[cfg(feature = "tun")]
|
use etherparse::Ethernet2Header;
|
||||||
use etherparse::{NetSlice, PacketBuilder, SlicedPacket, TransportSlice};
|
|
||||||
#[cfg(not(feature = "tun"))]
|
#[cfg(not(feature = "tun"))]
|
||||||
use etherparse::{IpSlice, LinkSlice, NetSlice, SlicedPacket, TransportSlice};
|
use etherparse::{IpSlice, LinkSlice, NetSlice, SlicedPacket, TransportSlice};
|
||||||
use etherparse::{Ethernet2Header};
|
#[cfg(feature = "tun")]
|
||||||
|
use etherparse::{NetSlice, PacketBuilder, SlicedPacket, TransportSlice};
|
||||||
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::{
|
use sdlan_sn_rs::utils::{ip_to_string, is_ipv6_multicast, net_bit_len_to_mask, Mac, SDLanError};
|
||||||
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};
|
||||||
@ -38,8 +36,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::{ARP_REPLY, ArpHdr, EthHdr, parse_dns_payload};
|
use crate::network::{parse_dns_payload, ArpHdr, EthHdr, ARP_REPLY};
|
||||||
use crate::network::{Node, send_packet_to_net};
|
use crate::network::{send_packet_to_net, Node};
|
||||||
#[cfg(not(feature = "tun"))]
|
#[cfg(not(feature = "tun"))]
|
||||||
use crate::pb::SdlArpResponse;
|
use crate::pb::SdlArpResponse;
|
||||||
#[cfg(feature = "tun")]
|
#[cfg(feature = "tun")]
|
||||||
@ -128,7 +126,12 @@ impl Iface {
|
|||||||
};
|
};
|
||||||
let has_resolvectl = check_has_resolvectl();
|
let has_resolvectl = check_has_resolvectl();
|
||||||
|
|
||||||
Ok(Iface { fd: fs, mode, name, has_resolvectl })
|
Ok(Iface {
|
||||||
|
fd: fs,
|
||||||
|
mode,
|
||||||
|
name,
|
||||||
|
has_resolvectl,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(SDLanError::NormalError("failed to setup tun"))
|
Err(SDLanError::NormalError("failed to setup tun"))
|
||||||
}
|
}
|
||||||
@ -177,7 +180,7 @@ impl Iface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node.route_table.apply_system();
|
node.route_table.apply_system(0);
|
||||||
|
|
||||||
if node.config.allow_routing.load(Ordering::Relaxed) {
|
if node.config.allow_routing.load(Ordering::Relaxed) {
|
||||||
set_allow_routing();
|
set_allow_routing();
|
||||||
@ -235,7 +238,6 @@ impl TunTapPacketHandler for Iface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(feature = "abc")]
|
#[cfg(feature = "abc")]
|
||||||
async fn handle_packet_from_device(
|
async fn handle_packet_from_device(
|
||||||
&self,
|
&self,
|
||||||
@ -259,7 +261,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::{ARP_REQUEST, ArpHdr};
|
use crate::network::{ArpHdr, ARP_REQUEST};
|
||||||
|
|
||||||
let arp = ArpHdr::from_slice(&data);
|
let arp = ArpHdr::from_slice(&data);
|
||||||
match arp.opcode {
|
match arp.opcode {
|
||||||
@ -296,7 +298,6 @@ 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;
|
||||||
|
|
||||||
@ -329,27 +330,28 @@ 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.udp_sock_for_dns.send_to(&data[14..], format!("{}:15353", edge.server_ip)).await {
|
if let Err(e) = edge
|
||||||
|
.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;
|
||||||
@ -404,11 +406,11 @@ impl TunTapPacketHandler for Iface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// if let Some(eth) = headers.link {
|
// if let Some(eth) = headers.link {
|
||||||
use etherparse::EtherType;
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use etherparse::EtherType;
|
||||||
|
|
||||||
if eth.ether_type == EtherType::ARP {
|
if eth.ether_type == EtherType::ARP {
|
||||||
use crate::network::{ARP_REQUEST, ArpHdr};
|
use crate::network::{ArpHdr, ARP_REQUEST};
|
||||||
|
|
||||||
let arp = ArpHdr::from_slice(&data);
|
let arp = ArpHdr::from_slice(&data);
|
||||||
match arp.opcode {
|
match arp.opcode {
|
||||||
@ -441,7 +443,6 @@ impl TunTapPacketHandler for Iface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
@ -471,9 +472,16 @@ impl TunTapPacketHandler for Iface {
|
|||||||
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(edge, udp.payload(), layer3, source_ip, udp.source_port()).await;
|
parse_dns_payload(
|
||||||
|
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 => {
|
||||||
@ -488,7 +496,6 @@ impl TunTapPacketHandler for Iface {
|
|||||||
// just ignore
|
// just ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = eth.destination;
|
let target = eth.destination;
|
||||||
@ -521,7 +528,6 @@ impl TunTapPacketHandler for Iface {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tun")]
|
#[cfg(feature = "tun")]
|
||||||
@ -644,7 +650,6 @@ 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 {
|
||||||
/*
|
/*
|
||||||
@ -712,10 +717,7 @@ impl TunTapPacketHandler for Iface {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_packet_from_device(
|
async fn handle_packet_from_device(&self, mut header: BytesMut) -> std::io::Result<()> {
|
||||||
&self,
|
|
||||||
mut header: BytesMut,
|
|
||||||
) -> std::io::Result<()> {
|
|
||||||
use etherparse::IpHeaders;
|
use etherparse::IpHeaders;
|
||||||
|
|
||||||
let eee = get_edge();
|
let eee = get_edge();
|
||||||
@ -733,10 +735,8 @@ 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,7 +745,9 @@ 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)) && (src != eee.device_config.get_ip()) {
|
if (!eee.config.allow_routing.load(Ordering::Relaxed))
|
||||||
|
&& (src != eee.device_config.get_ip())
|
||||||
|
{
|
||||||
info!("dropping routed packet");
|
info!("dropping routed packet");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@ -764,14 +766,19 @@ 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(eee, udp.payload(), &data, src, udp.source_port()).await;
|
parse_dns_payload(
|
||||||
|
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) {
|
||||||
@ -788,7 +795,6 @@ impl TunTapPacketHandler for Iface {
|
|||||||
let crc = caculate_crc(&data);
|
let crc = caculate_crc(&data);
|
||||||
header.unsplit(data);
|
header.unsplit(data);
|
||||||
|
|
||||||
|
|
||||||
// packet.extend_from_slice(ðerheader.to_bytes()[..]);
|
// packet.extend_from_slice(ðerheader.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());
|
||||||
@ -826,7 +832,10 @@ impl TunTapPacketHandler for Iface {
|
|||||||
src.to_be_bytes(),
|
src.to_be_bytes(),
|
||||||
dstip.to_be_bytes()
|
dstip.to_be_bytes()
|
||||||
);
|
);
|
||||||
debug!("no mac found for ip {:?}, sending arp request", dstip.to_be_bytes());
|
debug!(
|
||||||
|
"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)) {
|
||||||
@ -837,15 +846,11 @@ impl TunTapPacketHandler for Iface {
|
|||||||
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(())
|
||||||
}
|
}
|
||||||
@ -857,9 +862,7 @@ 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")
|
let res = Command::new("resolvectl").arg("status").output();
|
||||||
.arg("status")
|
|
||||||
.output();
|
|
||||||
if let Ok(_) = res {
|
if let Ok(_) = res {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@ -879,10 +882,7 @@ fn add_dns_route(dev_name: &str) -> Result<()>{
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_resolvectl(
|
fn add_resolvectl(name: &str, network_domain: &str) -> Result<()> {
|
||||||
name: &str,
|
|
||||||
network_domain: &str,
|
|
||||||
) -> Result<()>{
|
|
||||||
Command::new("resolvectl")
|
Command::new("resolvectl")
|
||||||
.arg("dns")
|
.arg("dns")
|
||||||
.arg(name)
|
.arg(name)
|
||||||
@ -898,12 +898,7 @@ fn add_resolvectl(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_dns(
|
fn set_dns(iface: &Iface, name: &str, network_domain: &str, gw: &str) -> Result<()> {
|
||||||
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)?;
|
||||||
@ -929,10 +924,17 @@ pub fn restore_dns() -> Result<()> {
|
|||||||
///
|
///
|
||||||
/// - `new_nameservers`: 新的 nameserver 列表(IPv4/IPv6 字符串)
|
/// - `new_nameservers`: 新的 nameserver 列表(IPv4/IPv6 字符串)
|
||||||
/// - `keep_other_ns`: 是否保留原有的 nameserver(true = 追加到新列表后,false = 完全替换)
|
/// - `keep_other_ns`: 是否保留原有的 nameserver(true = 追加到新列表后,false = 完全替换)
|
||||||
pub fn modify_resolv_conf(new_nameservers: &[String], search_domain: &str, keep_other_ns: bool) -> Result<()> {
|
pub fn modify_resolv_conf(
|
||||||
|
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!("{} does not exists", RESOLV_FILE)));
|
return Err(SDLanError::IOError(format!(
|
||||||
|
"{} does not exists",
|
||||||
|
RESOLV_FILE
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取原文件权限和元数据
|
// 读取原文件权限和元数据
|
||||||
@ -1020,7 +1022,10 @@ 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!("{} does not exists", RESOLV_FILE)));
|
return Err(SDLanError::IOError(format!(
|
||||||
|
"{} does not exists",
|
||||||
|
RESOLV_FILE
|
||||||
|
)));
|
||||||
// anyhow::bail!("Source /etc/resolv.conf does not exist");
|
// anyhow::bail!("Source /etc/resolv.conf does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1054,7 +1059,10 @@ 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!("{} does not exists", RESOLV_FILE_BACKUP)));
|
return Err(SDLanError::IOError(format!(
|
||||||
|
"{} does not exists",
|
||||||
|
RESOLV_FILE_BACKUP
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果目标是符号链接,先删除链接再复制(避免写入到链接指向位置)
|
// 如果目标是符号链接,先删除链接再复制(避免写入到链接指向位置)
|
||||||
@ -1094,7 +1102,7 @@ pub fn del_route(net: &Ipv4Net, gw: &Ipv4Addr) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_route(net: &Ipv4Net, gw: &Ipv4Addr) -> Result<()> {
|
pub fn add_route(net: &Ipv4Net, gw: &Ipv4Addr, _ifidx: u32) -> Result<()> {
|
||||||
let res = Command::new("route")
|
let res = Command::new("route")
|
||||||
.arg("add")
|
.arg("add")
|
||||||
.arg("-net")
|
.arg("-net")
|
||||||
@ -1152,7 +1160,11 @@ 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!("invalid target_mac: {:?}, ip={}", data.target_mac, ip_to_string(&data.target_ip));
|
error!(
|
||||||
|
"invalid target_mac: {:?}, ip={}",
|
||||||
|
data.target_mac,
|
||||||
|
ip_to_string(&data.target_ip)
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,7 +1180,11 @@ 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!("invalid target_mac: {:?}, ip={}", data.target_mac, ip_to_string(&data.target_ip));
|
error!(
|
||||||
|
"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;
|
||||||
@ -1198,7 +1214,10 @@ 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: [((dst_ip >> 16) & 0x0000ffff) as u16, (dst_ip & 0x0000ffff) as u16]
|
dipaddr: [
|
||||||
|
((dst_ip >> 16) & 0x0000ffff) as u16,
|
||||||
|
(dst_ip & 0x0000ffff) as u16,
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = hdr.marshal_to_bytes();
|
let data = hdr.marshal_to_bytes();
|
||||||
|
|||||||
@ -1,19 +1,30 @@
|
|||||||
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 quinn::Endpoint;
|
use default_net::Interface;
|
||||||
use quinn::crypto::rustls::QuicClientConfig;
|
use quinn::crypto::rustls::QuicClientConfig;
|
||||||
use rustls::crypto::CryptoProvider;
|
use quinn::Endpoint;
|
||||||
|
use quinn::TokioRuntime;
|
||||||
use rustls::crypto::ring;
|
use rustls::crypto::ring;
|
||||||
|
use rustls::crypto::CryptoProvider;
|
||||||
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;
|
||||||
|
|
||||||
pub fn quic_init() -> Endpoint {
|
use crate::get_default_interface;
|
||||||
|
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();
|
||||||
|
|
||||||
@ -26,7 +37,10 @@ pub fn quic_init() -> Endpoint {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
let mut root_store = rustls::RootCertStore::empty();
|
let mut root_store = rustls::RootCertStore::empty();
|
||||||
rustls_native_certs::load_native_certs().expect("could not load platform certs").into_iter().for_each(|cert| {
|
rustls_native_certs::load_native_certs()
|
||||||
|
.expect("could not load platform certs")
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|cert| {
|
||||||
root_store.add(cert).unwrap();
|
root_store.add(cert).unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -43,11 +57,34 @@ pub fn quic_init() -> Endpoint {
|
|||||||
.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 = quinn::ClientConfig::new(Arc::new(QuicClientConfig::try_from(rustls_config).unwrap()));
|
let quinn_client_config =
|
||||||
|
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
|
||||||
@ -56,21 +93,42 @@ pub fn quic_init() -> 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(&self, _: &CertificateDer<'_>, _: &[CertificateDer<'_>], _: &ServerName<'_>, _: &[u8], _: rustls::pki_types::UnixTime) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
|
fn verify_server_cert(
|
||||||
|
&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(&self, _: &[u8], _: &CertificateDer<'_>, _: &rustls::DigitallySignedStruct) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
fn verify_tls12_signature(
|
||||||
|
&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(&self, _: &[u8], _: &CertificateDer<'_>, _: &rustls::DigitallySignedStruct) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
|
fn verify_tls13_signature(
|
||||||
|
&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().signature_verification_algorithms.supported_schemes()
|
rustls::crypto::ring::default_provider()
|
||||||
|
.signature_verification_algorithms
|
||||||
|
.supported_schemes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_certs_from_pem(path: impl AsRef<Path>) -> Result<Vec<CertificateDer<'static>>, Box<dyn std::error::Error>> {
|
pub fn load_certs_from_pem(
|
||||||
|
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)
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
|
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 std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
use socket2::{Domain, Protocol, SockAddr};
|
||||||
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4};
|
||||||
use tokio::net::ToSocketAddrs;
|
use tokio::net::ToSocketAddrs;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
@ -61,13 +63,34 @@ impl Socket {
|
|||||||
Ok(Self { udp })
|
Ok(Self { udp })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn build(port: u16, bind_any: bool, join_multicast: bool, tos: u32) -> Result<Self> {
|
pub async fn build(
|
||||||
|
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))
|
||||||
@ -86,6 +109,29 @@ 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,
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
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 {
|
||||||
@ -63,6 +65,13 @@ 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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user