129 lines
3.6 KiB
Rust
Executable File

use std::sync::atomic::Ordering;
use bytes::Bytes;
use dashmap::DashMap;
use once_cell::sync::OnceCell;
use sdlan_sn_rs::{
config::SDLAN_DEFAULT_TTL,
utils::{get_current_timestamp, ip_to_string, Mac},
};
use tracing::debug;
use tracing::error;
use crate::{
network::{form_ethernet_packet, send_packet_to_net},
pb::{encode_to_udp_message, SdlData},
tcp::PacketType,
utils::mac_to_string,
};
use super::get_edge;
pub const MAX_WAIT_PACKETS: usize = 100;
pub trait TunTapPacketHandler {
async fn handle_packet_from_net(&self, data: &[u8]) -> std::io::Result<()>;
async fn handle_packet_from_device(&self, data: Vec<u8>) -> std::io::Result<()>;
}
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: Vec<u8>,
}
#[derive(Debug)]
pub struct ArpWaitList {
content: DashMap<u32, Vec<ArpWaitInfo>>,
}
impl ArpWaitList {
fn add_to_wait_list(&self, ip: u32, origin_data: Vec<u8>) {
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,
})
}
}
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: Vec<u8>) {
let waitlist = ARP_WAIT_LIST
.get()
.expect("ARP_WAIT_LIST has not been inited");
waitlist.add_to_wait_list(ip, origin_data);
}
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;
}