diff --git a/.vscode/settings.json b/.vscode/settings.json index c4c8773..01706d9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { // "rust-analyzer.cargo.target": "x86_64-pc-windows-gnu", - "rust-analyzer.cargo.target": "x86_64-unknown-linux-gnu", + // "rust-analyzer.cargo.target": "x86_64-unknown-linux-gnu", // "rust-analyzer.cargo.features": ["tun"] } \ No newline at end of file diff --git a/src/network/arp.rs b/src/network/arp.rs index 9d7de48..dc4ff5c 100755 --- a/src/network/arp.rs +++ b/src/network/arp.rs @@ -551,17 +551,16 @@ impl ArpWaitList { if (now - item.timestamp) > 5 { continue; } - let packet = form_ethernet_packet(src_mac, mac, item.origin_data); + let mut 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"); + let encryptor = edge.encryptor.load(); + if let Err(e) = encryptor.encrypt(&mut packet) { + error!("failed to encrypt packet request: {:?}", e); return; - }; - let data_bytes = Bytes::from(encrypted); + } + let data_bytes = packet.freeze(); let data = SdlData { is_p2p: true, network_id, diff --git a/src/network/async_main.rs b/src/network/async_main.rs index e30714c..d431152 100755 --- a/src/network/async_main.rs +++ b/src/network/async_main.rs @@ -304,8 +304,10 @@ async fn get_data_from_tun_with_layer2_zeroed(eee: &Node) -> BytesMut { // let mut temp = BytesMut::with_capacity(1514); let mut data_buf = temp.split_off(14); let Ok(size) = eee.device.recv(&mut data_buf).await else { + error!("failed to receive"); return BytesMut::new(); }; + warn!("got {} bytes from tun with layer 2", size); data_buf.truncate(size); temp.unsplit(data_buf); @@ -334,6 +336,7 @@ async fn get_tun_flow(eee: &'static Node, tx: Sender) { }; if buf.len() == 0 { + error!("buf length is zero, quitting loop"); return; } if let Err(e) = tx.send(buf).await { diff --git a/src/network/packet.rs b/src/network/packet.rs index b811c08..e8f3aa7 100755 --- a/src/network/packet.rs +++ b/src/network/packet.rs @@ -1,8 +1,8 @@ use std::{net::SocketAddr, sync::atomic::Ordering, time::Duration}; -use crate::FiveTuple; use crate::pb::SdlPolicyRequest; -use crate::tcp::{NatType, get_quic_write_conn}; +use crate::tcp::{get_quic_write_conn, NatType}; +use crate::FiveTuple; use crate::{network::TunTapPacketHandler, utils::mac_to_string}; use crate::{ @@ -11,19 +11,19 @@ use crate::{ encode_to_tcp_message, encode_to_udp_message, SdlData, SdlEmpty, SdlPeerInfo, SdlQueryInfo, SdlRegister, SdlRegisterAck, SdlStunProbeReply, }, - tcp::{PacketType}, + tcp::PacketType, utils::{send_to_sock, Socket}, }; use bytes::BytesMut; -use etherparse::{Ethernet2Header, IpNumber, PacketHeaders, ip_number}; +use etherparse::{ip_number, Ethernet2Header, IpNumber, PacketHeaders}; use prost::Message; -use sdlan_sn_rs::utils::{BROADCAST_MAC}; +use sdlan_sn_rs::utils::BROADCAST_MAC; use sdlan_sn_rs::{ config::{AF_INET, AF_INET6}, peer::{is_sdlan_sock_equal, SdlanSock, V6Info}, utils::{ - get_current_timestamp, get_sdlan_sock_from_socketaddr, is_multi_broadcast, - Mac, Result, SDLanError, + get_current_timestamp, get_sdlan_sock_from_socketaddr, is_multi_broadcast, Mac, Result, + SDLanError, }, }; @@ -569,7 +569,17 @@ pub async fn check_peer_registration_needed( } let origin_family = k.sock.family; if origin_family != peer_sock.family { - return; + if peer_sock.family == AF_INET6 && origin_family == AF_INET { + info!( + "Upgrading peer {} from IPv4 to IPv6 P2P", + mac_to_string(&src_mac) + ); + + // k.sock = peer_sock.deepcopy(); + // k.last_seen.store(now, Ordering::Relaxed); + } else { + return; + } } /* if peer_sock.family == AF_INET6 && k.sock.read().unwrap().family == AF_INET { @@ -833,11 +843,8 @@ async fn renew_identity_request(eee: &Node, identity: u32) { // println!("policy request: {:?}", policy_request); // debug!("send register super: {:?}", register_super); // let packet_id = edge.get_next_packet_id(); - let data = encode_to_tcp_message( - Some(policy_request), - PacketType::PolicyRequest as u8, - ) - .unwrap(); + let data = + encode_to_tcp_message(Some(policy_request), PacketType::PolicyRequest as u8).unwrap(); let stream = get_quic_write_conn(); if let Err(e) = stream.send(data).await { @@ -855,31 +862,34 @@ async fn handle_tun_packet( //let key = eee.get_encrypt_key(); // if key.len() == 0 { - // check the encrypt key - // error!("packet encrypt key not provided"); - // return; + // check the encrypt key + // error!("packet encrypt key not provided"); + // return; // } // test_aes(key.as_slice()); - let origin = eee.encryptor.load().decrypt(&payload); - // let origin = eee.encryptor.read().unwrap().decrypt(&payload); - // let origin = aes_decrypt(&payload); - if let Err(_e) = origin { + let mut payload = BytesMut::from(payload); + let decrypt_res = eee.encryptor.load().decrypt(&mut payload); + if let Err(_e) = decrypt_res { error!("failed to decrypt original data"); return; } - let data = origin.unwrap(); + let data = payload; let Ok(headers) = PacketHeaders::from_ethernet_slice(&data) else { error!("failed to parse packet"); return; }; if _from_sn { - eee.stats.rx_sup.fetch_add(data.len() as u64, Ordering::Relaxed); + eee.stats + .rx_sup + .fetch_add(data.len() as u64, Ordering::Relaxed); } else { - eee.stats.rx_p2p.fetch_add(data.len() as u64, Ordering::Relaxed); + eee.stats + .rx_p2p + .fetch_add(data.len() as u64, Ordering::Relaxed); } if let Some(ip) = headers.net { @@ -888,7 +898,6 @@ async fn handle_tun_packet( let protocol = ipv4.protocol; match protocol { ip_number::TCP => { - let Some(transport) = headers.transport else { error!("failed to get transport header"); return; @@ -904,9 +913,13 @@ async fn handle_tun_packet( dst_ip: ipv4.source.into(), src_port: tcp_header.destination_port, dst_port: tcp_header.source_port, - proto:IpNumber::TCP.0, + proto: IpNumber::TCP.0, }; - let (valid, need_refresh) = eee.rule_cache.is_identity_ok(eee.config.allow_routing.load(Ordering::Relaxed), pkt.identity_id, five_tuple); + let (valid, need_refresh) = eee.rule_cache.is_identity_ok( + eee.config.allow_routing.load(Ordering::Relaxed), + pkt.identity_id, + five_tuple, + ); if need_refresh { renew_identity_request(eee, pkt.identity_id).await; } @@ -930,9 +943,13 @@ async fn handle_tun_packet( dst_ip: ipv4.source.into(), src_port: udp_header.destination_port, dst_port: udp_header.source_port, - proto:IpNumber::UDP.0, + proto: IpNumber::UDP.0, }; - let (valid, need_refresh) = eee.rule_cache.is_identity_ok(eee.config.allow_routing.load(Ordering::Relaxed), pkt.identity_id, five_tuple); + let (valid, need_refresh) = eee.rule_cache.is_identity_ok( + eee.config.allow_routing.load(Ordering::Relaxed), + pkt.identity_id, + five_tuple, + ); if need_refresh { renew_identity_request(eee, pkt.identity_id).await; } @@ -949,17 +966,10 @@ async fn handle_tun_packet( // just ignore, ok } } - } - - debug!("sending packet to tun, {} bytes", data.len()); - if let Err(e) = eee - .device - .handle_packet_from_net(&data) - .await - { + if let Err(e) = eee.device.handle_packet_from_net(&data).await { error!("failed to handle packet from net: {}", e.to_string()); } /* @@ -1312,7 +1322,11 @@ pub async fn update_supernode_reg(eee: &Node) { */ #[allow(unused)] -pub fn form_ethernet_packet(src_mac: Mac, dst_mac: Mac, mut data_with_zeroed_layer2: BytesMut) -> BytesMut { +pub fn form_ethernet_packet( + src_mac: Mac, + dst_mac: Mac, + mut data_with_zeroed_layer2: BytesMut, +) -> BytesMut { let mut etherheader = Ethernet2Header::default(); etherheader.destination = dst_mac; etherheader.ether_type = etherparse::EtherType::IPV4; diff --git a/src/network/tun_linux.rs b/src/network/tun_linux.rs index a134733..ae694d5 100755 --- a/src/network/tun_linux.rs +++ b/src/network/tun_linux.rs @@ -328,17 +328,16 @@ impl TunTapPacketHandler for Iface { return Ok(()); } + let mut data = data; let size = data.len(); - let encrypted = match edge.encryptor.load().encrypt(&data) { - Ok(data) => data, - Err(e) => { - error!("failed to encrypt packet request: {}", e.as_str()); - return Ok(()); - } - }; + let encryptor = edge.encryptor.load(); + if let Err(e) = encryptor.encrypt(&mut data) { + error!("failed to encrypt packet request: {:?}", e); + return Ok(()); + } - let data_bytes = Bytes::from(encrypted); + let data_bytes = data.freeze(); let data = SdlData { is_p2p: true, network_id: edge.network_id.load(Ordering::Relaxed), @@ -444,14 +443,14 @@ impl TunTapPacketHandler for Iface { arp.sipaddr = [((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 mut data_buf = BytesMut::from(arp.marshal_to_bytes().as_slice()); + let encryptor = edge.encryptor.load(); + if let Err(e) = encryptor.encrypt(&mut data_buf) { + error!("failed to encrypt arp reply: {:?}", e); + return Ok(()); + } - let data_bytes = Bytes::from(encrypted); + let data_bytes = data_buf.freeze(); let data = SdlData { is_p2p: true, @@ -607,71 +606,72 @@ impl TunTapPacketHandler for Iface { } _other => {} } + } - match eee.arp_table.get(dstip) { - Some(mac) => { - 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); + match eee.arp_table.get(dstip) { + Some(mac) => { + 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); - header.copy_from_slice(ðerheader.to_bytes()[..]); + header.copy_from_slice(ðerheader.to_bytes()[..]); - let crc = caculate_crc(&data); - header.unsplit(data); + 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()); + // 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(); - // println!("sending data with mac"); + // 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(&header) 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 encryptor = eee.encryptor.load(); + if let Err(e) = encryptor.encrypt(&mut header) { + error!("failed to encrypt packet request: {:?}", e); + return Ok(()); } - 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; + let data_bytes = header.freeze(); - 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.lookup(dstip) { - let real_ip = u32::from_be_bytes(real_ip.octets()); - let _ = eee.send_arp_request(dstip, real_ip).await; - } + 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: data_bytes, + 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; + } + 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.lookup(dstip) { + let real_ip = u32::from_be_bytes(real_ip.octets()); + let _ = eee.send_arp_request(dstip, real_ip).await; } } } diff --git a/src/network/tun_win.rs b/src/network/tun_win.rs index f865426..b19f3f9 100755 --- a/src/network/tun_win.rs +++ b/src/network/tun_win.rs @@ -10,11 +10,11 @@ use sdlan_sn_rs::utils::{ use std::io::{Error, ErrorKind}; use std::net::Ipv4Addr; use std::os::windows::process::CommandExt; -use std::process::Command; +use std::process::{Command, Stdio}; use std::sync::atomic::Ordering; use std::sync::Arc; use tracing::{debug, error, info}; -use tun_rs::AsyncDevice; +use tun_rs::{AsyncDevice, SyncDevice}; use wintun; use crate::network::{ @@ -36,16 +36,20 @@ pub struct Iface { } impl Iface { - fn new(path: &str, name: &str) -> Self { + fn new(_path: &str, name: &str) -> Self { + println!("layer = {:?}", LAYER); let dev = tun_rs::DeviceBuilder::new() - .wintun_file(path.to_string()) + // .wintun_file(path.to_string()) .name(name) - .layer(LAYER) + // .ipv4(Ipv4Addr::new(10, 10, 4, 39), Ipv4Addr::new(255, 255, 255, 0), None) + .layer(tun_rs::Layer::L3) .mtu(1280) + // .enable(true) .build_async() .expect("failed to create tun"); let idx = dev.if_index().expect("failed to get if index"); + println!("index = {}", idx); Self { device: dev, if_idx: idx, @@ -351,14 +355,14 @@ impl TunTapPacketHandler for Iface { arp.sipaddr = [((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 mut data_buf = BytesMut::from(arp.marshal_to_bytes().as_slice()); + let encryptor = edge.encryptor.load(); + if let Err(e) = encryptor.encrypt(&mut data_buf) { + error!("failed to encrypt arp reply: {:?}", e); + return Ok(()); + } - let data_bytes = Bytes::from(encrypted); + let data_bytes = data_buf.freeze(); let data = SdlData { is_p2p: true, @@ -451,140 +455,7 @@ 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, mut header: BytesMut) -> std::io::Result<()> { - use etherparse::IpHeaders; - let eee = get_edge(); let src_mac = eee.device_config.get_mac(); @@ -645,78 +516,79 @@ impl TunTapPacketHandler for Iface { } _other => {} } + } - match eee.arp_table.get(dstip) { - Some(mac) => { - 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); + match eee.arp_table.get(dstip) { + Some(mac) => { + 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); - header.copy_from_slice(ðerheader.to_bytes()[..]); + header.copy_from_slice(ðerheader.to_bytes()[..]); - let crc = caculate_crc(&data); - header.unsplit(data); + 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()); + // 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(); - // println!("sending data with mac"); + // 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(&header) 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 encryptor = eee.encryptor.load(); + if let Err(e) = encryptor.encrypt(&mut header) { + error!("failed to encrypt packet request: {:?}", e); + return Ok(()); } - None => { - header.unsplit(data); - 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; + let data_bytes = header.freeze(); - if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) { - debug!("contains dst ip {}", ip_to_string(&dstip)); - eee.arp_table.add_to_arp_wait_list(dstip, header); - let _ = eee.send_arp_request(dstip, dstip).await; - } else { - debug!("try to lookup ip: {}", ip_to_string(&dstip)); - if let Some((_, real_ip)) = eee.route_table.lookup(dstip) { - eee.arp_table.add_to_arp_wait_list( - u32::from_be_bytes(real_ip.octets()), - header, - ); - error!("got target route: {}", real_ip); - let real_ip = u32::from_be_bytes(real_ip.octets()); - let _ = eee.send_arp_request(real_ip, dstip).await; - } + 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: data_bytes, + 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; + } + None => { + header.unsplit(data); + 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)) { + debug!("contains dst ip {}", ip_to_string(&dstip)); + eee.arp_table.add_to_arp_wait_list(dstip, header); + let _ = eee.send_arp_request(dstip, dstip).await; + } else { + debug!("try to lookup ip: {}", ip_to_string(&dstip)); + if let Some((_, real_ip)) = eee.route_table.lookup(dstip) { + eee.arp_table.add_to_arp_wait_list( + u32::from_be_bytes(real_ip.octets()), + header, + ); + error!("got target route: {}", real_ip); + let real_ip = u32::from_be_bytes(real_ip.octets()); + let _ = eee.send_arp_request(real_ip, dstip).await; } } } @@ -887,8 +759,8 @@ fn create_wintun(path: &str, name: &str) -> std::io::Result { */ } -pub fn new_iface(name: &str, _mode: Mode) -> std::io::Result { - create_wintun("./wintun.dll", name) +pub fn new_iface(name: &str) -> std::io::Result { + create_wintun("wintun.dll", name) // Ok(Box::new(create_wintun("/path/to/file"))) } diff --git a/src/network/tuntap.rs b/src/network/tuntap.rs index 7d70e1d..a68c312 100755 --- a/src/network/tuntap.rs +++ b/src/network/tuntap.rs @@ -8,10 +8,10 @@ use sdlan_sn_rs::{ utils::{get_current_timestamp, ip_to_string, Mac, Result}, }; -#[cfg(feature = "tun")] +#[cfg(any(feature = "tun", target_os = "windows"))] pub const LAYER: tun_rs::Layer = tun_rs::Layer::L3; -#[cfg(not(feature = "tun"))] +#[cfg(all(not(feature = "tun"), not(target_os = "windows")))] pub const LAYER: tun_rs::Layer = tun_rs::Layer::L2; use tracing::{debug, warn}; @@ -102,17 +102,16 @@ impl ArpWaitList { if (now - item.timestamp) > 5 { continue; } - let packet = form_ethernet_packet(src_mac, mac, item.origin_data); + let mut 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"); + let encryptor = edge.encryptor.load(); + if let Err(e) = encryptor.encrypt(&mut packet) { + error!("failed to encrypt packet request: {:?}", e); return; - }; - let data_bytes = Bytes::from(encrypted); + } + let data_bytes = packet.freeze(); let data = SdlData { is_p2p: true, network_id, diff --git a/src/tcp/quic.rs b/src/tcp/quic.rs index 70b7a4c..c0836a7 100644 --- a/src/tcp/quic.rs +++ b/src/tcp/quic.rs @@ -730,12 +730,14 @@ impl ReadWriteActor { match start_stop_chan.recv().await { Some(v) => { if !v.is_start { + error!("stop called1"); started = false; return; } } _other => { // send chan is closed; + error!("stop called2"); started = false; return; } diff --git a/src/utils/encrypter.rs b/src/utils/encrypter.rs index 250962e..5d88276 100644 --- a/src/utils/encrypter.rs +++ b/src/utils/encrypter.rs @@ -3,7 +3,8 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; -use chacha20poly1305::{aead::Aead, ChaCha20Poly1305, KeyInit}; +use bytes::BytesMut; +use chacha20poly1305::{aead::AeadInPlace, ChaCha20Poly1305, KeyInit}; use sdlan_sn_rs::utils::{aes_decrypt, aes_encrypt, Result, SDLanError}; const COUNTER_MASK: u32 = (1 << 24) - 1; @@ -11,8 +12,8 @@ const COUNTER_MASK: u32 = (1 << 24) - 1; pub trait Encryptor { fn is_setted(&self) -> bool; fn set_key(&mut self, region_id: u32, key: Vec); - fn encrypt(&self, data: &[u8]) -> Result>; - fn decrypt(&self, ciphered: &[u8]) -> Result>; + fn encrypt(&self, data: &mut BytesMut) -> Result<()>; + fn decrypt(&self, data: &mut BytesMut) -> Result<()>; } pub enum MyEncryptor { @@ -46,18 +47,19 @@ impl MyEncryptor { } } - pub fn encrypt(&self, data: &[u8]) -> Result> { + pub fn encrypt(&self, data: &mut BytesMut) -> Result<()> { match self { Self::Invalid => Err(SDLanError::EncryptError("invalid encryptor".to_owned())), Self::Aes(aes) => aes.encrypt(data), Self::ChaChao20(cha) => cha.encrypt(data), } } - pub fn decrypt(&self, ciphered: &[u8]) -> Result> { + + pub fn decrypt(&self, data: &mut BytesMut) -> Result<()> { match self { Self::Invalid => Err(SDLanError::EncryptError("invalid encryptor".to_owned())), - Self::Aes(aes) => aes.decrypt(ciphered), - Self::ChaChao20(cha) => cha.decrypt(ciphered), + Self::Aes(aes) => aes.decrypt(data), + Self::ChaChao20(cha) => cha.decrypt(data), } } } @@ -89,8 +91,10 @@ impl Encryptor for Chacha20Encryptor { self.region_id = region_id; } - fn encrypt(&self, data: &[u8]) -> Result> { - // let cipher = chacha20poly1305::ChaCha20Poly1305::new(self.key.as_slice().into()); + fn encrypt(&self, data: &mut BytesMut) -> Result<()> { + let plaintext_len = data.len(); + + // Prepare nonce let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() @@ -103,36 +107,61 @@ impl Encryptor for Chacha20Encryptor { }) .unwrap() as u64; - let mut nonce = Vec::new(); - let region_id = self.region_id.to_be_bytes(); - nonce.extend_from_slice(®ion_id); + let mut nonce_bytes = [0u8; 12]; + let region_id_bytes = self.region_id.to_be_bytes(); + nonce_bytes[0..4].copy_from_slice(®ion_id_bytes); let next_data = (now << 24) | next_counter; - nonce.extend_from_slice(&next_data.to_be_bytes()); + nonce_bytes[4..12].copy_from_slice(&next_data.to_be_bytes()); + let nonce = chacha20poly1305::Nonce::from_slice(&nonce_bytes); - match self.cipher.encrypt(nonce.as_slice().into(), data) { - Ok(data) => { - nonce.extend_from_slice(&data); - Ok(nonce) - } - Err(e) => Err(SDLanError::EncryptError(e.to_string())), - } + // Make room for tag (16 bytes) at the end + data.resize(plaintext_len + 16, 0); + let (payload, tag_space) = data.split_at_mut(plaintext_len); + + // Encrypt payload in place and get tag + let tag = self + .cipher + .encrypt_in_place_detached(&nonce, &[], payload) + .map_err(|e| SDLanError::EncryptError(e.to_string()))?; + + tag_space[..16].copy_from_slice(&tag); + + // Prepend nonce (12 bytes) + let mut final_buf = BytesMut::with_capacity(12 + data.len()); + final_buf.extend_from_slice(&nonce_bytes); + final_buf.unsplit(data.split_off(0)); + *data = final_buf; + + Ok(()) } - fn decrypt(&self, ciphered: &[u8]) -> Result> { - if ciphered.len() < 12 { + fn decrypt(&self, data: &mut BytesMut) -> Result<()> { + if data.len() < 28 { return Err(SDLanError::EncryptError( "ciphered text size error".to_owned(), )); } - // let cipher = chacha20poly1305::ChaCha20Poly1305::new(self.key.as_slice().into()); - let nonce = &ciphered[0..12]; - match self.cipher.decrypt(nonce.into(), &ciphered[12..]) { - Ok(data) => Ok(data), - Err(e) => Err(SDLanError::EncryptError(format!( - "failed to decyrpt: {}", - e.to_string() - ))), - } + + // Split off the 12-byte Nonce + let mut payload = data.split_off(12); + let mut nonce_bytes = [0u8; 12]; + nonce_bytes.copy_from_slice(&data[0..12]); + let nonce = chacha20poly1305::Nonce::from_slice(&nonce_bytes); + + // Split off the 16-byte Tag + let ciphertext_len = payload.len() - 16; + let (ciphertext, tag_space) = payload.split_at_mut(ciphertext_len); + let tag = chacha20poly1305::Tag::from_slice(&tag_space[..16]); + + // Decrypt in place + self.cipher + .decrypt_in_place_detached(&nonce, &[], ciphertext, tag) + .map_err(|e| SDLanError::EncryptError(format!("failed to decrypt: {}", e.to_string())))?; + + payload.truncate(ciphertext_len); + *data = payload; + + Ok(()) } fn is_setted(&self) -> bool { @@ -155,12 +184,16 @@ impl AesEncryptor { } impl Encryptor for AesEncryptor { - fn decrypt(&self, ciphered: &[u8]) -> Result> { - aes_decrypt(&self.key, ciphered) + fn decrypt(&self, data: &mut BytesMut) -> Result<()> { + let res = aes_decrypt(&self.key, data)?; + *data = BytesMut::from(res.as_slice()); + Ok(()) } - fn encrypt(&self, data: &[u8]) -> Result> { - aes_encrypt(&self.key, data) + fn encrypt(&self, data: &mut BytesMut) -> Result<()> { + let res = aes_encrypt(&self.key, data)?; + *data = BytesMut::from(res.as_slice()); + Ok(()) } fn is_setted(&self) -> bool { @@ -172,3 +205,18 @@ impl Encryptor for AesEncryptor { self.is_setted = true; } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_chacha20_encrypt_decrypt() { + let key = vec![0u8; 32]; + let encryptor = Chacha20Encryptor::new(key, 1); + let mut data = BytesMut::from(&b"hello world"[..]); + encryptor.encrypt(&mut data).unwrap(); + encryptor.decrypt(&mut data).unwrap(); + assert_eq!(&data[..], b"hello world"); + } +}