2026-04-20 16:30:54 +08:00

229 lines
7.2 KiB
Rust
Executable File

use std::sync::atomic::Ordering;
use bytes::{Bytes, BytesMut};
use dashmap::DashMap;
use once_cell::sync::OnceCell;
use sdlan_sn_rs::{
config::SDLAN_DEFAULT_TTL,
utils::{get_current_timestamp, ip_to_string, Mac, Result},
};
use tracing::{debug, warn};
use tracing::error;
use crate::{
network::{form_ethernet_packet, send_packet_to_net, Node, RouteInfo},
pb::{encode_to_udp_message, SdlData},
tcp::PacketType,
utils::mac_to_string,
};
use super::get_edge;
pub const MAX_WAIT_PACKETS: usize = 100;
const DEFAULT_DNS_SERVER: u32 = (223 << 24) + (5 << 16) + (5 << 8) + 5; // ali dns
pub trait TunTapPacketHandler {
async fn handle_packet_from_net(&self, data: &[u8]) -> std::io::Result<()>;
async fn handle_packet_from_device(&self, data: BytesMut) -> std::io::Result<()>;
}
pub fn set_route_from_net(routes: Vec<RouteInfo>) -> Result<()> {
let eee = get_edge();
eee.route_table.clear_and_add_routes(routes)?;
eee.route_table.apply_system(eee.device.get_if_idx());
Ok(())
}
/*
static ARP_WAIT_LIST: OnceCell<ArpWaitList> = OnceCell::new();
pub fn init_arp_wait_list() {
let waitlist = ArpWaitList {
content: DashMap::new(),
};
ARP_WAIT_LIST.set(waitlist).unwrap();
}
#[derive(Debug)]
pub struct ArpWaitInfo {
timestamp: u64,
// origin data is from the tun or tap device
origin_data: BytesMut,
}
#[derive(Debug)]
pub struct ArpWaitList {
content: DashMap<u32, Vec<ArpWaitInfo>>,
}
impl ArpWaitList {
fn add_to_wait_list(&self, ip: u32, origin_data_with_zeroed_layer2: BytesMut) {
let mut entry = self.content.entry(ip).or_insert(vec![]);
if entry.len() < MAX_WAIT_PACKETS {
entry.push(ArpWaitInfo {
timestamp: get_current_timestamp(),
origin_data: origin_data_with_zeroed_layer2,
})
}
}
async fn arp_arrived(&self, ip: u32, mac: Mac) {
debug!(
"arp for {} arrived: {}",
ip_to_string(&ip),
mac_to_string(&mac)
);
let Some(items) = self.content.remove(&ip) else {
return;
};
let edge = get_edge();
// just remove the items
if !edge.is_authorized() {
return;
}
// let encrypt_key = edge.get_encrypt_key();
let network_id = edge.network_id.load(Ordering::Relaxed);
let src_mac = edge.device_config.get_mac();
let now = get_current_timestamp();
for item in items.1 {
if (now - item.timestamp) > 5 {
continue;
}
let packet = form_ethernet_packet(src_mac, mac, item.origin_data);
let pkt_size = packet.len();
let Ok(encrypted) = edge.encryptor.load().encrypt(&packet) else {
// let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&packet) else {
// let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else {
error!("failed to encrypt packet request");
return;
};
let data_bytes = Bytes::from(encrypted);
let data = SdlData {
is_p2p: true,
network_id,
ttl: SDLAN_DEFAULT_TTL as u32,
src_mac: Vec::from(src_mac),
dst_mac: Vec::from(mac),
data: data_bytes,
identity_id: edge.identity_id.load(),
session_token: edge.session_token.get(),
};
let msg = encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap();
send_packet_to_net(edge, mac, &msg, pkt_size as u64).await;
}
}
}
pub fn add_to_arp_wait_list(ip: u32, origin_data_with_zeroed_layer2: BytesMut) {
let waitlist = ARP_WAIT_LIST
.get()
.expect("ARP_WAIT_LIST has not been inited");
waitlist.add_to_wait_list(ip, origin_data_with_zeroed_layer2);
}
pub async fn arp_arrived(ip: u32, mac: Mac) {
let waitlist = ARP_WAIT_LIST
.get()
.expect("ARP_WAIT_LIST has not been inited");
waitlist.arp_arrived(ip, mac).await;
}
*/
pub fn get_dns_gateway(edge: &Node, payload: &[u8]) -> Option<String> {
let dns_packet = match simple_dns::Packet::parse(payload) {
Err(e) => {
error!("failed to parse dns packet: {}", e);
return None;
}
Ok(p) => p,
};
let mut target_dns: &str = "";
if !dns_packet.has_flags(simple_dns::PacketFlag::RESPONSE) && !dns_packet.questions.is_empty() {
let question = &dns_packet.questions[0];
let domain = question.qname.to_string();
let self_domain = &edge.network_domain.load();
if self_domain.is_empty() {
return None;
}
if domain.ends_with(self_domain.as_str()) {
debug!("got dns request for domain {}, which ends with our network domain {}, should send to dns server", domain, self_domain);
return Some(domain);
}
}
return None;
}
pub async fn parse_dns_payload(
edge: &Node,
layer7: &[u8],
layer3: &[u8],
source_ip: u32,
source_port: u16,
) {
match simple_dns::Packet::parse(layer7) {
Ok(mut dns) => {
if !dns.has_flags(simple_dns::PacketFlag::RESPONSE) && !dns.questions.is_empty() {
let question = &dns.questions[0];
let qname = question.qname.to_string();
if qname.ends_with(edge.network_domain.load().as_str()) {
warn!(
"question 15353 for {} from {}:{} with transaction_id = {}",
qname,
ip_to_string(&source_ip),
source_port,
dns.id()
);
// should send to our socket
if let Err(e) = edge
.udp_sock_for_dns
.send_to(layer3, format!("{}:15353", edge.server_ip))
.await
{
error!("failed to send request to 15353: {}", e);
}
} else {
let origin_transaction_id = dns.id();
let transaction_id = edge.dns_matcher.generate_transaction_id(
source_ip,
source_port,
origin_transaction_id,
);
dns.set_id(transaction_id);
warn!(
"question 223.5.5.5 for {} from {}:{} with transaction_id = {}",
qname,
ip_to_string(&source_ip),
source_port,
dns.id()
);
if let Ok(res) = dns.build_bytes_vec() {
if let Err(e) = edge
.udp_sock_for_global_dns
.send_to(&res, "223.5.5.5:53")
.await
{
error!("failed to query for global dns: {}", e);
}
}
// edge.udp_sock_for_global_dns.send_to()
}
}
}
Err(e) => {
error!("failed to parse dns packet");
}
}
}