From 12dda5d35cc4b08105df1b0e3c6b5e53fc86ac78 Mon Sep 17 00:00:00 2001 From: asxalex Date: Thu, 23 Apr 2026 10:01:40 +0800 Subject: [PATCH] fix some linux --- src/network/tun_linux.rs | 195 +++++++++++++++++++++------------------ 1 file changed, 107 insertions(+), 88 deletions(-) diff --git a/src/network/tun_linux.rs b/src/network/tun_linux.rs index 4c9d323..503b33c 100755 --- a/src/network/tun_linux.rs +++ b/src/network/tun_linux.rs @@ -2,18 +2,16 @@ use bytes::Bytes; #[cfg(not(feature = "tun"))] use bytes::BytesMut; #[cfg(feature = "tun")] -use bytes::{BytesMut}; +use bytes::BytesMut; -#[cfg(feature = "tun")] -use etherparse::{NetSlice, PacketBuilder, SlicedPacket, TransportSlice}; +use etherparse::Ethernet2Header; #[cfg(not(feature = "tun"))] use etherparse::{IpSlice, LinkSlice, NetSlice, SlicedPacket, TransportSlice}; -use etherparse::{Ethernet2Header}; +#[cfg(feature = "tun")] +use etherparse::{NetSlice, PacketBuilder, SlicedPacket, TransportSlice}; use ipnet::Ipv4Net; use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL; -use sdlan_sn_rs::utils::{ - Mac, SDLanError, ip_to_string, is_ipv6_multicast, net_bit_len_to_mask -}; +use sdlan_sn_rs::utils::{ip_to_string, is_ipv6_multicast, net_bit_len_to_mask, Mac, SDLanError}; use std::ffi::CStr; use std::ffi::{c_char, c_int}; use std::fs::{self, OpenOptions}; @@ -38,8 +36,8 @@ use crate::get_edge; #[cfg(feature = "tun")] use crate::network::parse_dns_payload; #[cfg(not(feature = "tun"))] -use crate::network::{ARP_REPLY, ArpHdr, EthHdr, parse_dns_payload}; -use crate::network::{Node, send_packet_to_net}; +use crate::network::{parse_dns_payload, ArpHdr, EthHdr, ARP_REPLY}; +use crate::network::{send_packet_to_net, Node}; #[cfg(not(feature = "tun"))] use crate::pb::SdlArpResponse; #[cfg(feature = "tun")] @@ -128,7 +126,12 @@ impl Iface { }; let has_resolvectl = check_has_resolvectl(); - Ok(Iface { fd: fs, mode, name, has_resolvectl }) + Ok(Iface { + fd: fs, + mode, + name, + has_resolvectl, + }) } else { Err(SDLanError::NormalError("failed to setup tun")) } @@ -177,7 +180,7 @@ impl Iface { } } - node.route_table.apply_system(); + node.route_table.apply_system(0); if node.config.allow_routing.load(Ordering::Relaxed) { set_allow_routing(); @@ -235,8 +238,7 @@ impl TunTapPacketHandler for Iface { } } - - #[cfg(feature="abc")] + #[cfg(feature = "abc")] async fn handle_packet_from_device( &self, data: BytesMut, @@ -259,7 +261,7 @@ impl TunTapPacketHandler for Iface { use bytes::Bytes; if hdr.ether_type == EtherType::ARP { - use crate::network::{ARP_REQUEST, ArpHdr}; + use crate::network::{ArpHdr, ARP_REQUEST}; let arp = ArpHdr::from_slice(&data); match arp.opcode { @@ -267,14 +269,14 @@ impl TunTapPacketHandler for Iface { let dest_ip = ((arp.dipaddr[0] as u32) << 16) + arp.dipaddr[1] as u32; if edge.device_config.contains(&Ipv4Addr::from_bits(dest_ip)) { - let _ = edge.send_arp_request(dest_ip, dest_ip).await; + let _ = edge.send_arp_request(dest_ip, dest_ip).await; } else { if let Some((_, real_ip)) = edge.route_table.lookup(dest_ip) { let real_ip = u32::from_be_bytes(real_ip.octets()); let _ = edge.send_arp_request(dest_ip, real_ip).await; } } - /* + /* let request = SdlArpRequest { pkt_id: edge.get_next_packet_id(), target_ip: dest_ip, @@ -296,7 +298,6 @@ impl TunTapPacketHandler for Iface { if let Some(ip) = headers.net { match ip { etherparse::NetHeaders::Ipv4(ipv4, _) => { - use crate::FiveTuple; use etherparse::IpNumber; @@ -315,7 +316,7 @@ impl TunTapPacketHandler for Iface { edge.rule_cache.touch_packet(out_five_tuple); } - // is tcp + // is tcp } IpNumber::UDP => { if let Some(udp) = transport.udp() { @@ -329,27 +330,28 @@ impl TunTapPacketHandler for Iface { edge.rule_cache.touch_packet(out_five_tuple); } } - _other => { - - } + _other => {} } } if u32::from_be_bytes(ipv4.destination) == DNS_IP { // should send to dns parse_dns_payload(edge, &headers.payload.slice()); - if let Err(e) = edge.udp_sock_for_dns.send_to(&data[14..], format!("{}:15353", edge.server_ip)).await { + if let Err(e) = edge + .udp_sock_for_dns + .send_to(&data[14..], format!("{}:15353", edge.server_ip)) + .await + { error!("failed to send request to 15353: {}", e); } // edge.udp_sock_for_dns.send_to() - return Ok(()) + return Ok(()); } } _other => { // just ignore } } - } let target = hdr.destination; @@ -359,8 +361,8 @@ impl TunTapPacketHandler for Iface { let size = data.len(); let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else { - // let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else { - // let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else { + // let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else { + // let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else { error!("failed to encrypt packet request"); return Ok(()); }; @@ -404,11 +406,11 @@ impl TunTapPacketHandler for Iface { }; // if let Some(eth) = headers.link { - use etherparse::EtherType; use bytes::Bytes; + use etherparse::EtherType; if eth.ether_type == EtherType::ARP { - use crate::network::{ARP_REQUEST, ArpHdr}; + use crate::network::{ArpHdr, ARP_REQUEST}; let arp = ArpHdr::from_slice(&data); match arp.opcode { @@ -422,7 +424,7 @@ impl TunTapPacketHandler for Iface { } if edge.device_config.contains(&Ipv4Addr::from_bits(dest_ip)) { - let _ = edge.send_arp_request(dest_ip, dest_ip).await; + let _ = edge.send_arp_request(dest_ip, dest_ip).await; } else { if let Some((_, real_ip)) = edge.route_table.lookup(dest_ip) { let real_ip = u32::from_be_bytes(real_ip.octets()); @@ -440,8 +442,7 @@ impl TunTapPacketHandler for Iface { return Ok(()); }; - if let Some(ip) = net_slice.net{ - + if let Some(ip) = net_slice.net { match ip { NetSlice::Ipv4(ipv4) => { use crate::FiveTuple; @@ -467,13 +468,20 @@ impl TunTapPacketHandler for Iface { proto: IpNumber::UDP.0, }; edge.rule_cache.touch_packet(out_five_tuple); - + if u32::from_be_bytes(ipv4.header().destination()) == DNS_IP { // should send to dns let source_ip = u32::from_be_bytes(ipv4.header().source()); - parse_dns_payload(edge, udp.payload(), layer3, source_ip, udp.source_port()).await; + parse_dns_payload( + edge, + udp.payload(), + layer3, + source_ip, + udp.source_port(), + ) + .await; // edge.udp_sock_for_dns.send_to() - return Ok(()) + return Ok(()); } } _other => { @@ -488,19 +496,18 @@ impl TunTapPacketHandler for Iface { // just ignore } } - } let target = eth.destination; if is_ipv6_multicast(&target) { return Ok(()); } - + let size = data.len(); let Ok(encrypted) = edge.encryptor.load().encrypt(&data) else { - // let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else { - // let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else { + // let Ok(encrypted) = edge.encryptor.read().unwrap().encrypt(&data) else { + // let Ok(encrypted) = aes_encrypt(encrypt_key, &data) else { error!("failed to encrypt packet request"); return Ok(()); }; @@ -521,7 +528,6 @@ impl TunTapPacketHandler for Iface { Ok(()) } - } #[cfg(feature = "tun")] @@ -589,7 +595,7 @@ impl TunTapPacketHandler for Iface { edge.arp_table.set(from_ip, arp.shwaddr); - /* + /* use crate::network::{ARP_REPLY, ArpRequestInfo, send_arp_request}; send_arp_request(ArpRequestInfo::Set { @@ -644,10 +650,9 @@ impl TunTapPacketHandler for Iface { } } ARP_REPLY => { - 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 { @@ -712,10 +717,7 @@ impl TunTapPacketHandler for Iface { Ok(()) } - async fn handle_packet_from_device( - &self, - mut header: BytesMut, - ) -> std::io::Result<()> { + async fn handle_packet_from_device(&self, mut header: BytesMut) -> std::io::Result<()> { use etherparse::IpHeaders; let eee = get_edge(); @@ -733,10 +735,8 @@ impl TunTapPacketHandler for Iface { return Ok(()); }; - match net { NetSlice::Ipv4(ipv4) => { - let dstip = u32::from_be_bytes(ipv4.header().destination()); // let dstip = u32::from_be_bytes(ipv4hdr.0.destination); debug!("packet dst ip: {:?}", ip_to_string(&dstip)); @@ -745,7 +745,9 @@ impl TunTapPacketHandler for Iface { debug!("packet src ip: {:?}", ip_to_string(&src)); // 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()) { + if (!eee.config.allow_routing.load(Ordering::Relaxed)) + && (src != eee.device_config.get_ip()) + { info!("dropping routed packet"); return Ok(()); } @@ -764,14 +766,19 @@ impl TunTapPacketHandler for Iface { // should do the dns request // println!("request for dns"); - parse_dns_payload(eee, udp.payload(), &data, src, udp.source_port()).await; + parse_dns_payload( + eee, + udp.payload(), + &data, + src, + udp.source_port(), + ) + .await; // edge.udp_sock_for_dns.send_to() return Ok(()); } } - _other => { - - } + _other => {} } match eee.arp_table.get(dstip) { @@ -788,7 +795,6 @@ impl TunTapPacketHandler for Iface { 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()); @@ -826,26 +832,25 @@ impl TunTapPacketHandler for Iface { src.to_be_bytes(), dstip.to_be_bytes() ); - debug!("no mac found for ip {:?}, sending arp request", 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; + 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; } } - } } - } } - NetSlice::Ipv6(ipv6) => { - - } + NetSlice::Ipv6(ipv6) => {} } Ok(()) } @@ -857,9 +862,7 @@ pub fn get_install_channel() -> String { fn check_has_resolvectl() -> bool { return false; - let res = Command::new("resolvectl") - .arg("status") - .output(); + let res = Command::new("resolvectl").arg("status").output(); if let Ok(_) = res { true } else { @@ -867,7 +870,7 @@ fn check_has_resolvectl() -> bool { } } -fn add_dns_route(dev_name: &str) -> Result<()>{ +fn add_dns_route(dev_name: &str) -> Result<()> { Command::new("route") .arg("add") .arg("-host") @@ -879,10 +882,7 @@ fn add_dns_route(dev_name: &str) -> Result<()>{ Ok(()) } -fn add_resolvectl( - name: &str, - network_domain: &str, -) -> Result<()>{ +fn add_resolvectl(name: &str, network_domain: &str) -> Result<()> { Command::new("resolvectl") .arg("dns") .arg(name) @@ -898,12 +898,7 @@ fn add_resolvectl( Ok(()) } -fn set_dns( - iface: &Iface, - name: &str, - network_domain: &str, - gw: &str -) -> Result<()> { +fn set_dns(iface: &Iface, name: &str, network_domain: &str, gw: &str) -> Result<()> { error!("network_domain = {}", network_domain); if iface.has_resolvectl { add_resolvectl(name, network_domain)?; @@ -929,10 +924,17 @@ pub fn restore_dns() -> Result<()> { /// /// - `new_nameservers`: 新的 nameserver 列表(IPv4/IPv6 字符串) /// - `keep_other_ns`: 是否保留原有的 nameserver(true = 追加到新列表后,false = 完全替换) -pub fn modify_resolv_conf(new_nameservers: &[String], search_domain: &str, keep_other_ns: bool) -> Result<()> { +pub fn modify_resolv_conf( + new_nameservers: &[String], + search_domain: &str, + keep_other_ns: bool, +) -> Result<()> { let path = Path::new(RESOLV_FILE); if !path.exists() { - return Err(SDLanError::IOError(format!("{} does not exists", RESOLV_FILE))); + return Err(SDLanError::IOError(format!( + "{} does not exists", + RESOLV_FILE + ))); } // 读取原文件权限和元数据 @@ -950,7 +952,7 @@ pub fn modify_resolv_conf(new_nameservers: &[String], search_domain: &str, keep_ lines.push(format!("nameserver {}", ns)) } lines.push(format!("search {}", search_domain)); - /* + /* let mut inserted = false; let mut encounted_nameserver = false; let mut search_added = false; @@ -1020,7 +1022,10 @@ fn backup_resolv_conf() -> Result<()> { let dst = Path::new(RESOLV_FILE_BACKUP); if !src.exists() { - return Err(SDLanError::IOError(format!("{} does not exists", RESOLV_FILE))); + return Err(SDLanError::IOError(format!( + "{} does not exists", + RESOLV_FILE + ))); // anyhow::bail!("Source /etc/resolv.conf does not exist"); } @@ -1054,7 +1059,10 @@ fn restore_resolv_conf() -> Result<()> { let dst = Path::new(RESOLV_FILE); if !src.exists() { - return Err(SDLanError::IOError(format!("{} does not exists", RESOLV_FILE_BACKUP))); + return Err(SDLanError::IOError(format!( + "{} does not exists", + RESOLV_FILE_BACKUP + ))); } // 如果目标是符号链接,先删除链接再复制(避免写入到链接指向位置) @@ -1094,7 +1102,7 @@ pub fn del_route(net: &Ipv4Net, gw: &Ipv4Addr) -> Result<()> { Ok(()) } -pub fn add_route(net: &Ipv4Net, gw: &Ipv4Addr) -> Result<()> { +pub fn add_route(net: &Ipv4Net, gw: &Ipv4Addr, _ifidx: u32) -> Result<()> { let res = Command::new("route") .arg("add") .arg("-net") @@ -1152,13 +1160,17 @@ 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)); + error!( + "invalid target_mac: {:?}, ip={}", + data.target_mac, + ip_to_string(&data.target_ip) + ); return; } let ip = data.origin_ip; let mac = data.target_mac.try_into().unwrap(); - + edge.arp_table.set(ip, mac); edge.arp_table.arp_arrived(ip, mac).await; } @@ -1168,7 +1180,11 @@ 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)); + error!( + "invalid target_mac: {:?}, ip={}", + data.target_mac, + ip_to_string(&data.target_ip) + ); return; } // TODO: construct the arp reply, and write to tun; @@ -1179,12 +1195,12 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) { write_arp_to_device(edge, src_mac, src_ip); } -#[cfg(not(feature="tun"))] +#[cfg(not(feature = "tun"))] pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) { let dst_mac = edge.device_config.get_mac(); let dst_ip = edge.device_config.get_ip(); - let hdr = ArpHdr{ + let hdr = ArpHdr { ethhdr: EthHdr { dest: dst_mac, src: src_mac, @@ -1198,11 +1214,14 @@ pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) { shwaddr: src_mac, sipaddr: [((src_ip >> 16) as u16) & 0xffff, (src_ip as u16) & 0xffff], dhwaddr: dst_mac, - dipaddr: [((dst_ip >> 16) & 0x0000ffff) as u16, (dst_ip & 0x0000ffff) as u16] + dipaddr: [ + ((dst_ip >> 16) & 0x0000ffff) as u16, + (dst_ip & 0x0000ffff) as u16, + ], }; let data = hdr.marshal_to_bytes(); if let Err(_e) = edge.device.send(&data) { error!("failed to write arp response to device"); } -} \ No newline at end of file +}