From 732b3f4a0a09dee8cbc5d8ac2426da4b17fba5d0 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 9 Apr 2026 17:55:21 +0800 Subject: [PATCH] fix windows --- .vscode/settings.json | 2 +- src/network/node.rs | 4 +- src/network/tun_linux.rs | 2 +- src/network/tun_win.rs | 319 +++++++++++++++++++++++++++++---------- src/tcp/quic.rs | 1 - src/tcp/tcp_codec.rs | 6 +- src/utils/acl_session.rs | 1 + 7 files changed, 251 insertions(+), 84 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index fb0827b..9eb94d8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { - // "rust-analyzer.cargo.target": "x86_64-pc-windows-gnu", + "rust-analyzer.cargo.target": "x86_64-pc-windows-gnu", // "rust-analyzer.cargo.features": ["tun"] } \ No newline at end of file diff --git a/src/network/node.rs b/src/network/node.rs index 9697adf..1acbee1 100755 --- a/src/network/node.rs +++ b/src/network/node.rs @@ -219,7 +219,7 @@ pub struct Node { // store pending, and known peers pub pending_peers: PeerMap, - #[cfg(feature = "tun")] + #[cfg(any(feature = "tun", target_os = "windows"))] pub arp_table: ArpTable, pub known_peers: PeerMap, @@ -400,7 +400,7 @@ impl Node { Self { - #[cfg(feature = "tun")] + #[cfg(any(feature = "tun", target_os = "windows"))] arp_table: ArpTable::new(), packet_id: AtomicU32::new(1), diff --git a/src/network/tun_linux.rs b/src/network/tun_linux.rs index 8c888cc..383af46 100755 --- a/src/network/tun_linux.rs +++ b/src/network/tun_linux.rs @@ -593,7 +593,7 @@ impl TunTapPacketHandler for Iface { debug!("packet src ip: {:?}", ipv4hdr.0.source); // packet should be sent to dev debug!("got {} bytes from tun", data.len()); - if (!eee.config.allow_routing) && (src != eee.device_config.get_ip()) { + if (!eee.config.allow_routing.load(Ordering::Relaxed)) && (src != eee.device_config.get_ip()) { info!("dropping routed packet"); return Ok(()); } diff --git a/src/network/tun_win.rs b/src/network/tun_win.rs index 29dc950..b6f8c89 100755 --- a/src/network/tun_win.rs +++ b/src/network/tun_win.rs @@ -1,4 +1,4 @@ -use bytes::Bytes; +use bytes::{Bytes, BytesMut}; use etherparse::ether_type::ARP; use etherparse::{Ethernet2Header, IpHeaders}; use ipnet::Ipv4Net; @@ -15,11 +15,11 @@ use std::sync::Arc; use tracing::{debug, error, info}; use wintun; -use crate::get_edge; +use crate::{caculate_crc, get_edge}; use crate::network::{ - ARP_REPLY, ARP_REQUEST, ArpHdr, ArpRequestInfo, ArpResponse, DNS_IP, Node, add_to_arp_wait_list, arp_arrived, form_ethernet_packet, generate_arp_request, send_arp_request, send_packet_to_net + ARP_REPLY, ARP_REQUEST, ArpHdr, DNS_IP, Node, form_ethernet_packet, generate_arp_request, send_packet_to_net }; -use crate::pb::{encode_to_udp_message, SdlData}; +use crate::pb::{SdlArpResponse, SdlData, encode_to_udp_message}; use crate::tcp::PacketType; use crate::utils::mac_to_string; @@ -136,19 +136,21 @@ impl Iface { impl TunTapPacketHandler for Iface { async fn handle_packet_from_net(&self, data: &[u8]) -> std::io::Result<()> { - // got layer 2 frame + match Ethernet2Header::from_slice(&data) { Ok((hdr, rest)) => { + use etherparse::ether_type::ARP; + use sdlan_sn_rs::utils::is_multi_broadcast; + if rest.len() < 4 { error!("payload length error"); return Ok(()); } // let crc_code = &rest[(rest.len() - 4)..rest.len()]; - // let rest = &rest[..(rest.len() - 4)]; // let crc_hash: crc::Crc = crc::Crc::::new(&crc::CRC_32_CKSUM); - // let ck = CRC_HASH.checksum(&data[..(data.len()) - 4]); + // let ck = caculate_crc(&data[..(data.len() - 4)]); // let sent_ck = u32::from_be_bytes(crc_code.try_into().unwrap()); // debug!("ck = {}, sent_ck = {}", ck, sent_ck); @@ -156,7 +158,9 @@ impl TunTapPacketHandler for Iface { let edge = get_edge(); let self_mac = edge.device_config.get_mac(); - if hdr.destination != self_mac && hdr.destination != BROADCAST_MAC { + if hdr.destination != self_mac && !is_multi_broadcast(&hdr.destination) { + use sdlan_sn_rs::utils::mac_to_string; + error!( "packet to [{:?}] not direct to us", mac_to_string(&hdr.destination) @@ -165,14 +169,16 @@ impl TunTapPacketHandler for Iface { } if hdr.ether_type == ARP { + use crate::network::ArpHdr; + let mut arp = ArpHdr::from_slice(&data); let self_ip = edge.device_config.get_ip(); - debug!("self_ip: {:?}", self_ip.to_be_bytes()); + // println!("self_ip: {:?}", self_ip.to_be_bytes()); let from_ip = ((arp.sipaddr[0] as u32) << 16) + arp.sipaddr[1] as u32; - debug!("from_ip: {:?}", from_ip.to_be_bytes()); + // println!("from_ip: {:?}", from_ip.to_be_bytes()); let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32; - debug!("dest_ip: {:?}", dest_ip.to_be_bytes()); + // println!("dest_ip: {:?}", dest_ip.to_be_bytes()); match arp.opcode { ARP_REQUEST => { @@ -183,11 +189,23 @@ impl TunTapPacketHandler for Iface { return Ok(()); } if dest_ip == self_ip { + use bytes::Bytes; + use sdlan_sn_rs::utils::mac_to_string; + + use crate::network::ARP_REPLY; + + edge.arp_table.set(from_ip, arp.shwaddr); + + /* + use crate::network::{ARP_REPLY, ArpRequestInfo, send_arp_request}; + send_arp_request(ArpRequestInfo::Set { ip: from_ip, mac: arp.shwaddr, }) .await; + */ + // target to us arp.opcode = ARP_REPLY; arp.dhwaddr = arp.shwaddr; @@ -201,21 +219,21 @@ impl TunTapPacketHandler for Iface { [((self_ip >> 16) & 0xffff) as u16, (self_ip & 0xffff) as u16]; let data = arp.marshal_to_bytes(); - - // let Ok(encrypted) = aes_encrypt(key, &data) else { let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else { error!("failed to encrypt arp reply"); return Ok(()); }; + let data_bytes = Bytes::from(encrypted); + let data = SdlData { is_p2p: true, ttl: 2, network_id: edge.network_id.load(Ordering::Relaxed), src_mac: Vec::from(self_mac), dst_mac: Vec::from(arp.dhwaddr), - data: Bytes::from(encrypted), + data: data_bytes, session_token: edge.session_token.get(), identity_id: edge.identity_id.load(), }; @@ -236,12 +254,19 @@ impl TunTapPacketHandler for Iface { debug!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes()); if dest_ip == self_ip { + /* + use crate::network::{ArpRequestInfo, arp_arrived, send_arp_request}; + send_arp_request(ArpRequestInfo::Set { ip: from_ip, mac: arp.shwaddr, }) .await; - arp_arrived(from_ip, arp.shwaddr).await; + */ + + // use crate::network::arp_arrived; + edge.arp_table.set(from_ip, arp.shwaddr); + edge.arp_table.arp_arrived(from_ip, arp.shwaddr).await; } } _other => { @@ -249,6 +274,8 @@ impl TunTapPacketHandler for Iface { } } } else { + use etherparse::IpHeaders; + match IpHeaders::from_slice(rest) { Ok((iphdr, _)) => { let Some(ipv4) = iphdr.ipv4() else { @@ -258,7 +285,10 @@ impl TunTapPacketHandler for Iface { let ip = u32::from_be_bytes(ipv4.0.source); let mac = hdr.source; if !is_multi_broadcast(&mac) { - send_arp_request(ArpRequestInfo::Set { ip, mac }).await; + //use crate::network::{ArpRequestInfo, send_arp_request}; + + edge.arp_table.set(ip, mac); + // send_arp_request(ArpRequestInfo::Set { ip, mac }).await; } } Err(_) => { @@ -267,6 +297,8 @@ impl TunTapPacketHandler for Iface { } } + // println!("got ip packet"); + // println!("got data: {:?}", rest); match edge.device.send(rest) { Ok(size) => { debug!("send to tun {} bytes", size); @@ -279,7 +311,7 @@ impl TunTapPacketHandler for Iface { } } Err(e) => { - error!("failed to parse tap packet: {}", e); + error!("failed to parse tun packet: {}", e); return Ok(()); } } @@ -287,17 +319,153 @@ impl TunTapPacketHandler for Iface { Ok(()) } + // async fn handle_packet_from_device( + // &self, + // data: BytesMut, + // // encrypt_key: &[u8], + // ) -> std::io::Result<()> { + // let eee = get_edge(); + + // let src_mac = eee.device_config.get_mac(); + + // match IpHeaders::from_slice(&data) { + // Ok((iphdr, _payload)) => { + // let Some(ipv4hdr) = iphdr.ipv4() else { + // debug!("ipv6 packet ignored"); + // return Ok(()); + // }; + // let dstip = u32::from_be_bytes(ipv4hdr.0.destination); + // debug!("packet dst ip: {:?}", ipv4hdr.0.destination); + // let src = u32::from_be_bytes(ipv4hdr.0.source); + // debug!("packet src ip: {:?}", ipv4hdr.0.source); + // // packet should be sent to dev + // debug!("got {} bytes from tun", data.len()); + // if (!eee.config.allow_routing.load(Ordering::Relaxed)) && (src != eee.device_config.get_ip()) { + // info!("dropping routed packet"); + // return Ok(()); + // } + // if !eee.is_authorized() { + // debug!("drop tun packet due to not authed"); + // return Ok(()); + // } + // if dstip == DNS_IP { + // // println!("request for dns"); + // let addr = format!("{}:15353", eee.server_ip); + // // println!("send dns to {}", addr); + // if let Err(e) = eee.udp_sock_for_dns.send_to(&data, &addr).await { + // error!("failed to send request to 15353: {}", e); + // } + // return Ok(()); + // } + // match send_arp_request(ArpRequestInfo::Lookup { ip: dstip }).await { + // ArpResponse::LookupResp { + // mac, + // ip, + // do_arp_request, + // } => { + // if do_arp_request { + // add_to_arp_wait_list(dstip, data); + + // info!( + // "find ip: {:?} => {:?}", + // src.to_be_bytes(), + // dstip.to_be_bytes() + // ); + // let arp_msg = + // generate_arp_request(src_mac, ip, eee.device_config.get_ip()); + + // let Ok(encrypted) = eee.encryptor.load().encrypt(&arp_msg) else { + // // let Ok(encrypted) = aes_encrypt(&encrypt_key, &arp_msg) else { + // error!("failed to encrypt arp request"); + // return Ok(()); + // }; + // // println!("arp_msg: {:?}", arp_msg); + // let data = SdlData { + // network_id: eee.network_id.load(Ordering::Relaxed), + // src_mac: Vec::from(src_mac), + // dst_mac: Vec::from([0xff; 6]), + // is_p2p: true, + // ttl: SDLAN_DEFAULT_TTL as u32, + // data: Bytes::from(encrypted), + + // session_token: eee.session_token.get(), + // identity_id: eee.identity_id.load(), + // }; + // let data = + // encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); + // debug!("sending arp"); + // // let data = marshal_message(&data); + // send_packet_to_net(eee, BROADCAST_MAC, &data, arp_msg.len() as u64) + // .await; + // // edge.sock.send(data).await; + // // println!("should send arp"); + // 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; + // 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); + // */ + // // let crc = CRC_HASH.checksum(&packet); + // // packet.extend_from_slice(&crc.to_be_bytes()); + + // let pkt_size = packet.len(); + // // println!("sending data with mac"); + + // // let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else { + // let Ok(encrypted) = eee.encryptor.load().encrypt(&packet) else { + // error!("failed to encrypt packet request"); + // return Ok(()); + // }; + // let data = SdlData { + // is_p2p: true, + // network_id: eee.network_id.load(Ordering::Relaxed), + // ttl: SDLAN_DEFAULT_TTL as u32, + // src_mac: Vec::from(src_mac), + // dst_mac: Vec::from(mac), + // data: Bytes::from(encrypted), + // session_token: eee.session_token.get(), + // identity_id: eee.identity_id.load(), + // }; + // let msg = + // encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); + // let size = msg.len(); + // send_packet_to_net(eee, mac, &msg, pkt_size as u64).await; + // // let dstip = u32::from_be_bytes(ipv4hdr.0.destination); + // } + // _ => {} + // } + // } + // Err(e) => { + // error!("failed to parse ip packet: {}", e.to_string()); + // } + // } + // Ok(()) + // } + async fn handle_packet_from_device( &self, - data: Vec, - // encrypt_key: &[u8], + mut header: BytesMut, ) -> std::io::Result<()> { + use etherparse::IpHeaders; + let eee = get_edge(); let src_mac = eee.device_config.get_mac(); + let data = header.split_off(14); + match IpHeaders::from_slice(&data) { Ok((iphdr, _payload)) => { + //use crate::network::{ArpRequestInfo, ArpResponse, send_arp_request}; + let Some(ipv4hdr) = iphdr.ipv4() else { debug!("ipv6 packet ignored"); return Ok(()); @@ -308,7 +476,7 @@ impl TunTapPacketHandler for Iface { debug!("packet src ip: {:?}", ipv4hdr.0.source); // packet should be sent to dev debug!("got {} bytes from tun", data.len()); - if (!eee.config.allow_routing) && (src != eee.device_config.get_ip()) { + if (!eee.config.allow_routing.load(Ordering::Relaxed)) && (src != eee.device_config.get_ip()) { info!("dropping routed packet"); return Ok(()); } @@ -317,6 +485,7 @@ impl TunTapPacketHandler for Iface { return Ok(()); } if dstip == DNS_IP { + // should do the dns request // println!("request for dns"); let addr = format!("{}:15353", eee.server_ip); // println!("send dns to {}", addr); @@ -325,73 +494,36 @@ impl TunTapPacketHandler for Iface { } return Ok(()); } - match send_arp_request(ArpRequestInfo::Lookup { ip: dstip }).await { - ArpResponse::LookupResp { - mac, - ip, - do_arp_request, - } => { - if do_arp_request { - add_to_arp_wait_list(dstip, data); + match eee.arp_table.get(dstip) { + Some(mac) => { - info!( - "find ip: {:?} => {:?}", - src.to_be_bytes(), - dstip.to_be_bytes() - ); - let arp_msg = - generate_arp_request(src_mac, ip, eee.device_config.get_ip()); - - let Ok(encrypted) = eee.encryptor.load().encrypt(&arp_msg) else { - // let Ok(encrypted) = aes_encrypt(&encrypt_key, &arp_msg) else { - error!("failed to encrypt arp request"); - return Ok(()); - }; - // println!("arp_msg: {:?}", arp_msg); - let data = SdlData { - network_id: eee.network_id.load(Ordering::Relaxed), - src_mac: Vec::from(src_mac), - dst_mac: Vec::from([0xff; 6]), - is_p2p: true, - ttl: SDLAN_DEFAULT_TTL as u32, - data: Bytes::from(encrypted), - - session_token: eee.session_token.get(), - identity_id: eee.identity_id.load(), - }; - let data = - encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); - debug!("sending arp"); - // let data = marshal_message(&data); - send_packet_to_net(eee, BROADCAST_MAC, &data, arp_msg.len() as u64) - .await; - // edge.sock.send(data).await; - // println!("should send arp"); - return Ok(()); - } - - let packet = form_ethernet_packet(src_mac, mac, &data); - // prepend the ether header - /* + let pkt_size = data.len() + 14; let mut etherheader = Ethernet2Header::default(); etherheader.destination = 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); - */ - // let crc = CRC_HASH.checksum(&packet); + // let mut packet = Vec::with_capacity(14 + data.len() + 4); + + header.copy_from_slice(ðerheader.to_bytes()[..]); + + let crc = caculate_crc(&data); + header.unsplit(data); + + + // packet.extend_from_slice(ðerheader.to_bytes()[..]); + // packet.extend_from_slice(&data); + header.extend_from_slice(&crc.to_be_bytes()); // packet.extend_from_slice(&crc.to_be_bytes()); - let pkt_size = packet.len(); + // let pkt_size = packet.len(); // println!("sending data with mac"); // let Ok(encrypted) = aes_encrypt(&encrypt_key, &packet) else { - let Ok(encrypted) = eee.encryptor.load().encrypt(&packet) else { + let Ok(encrypted) = eee.encryptor.load().encrypt(&header) else { error!("failed to encrypt packet request"); return Ok(()); }; + let data = SdlData { is_p2p: true, network_id: eee.network_id.load(Ordering::Relaxed), @@ -406,10 +538,30 @@ impl TunTapPacketHandler for Iface { encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); let size = msg.len(); send_packet_to_net(eee, mac, &msg, pkt_size as u64).await; - // let dstip = u32::from_be_bytes(ipv4hdr.0.destination); } - _ => {} + None => { + header.unsplit(data); + eee.arp_table.add_to_arp_wait_list(dstip, header); + debug!( + "find ip: {:?} => {:?}", + src.to_be_bytes(), + dstip.to_be_bytes() + ); + debug!("no mac found for ip {:?}, sending arp request", dstip.to_be_bytes()); + // let _ = eee.send_arp_request(dstip, dstip).await; + + if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) { + let _ = eee.send_arp_request(dstip, dstip).await; + } else { + if let Some((_, real_ip)) = eee.route_table.route_table.lookup(dstip) { + let real_ip = u32::from_be_bytes(real_ip.octets()); + let _ = eee.send_arp_request(dstip, real_ip).await; + } + } + + } } + } Err(e) => { error!("failed to parse ip packet: {}", e.to_string()); @@ -506,4 +658,19 @@ pub fn add_route(net: &Ipv4Net, gw: &Ipv4Addr) -> Result<()> { .arg(gw.to_string()) .output()?; Ok(()) +} + + +pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) { + debug!("got arp response: {:?}", data); + if data.target_mac.len() != 6 { + // invalid target_mac + error!("invalid target_mac: {:?}, ip={}", data.target_mac, ip_to_string(&data.target_ip)); + return; + } + + let ip = data.target_ip; + let mac = data.target_mac.try_into().unwrap(); + + edge.arp_table.arp_arrived(ip, mac).await; } \ No newline at end of file diff --git a/src/tcp/quic.rs b/src/tcp/quic.rs index 0a2afe6..35e77a9 100644 --- a/src/tcp/quic.rs +++ b/src/tcp/quic.rs @@ -1,7 +1,6 @@ use std::{net::IpAddr, sync::{Arc, OnceLock, atomic::{AtomicBool, AtomicU64, Ordering}}, time::Duration}; use futures_util::pin_mut; -use libc::PR_SET_THP_DISABLE; use prost::Message; use quinn::SendStream; use sdlan_sn_rs::{config::AF_INET, peer::{SdlanSock, V6Info}, utils::{Result, SDLanError, get_current_timestamp, ip_to_string, rsa_decrypt}}; diff --git a/src/tcp/tcp_codec.rs b/src/tcp/tcp_codec.rs index 11d6c44..f542795 100755 --- a/src/tcp/tcp_codec.rs +++ b/src/tcp/tcp_codec.rs @@ -138,11 +138,11 @@ pub async fn send_stun_request(eee: &Node) { pub async fn read_a_packet( reader: &mut RecvStream, ) -> Result { - debug!("read a packet"); + // debug!("read a packet"); let payload_size = reader.read_u16().await?; - debug!("1"); + // debug!("payload size: {}", payload_size); let packet_type = reader.read_u8().await?; - debug!("3"); + // debug!("packet type: 0x{:02x}", packet_type); if payload_size < 1 { return Err(std::io::Error::new( diff --git a/src/utils/acl_session.rs b/src/utils/acl_session.rs index 22f723d..5c16269 100644 --- a/src/utils/acl_session.rs +++ b/src/utils/acl_session.rs @@ -139,6 +139,7 @@ impl RuleCache { } pub fn is_identity_ok(&self, identity: IdentityID, info: FiveTuple) -> (bool, ShouldRenew) { + return (true, false); error!("is identity ok? {:?}", info); if self.session_table.process_packet(&info) { error!("identity is ok");