add arp to waitlist
This commit is contained in:
parent
e7352c7b67
commit
69255d7907
3
Makefile
3
Makefile
@ -4,6 +4,9 @@ linux:
|
||||
linux-tun:
|
||||
RUSTFLAGS="-L ." cargo build --release
|
||||
|
||||
win:
|
||||
cargo build --release
|
||||
|
||||
pb:
|
||||
cargo run --bin build_pb
|
||||
mv src/pb/_.rs src/pb/message.rs
|
||||
|
||||
@ -583,10 +583,10 @@ async fn read_and_parse_tun_packet(eee: &'static Node, buf: Vec<u8>) {
|
||||
*/
|
||||
// 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);
|
||||
|
||||
let encrypt_key = eee.get_encrypt_key();
|
||||
|
||||
@ -11,6 +11,7 @@ use crate::{
|
||||
tcp::{get_tcp_conn, PacketType},
|
||||
utils::{send_to_sock, Socket},
|
||||
};
|
||||
use etherparse::Ethernet2Header;
|
||||
use prost::Message;
|
||||
use sdlan_sn_rs::{
|
||||
config::{AF_INET, AF_INET6},
|
||||
@ -1101,3 +1102,14 @@ pub async fn update_supernode_reg(eee: &Node) {
|
||||
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(ðerheader.to_bytes()[..]);
|
||||
packet.extend_from_slice(&data);
|
||||
packet
|
||||
}
|
||||
|
||||
@ -14,8 +14,8 @@ use wintun;
|
||||
|
||||
use crate::get_edge;
|
||||
use crate::network::{
|
||||
generate_arp_request, send_arp_request, send_packet_to_net, ArpHdr, ArpRequestInfo,
|
||||
ArpResponse, ARP_REPLY, ARP_REQUEST,
|
||||
add_to_arp_wait_list, form_ethernet_packet, generate_arp_request, send_arp_request,
|
||||
send_packet_to_net, ArpHdr, ArpRequestInfo, ArpResponse, ARP_REPLY, ARP_REQUEST,
|
||||
};
|
||||
use crate::pb::{encode_to_udp_message, SdlData};
|
||||
use crate::tcp::PacketType;
|
||||
@ -247,7 +247,7 @@ impl TunTapPacketHandler for Iface {
|
||||
|
||||
async fn handle_packet_from_device(
|
||||
&self,
|
||||
data: &[u8],
|
||||
data: Vec<u8>,
|
||||
encrypt_key: &[u8],
|
||||
) -> std::io::Result<()> {
|
||||
let eee = get_edge();
|
||||
@ -281,6 +281,8 @@ impl TunTapPacketHandler for Iface {
|
||||
do_arp_request,
|
||||
} => {
|
||||
if do_arp_request {
|
||||
add_to_arp_wait_list(dstip, data);
|
||||
|
||||
println!(
|
||||
"find ip: {:?} => {:?}",
|
||||
src.to_be_bytes(),
|
||||
@ -312,7 +314,9 @@ impl TunTapPacketHandler for Iface {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let packet = form_ethernet_packet(src_mac, mac, &data);
|
||||
// prepend the ether header
|
||||
/*
|
||||
let mut etherheader = Ethernet2Header::default();
|
||||
etherheader.destination = mac;
|
||||
etherheader.ether_type = etherparse::EtherType::IPV4;
|
||||
@ -320,6 +324,7 @@ impl TunTapPacketHandler for Iface {
|
||||
let mut packet = Vec::with_capacity(14 + data.len() + 4);
|
||||
packet.extend_from_slice(ðerheader.to_bytes()[..]);
|
||||
packet.extend_from_slice(&data);
|
||||
*/
|
||||
// let crc = CRC_HASH.checksum(&packet);
|
||||
// packet.extend_from_slice(&crc.to_be_bytes());
|
||||
|
||||
|
||||
@ -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 {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ pub use pid_recorder::PidRecorder;
|
||||
|
||||
// pub const CRC_HASH: crc::Crc<u32> = crc::Crc::<u32>::new(&crc::CRC_32_XFER);
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn caculate_crc(data: &[u8]) -> u32 {
|
||||
let res = crc32fast::hash(data);
|
||||
res
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user