add arp to waitlist

This commit is contained in:
asxalex 2024-10-25 16:41:02 +08:00
parent e7352c7b67
commit 69255d7907
6 changed files with 138 additions and 6 deletions

View File

@ -4,6 +4,9 @@ linux:
linux-tun: linux-tun:
RUSTFLAGS="-L ." cargo build --release RUSTFLAGS="-L ." cargo build --release
win:
cargo build --release
pb: pb:
cargo run --bin build_pb cargo run --bin build_pb
mv src/pb/_.rs src/pb/message.rs mv src/pb/_.rs src/pb/message.rs

View File

@ -583,10 +583,10 @@ async fn read_and_parse_tun_packet(eee: &'static Node, buf: Vec<u8>) {
*/ */
// buf.truncate(size); // buf.truncate(size);
edge_send_packet_to_net(eee, &buf).await; edge_send_packet_to_net(eee, buf).await;
} }
async fn edge_send_packet_to_net(eee: &Node, data: &[u8]) { async fn edge_send_packet_to_net(eee: &Node, data: Vec<u8>) {
debug!("edge send packet to net({} bytes): {:?}", data.len(), data); debug!("edge send packet to net({} bytes): {:?}", data.len(), data);
let encrypt_key = eee.get_encrypt_key(); let encrypt_key = eee.get_encrypt_key();

View File

@ -11,6 +11,7 @@ use crate::{
tcp::{get_tcp_conn, PacketType}, tcp::{get_tcp_conn, PacketType},
utils::{send_to_sock, Socket}, utils::{send_to_sock, Socket},
}; };
use etherparse::Ethernet2Header;
use prost::Message; use prost::Message;
use sdlan_sn_rs::{ use sdlan_sn_rs::{
config::{AF_INET, AF_INET6}, config::{AF_INET, AF_INET6},
@ -1101,3 +1102,14 @@ pub async fn update_supernode_reg(eee: &Node) {
register_with_local_peers(eee).await; register_with_local_peers(eee).await;
} }
*/ */
pub fn form_ethernet_packet(src_mac: Mac, dst_mac: Mac, data: &[u8]) -> Vec<u8> {
let mut etherheader = Ethernet2Header::default();
etherheader.destination = dst_mac;
etherheader.ether_type = etherparse::EtherType::IPV4;
etherheader.source = src_mac;
let mut packet = Vec::with_capacity(14 + data.len() + 4);
packet.extend_from_slice(&etherheader.to_bytes()[..]);
packet.extend_from_slice(&data);
packet
}

View File

@ -14,8 +14,8 @@ use wintun;
use crate::get_edge; use crate::get_edge;
use crate::network::{ use crate::network::{
generate_arp_request, send_arp_request, send_packet_to_net, ArpHdr, ArpRequestInfo, add_to_arp_wait_list, form_ethernet_packet, generate_arp_request, send_arp_request,
ArpResponse, ARP_REPLY, ARP_REQUEST, send_packet_to_net, ArpHdr, ArpRequestInfo, ArpResponse, ARP_REPLY, ARP_REQUEST,
}; };
use crate::pb::{encode_to_udp_message, SdlData}; use crate::pb::{encode_to_udp_message, SdlData};
use crate::tcp::PacketType; use crate::tcp::PacketType;
@ -247,7 +247,7 @@ impl TunTapPacketHandler for Iface {
async fn handle_packet_from_device( async fn handle_packet_from_device(
&self, &self,
data: &[u8], data: Vec<u8>,
encrypt_key: &[u8], encrypt_key: &[u8],
) -> std::io::Result<()> { ) -> std::io::Result<()> {
let eee = get_edge(); let eee = get_edge();
@ -281,6 +281,8 @@ impl TunTapPacketHandler for Iface {
do_arp_request, do_arp_request,
} => { } => {
if do_arp_request { if do_arp_request {
add_to_arp_wait_list(dstip, data);
println!( println!(
"find ip: {:?} => {:?}", "find ip: {:?} => {:?}",
src.to_be_bytes(), src.to_be_bytes(),
@ -312,7 +314,9 @@ impl TunTapPacketHandler for Iface {
return Ok(()); return Ok(());
} }
let packet = form_ethernet_packet(src_mac, mac, &data);
// prepend the ether header // prepend the ether header
/*
let mut etherheader = Ethernet2Header::default(); let mut etherheader = Ethernet2Header::default();
etherheader.destination = mac; etherheader.destination = mac;
etherheader.ether_type = etherparse::EtherType::IPV4; etherheader.ether_type = etherparse::EtherType::IPV4;
@ -320,6 +324,7 @@ impl TunTapPacketHandler for Iface {
let mut packet = Vec::with_capacity(14 + data.len() + 4); let mut packet = Vec::with_capacity(14 + data.len() + 4);
packet.extend_from_slice(&etherheader.to_bytes()[..]); packet.extend_from_slice(&etherheader.to_bytes()[..]);
packet.extend_from_slice(&data); packet.extend_from_slice(&data);
*/
// let crc = CRC_HASH.checksum(&packet); // let crc = CRC_HASH.checksum(&packet);
// packet.extend_from_slice(&crc.to_be_bytes()); // packet.extend_from_slice(&crc.to_be_bytes());

View File

@ -1,4 +1,115 @@
use std::sync::atomic::Ordering;
use dashmap::DashMap;
use etherparse::Ethernet2Header;
use once_cell::sync::OnceCell;
use sdlan_sn_rs::{
config::SDLAN_DEFAULT_TTL,
utils::{aes_encrypt, get_current_timestamp, Mac},
};
use tracing::error;
use crate::{
network::{form_ethernet_packet, send_packet_to_net},
pb::{encode_to_udp_message, SdlData},
tcp::PacketType,
};
use super::get_edge;
pub const MAX_WAIT_PACKETS: usize = 100;
pub trait TunTapPacketHandler { pub trait TunTapPacketHandler {
async fn handle_packet_from_net(&self, data: &[u8], key: &[u8]) -> std::io::Result<()>; async fn handle_packet_from_net(&self, data: &[u8], key: &[u8]) -> std::io::Result<()>;
async fn handle_packet_from_device(&self, data: &[u8], key: &[u8]) -> std::io::Result<()>; async fn handle_packet_from_device(&self, data: Vec<u8>, key: &[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) {
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) = aes_encrypt(&encrypt_key, &packet) else {
error!("failed to encrypt packet request");
return;
};
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: Vec::from(encrypted),
};
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;
} }

View File

@ -12,6 +12,7 @@ pub use pid_recorder::PidRecorder;
// pub const CRC_HASH: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_XFER); // pub const CRC_HASH: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_XFER);
#[allow(unused)]
pub fn caculate_crc(data: &[u8]) -> u32 { pub fn caculate_crc(data: &[u8]) -> u32 {
let res = crc32fast::hash(data); let res = crc32fast::hash(data);
res res