add arp to waitlist
This commit is contained in:
parent
e7352c7b67
commit
69255d7907
3
Makefile
3
Makefile
@ -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
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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(ðerheader.to_bytes()[..]);
|
||||||
|
packet.extend_from_slice(&data);
|
||||||
|
packet
|
||||||
|
}
|
||||||
|
|||||||
@ -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(ðerheader.to_bytes()[..]);
|
packet.extend_from_slice(ðerheader.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());
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user