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) -> 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 = 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>, } 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 { 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"); } } }