fix some linux

This commit is contained in:
asxalex 2026-04-23 10:01:40 +08:00
parent 6874bc5291
commit 12dda5d35c

View File

@ -2,18 +2,16 @@ use bytes::Bytes;
#[cfg(not(feature = "tun"))] #[cfg(not(feature = "tun"))]
use bytes::BytesMut; use bytes::BytesMut;
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
use bytes::{BytesMut}; use bytes::BytesMut;
#[cfg(feature = "tun")] use etherparse::Ethernet2Header;
use etherparse::{NetSlice, PacketBuilder, SlicedPacket, TransportSlice};
#[cfg(not(feature = "tun"))] #[cfg(not(feature = "tun"))]
use etherparse::{IpSlice, LinkSlice, NetSlice, SlicedPacket, TransportSlice}; use etherparse::{IpSlice, LinkSlice, NetSlice, SlicedPacket, TransportSlice};
use etherparse::{Ethernet2Header}; #[cfg(feature = "tun")]
use etherparse::{NetSlice, PacketBuilder, SlicedPacket, TransportSlice};
use ipnet::Ipv4Net; use ipnet::Ipv4Net;
use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL; use sdlan_sn_rs::config::SDLAN_DEFAULT_TTL;
use sdlan_sn_rs::utils::{ use sdlan_sn_rs::utils::{ip_to_string, is_ipv6_multicast, net_bit_len_to_mask, Mac, SDLanError};
Mac, SDLanError, ip_to_string, is_ipv6_multicast, net_bit_len_to_mask
};
use std::ffi::CStr; use std::ffi::CStr;
use std::ffi::{c_char, c_int}; use std::ffi::{c_char, c_int};
use std::fs::{self, OpenOptions}; use std::fs::{self, OpenOptions};
@ -38,8 +36,8 @@ use crate::get_edge;
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
use crate::network::parse_dns_payload; use crate::network::parse_dns_payload;
#[cfg(not(feature = "tun"))] #[cfg(not(feature = "tun"))]
use crate::network::{ARP_REPLY, ArpHdr, EthHdr, parse_dns_payload}; use crate::network::{parse_dns_payload, ArpHdr, EthHdr, ARP_REPLY};
use crate::network::{Node, send_packet_to_net}; use crate::network::{send_packet_to_net, Node};
#[cfg(not(feature = "tun"))] #[cfg(not(feature = "tun"))]
use crate::pb::SdlArpResponse; use crate::pb::SdlArpResponse;
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
@ -128,7 +126,12 @@ impl Iface {
}; };
let has_resolvectl = check_has_resolvectl(); let has_resolvectl = check_has_resolvectl();
Ok(Iface { fd: fs, mode, name, has_resolvectl }) Ok(Iface {
fd: fs,
mode,
name,
has_resolvectl,
})
} else { } else {
Err(SDLanError::NormalError("failed to setup tun")) 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) { if node.config.allow_routing.load(Ordering::Relaxed) {
set_allow_routing(); set_allow_routing();
@ -235,8 +238,7 @@ impl TunTapPacketHandler for Iface {
} }
} }
#[cfg(feature = "abc")]
#[cfg(feature="abc")]
async fn handle_packet_from_device( async fn handle_packet_from_device(
&self, &self,
data: BytesMut, data: BytesMut,
@ -259,7 +261,7 @@ impl TunTapPacketHandler for Iface {
use bytes::Bytes; use bytes::Bytes;
if hdr.ether_type == EtherType::ARP { if hdr.ether_type == EtherType::ARP {
use crate::network::{ARP_REQUEST, ArpHdr}; use crate::network::{ArpHdr, ARP_REQUEST};
let arp = ArpHdr::from_slice(&data); let arp = ArpHdr::from_slice(&data);
match arp.opcode { match arp.opcode {
@ -296,7 +298,6 @@ impl TunTapPacketHandler for Iface {
if let Some(ip) = headers.net { if let Some(ip) = headers.net {
match ip { match ip {
etherparse::NetHeaders::Ipv4(ipv4, _) => { etherparse::NetHeaders::Ipv4(ipv4, _) => {
use crate::FiveTuple; use crate::FiveTuple;
use etherparse::IpNumber; use etherparse::IpNumber;
@ -329,27 +330,28 @@ impl TunTapPacketHandler for Iface {
edge.rule_cache.touch_packet(out_five_tuple); edge.rule_cache.touch_packet(out_five_tuple);
} }
} }
_other => { _other => {}
}
} }
} }
if u32::from_be_bytes(ipv4.destination) == DNS_IP { if u32::from_be_bytes(ipv4.destination) == DNS_IP {
// should send to dns // should send to dns
parse_dns_payload(edge, &headers.payload.slice()); 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); error!("failed to send request to 15353: {}", e);
} }
// edge.udp_sock_for_dns.send_to() // edge.udp_sock_for_dns.send_to()
return Ok(()) return Ok(());
} }
} }
_other => { _other => {
// just ignore // just ignore
} }
} }
} }
let target = hdr.destination; let target = hdr.destination;
@ -404,11 +406,11 @@ impl TunTapPacketHandler for Iface {
}; };
// if let Some(eth) = headers.link { // if let Some(eth) = headers.link {
use etherparse::EtherType;
use bytes::Bytes; use bytes::Bytes;
use etherparse::EtherType;
if eth.ether_type == EtherType::ARP { if eth.ether_type == EtherType::ARP {
use crate::network::{ARP_REQUEST, ArpHdr}; use crate::network::{ArpHdr, ARP_REQUEST};
let arp = ArpHdr::from_slice(&data); let arp = ArpHdr::from_slice(&data);
match arp.opcode { match arp.opcode {
@ -440,8 +442,7 @@ impl TunTapPacketHandler for Iface {
return Ok(()); return Ok(());
}; };
if let Some(ip) = net_slice.net{ if let Some(ip) = net_slice.net {
match ip { match ip {
NetSlice::Ipv4(ipv4) => { NetSlice::Ipv4(ipv4) => {
use crate::FiveTuple; use crate::FiveTuple;
@ -471,9 +472,16 @@ impl TunTapPacketHandler for Iface {
if u32::from_be_bytes(ipv4.header().destination()) == DNS_IP { if u32::from_be_bytes(ipv4.header().destination()) == DNS_IP {
// should send to dns // should send to dns
let source_ip = u32::from_be_bytes(ipv4.header().source()); 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() // edge.udp_sock_for_dns.send_to()
return Ok(()) return Ok(());
} }
} }
_other => { _other => {
@ -488,7 +496,6 @@ impl TunTapPacketHandler for Iface {
// just ignore // just ignore
} }
} }
} }
let target = eth.destination; let target = eth.destination;
@ -521,7 +528,6 @@ impl TunTapPacketHandler for Iface {
Ok(()) Ok(())
} }
} }
#[cfg(feature = "tun")] #[cfg(feature = "tun")]
@ -644,7 +650,6 @@ impl TunTapPacketHandler for Iface {
} }
} }
ARP_REPLY => { ARP_REPLY => {
debug!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes()); debug!("mac {:?} is at {:?}", arp.shwaddr, from_ip.to_be_bytes());
if dest_ip == self_ip { if dest_ip == self_ip {
/* /*
@ -712,10 +717,7 @@ impl TunTapPacketHandler for Iface {
Ok(()) Ok(())
} }
async fn handle_packet_from_device( async fn handle_packet_from_device(&self, mut header: BytesMut) -> std::io::Result<()> {
&self,
mut header: BytesMut,
) -> std::io::Result<()> {
use etherparse::IpHeaders; use etherparse::IpHeaders;
let eee = get_edge(); let eee = get_edge();
@ -733,10 +735,8 @@ impl TunTapPacketHandler for Iface {
return Ok(()); return Ok(());
}; };
match net { match net {
NetSlice::Ipv4(ipv4) => { NetSlice::Ipv4(ipv4) => {
let dstip = u32::from_be_bytes(ipv4.header().destination()); let dstip = u32::from_be_bytes(ipv4.header().destination());
// let dstip = u32::from_be_bytes(ipv4hdr.0.destination); // let dstip = u32::from_be_bytes(ipv4hdr.0.destination);
debug!("packet dst ip: {:?}", ip_to_string(&dstip)); debug!("packet dst ip: {:?}", ip_to_string(&dstip));
@ -745,7 +745,9 @@ impl TunTapPacketHandler for Iface {
debug!("packet src ip: {:?}", ip_to_string(&src)); debug!("packet src ip: {:?}", ip_to_string(&src));
// packet should be sent to dev // packet should be sent to dev
debug!("got {} bytes from tun", data.len()); 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"); info!("dropping routed packet");
return Ok(()); return Ok(());
} }
@ -764,14 +766,19 @@ impl TunTapPacketHandler for Iface {
// should do the dns request // should do the dns request
// println!("request for dns"); // 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() // edge.udp_sock_for_dns.send_to()
return Ok(()); return Ok(());
} }
} }
_other => { _other => {}
}
} }
match eee.arp_table.get(dstip) { match eee.arp_table.get(dstip) {
@ -788,7 +795,6 @@ impl TunTapPacketHandler for Iface {
let crc = caculate_crc(&data); let crc = caculate_crc(&data);
header.unsplit(data); header.unsplit(data);
// packet.extend_from_slice(&etherheader.to_bytes()[..]); // packet.extend_from_slice(&etherheader.to_bytes()[..]);
// packet.extend_from_slice(&data); // packet.extend_from_slice(&data);
header.extend_from_slice(&crc.to_be_bytes()); header.extend_from_slice(&crc.to_be_bytes());
@ -826,7 +832,10 @@ impl TunTapPacketHandler for Iface {
src.to_be_bytes(), src.to_be_bytes(),
dstip.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; // let _ = eee.send_arp_request(dstip, dstip).await;
if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) { if eee.device_config.contains(&Ipv4Addr::from_bits(dstip)) {
@ -837,15 +846,11 @@ impl TunTapPacketHandler for Iface {
let _ = eee.send_arp_request(dstip, real_ip).await; let _ = eee.send_arp_request(dstip, real_ip).await;
} }
} }
} }
} }
} }
} }
NetSlice::Ipv6(ipv6) => { NetSlice::Ipv6(ipv6) => {}
}
} }
Ok(()) Ok(())
} }
@ -857,9 +862,7 @@ pub fn get_install_channel() -> String {
fn check_has_resolvectl() -> bool { fn check_has_resolvectl() -> bool {
return false; return false;
let res = Command::new("resolvectl") let res = Command::new("resolvectl").arg("status").output();
.arg("status")
.output();
if let Ok(_) = res { if let Ok(_) = res {
true true
} else { } 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") Command::new("route")
.arg("add") .arg("add")
.arg("-host") .arg("-host")
@ -879,10 +882,7 @@ fn add_dns_route(dev_name: &str) -> Result<()>{
Ok(()) Ok(())
} }
fn add_resolvectl( fn add_resolvectl(name: &str, network_domain: &str) -> Result<()> {
name: &str,
network_domain: &str,
) -> Result<()>{
Command::new("resolvectl") Command::new("resolvectl")
.arg("dns") .arg("dns")
.arg(name) .arg(name)
@ -898,12 +898,7 @@ fn add_resolvectl(
Ok(()) Ok(())
} }
fn set_dns( fn set_dns(iface: &Iface, name: &str, network_domain: &str, gw: &str) -> Result<()> {
iface: &Iface,
name: &str,
network_domain: &str,
gw: &str
) -> Result<()> {
error!("network_domain = {}", network_domain); error!("network_domain = {}", network_domain);
if iface.has_resolvectl { if iface.has_resolvectl {
add_resolvectl(name, network_domain)?; add_resolvectl(name, network_domain)?;
@ -929,10 +924,17 @@ pub fn restore_dns() -> Result<()> {
/// ///
/// - `new_nameservers`: 新的 nameserver 列表IPv4/IPv6 字符串) /// - `new_nameservers`: 新的 nameserver 列表IPv4/IPv6 字符串)
/// - `keep_other_ns`: 是否保留原有的 nameservertrue = 追加到新列表后false = 完全替换) /// - `keep_other_ns`: 是否保留原有的 nameservertrue = 追加到新列表后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); let path = Path::new(RESOLV_FILE);
if !path.exists() { if !path.exists() {
return Err(SDLanError::IOError(format!("{} does not exists", RESOLV_FILE))); return Err(SDLanError::IOError(format!(
"{} does not exists",
RESOLV_FILE
)));
} }
// 读取原文件权限和元数据 // 读取原文件权限和元数据
@ -1020,7 +1022,10 @@ fn backup_resolv_conf() -> Result<()> {
let dst = Path::new(RESOLV_FILE_BACKUP); let dst = Path::new(RESOLV_FILE_BACKUP);
if !src.exists() { 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"); // anyhow::bail!("Source /etc/resolv.conf does not exist");
} }
@ -1054,7 +1059,10 @@ fn restore_resolv_conf() -> Result<()> {
let dst = Path::new(RESOLV_FILE); let dst = Path::new(RESOLV_FILE);
if !src.exists() { 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(()) 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") let res = Command::new("route")
.arg("add") .arg("add")
.arg("-net") .arg("-net")
@ -1152,7 +1160,11 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) {
debug!("got arp response: {:?}", data); debug!("got arp response: {:?}", data);
if data.target_mac.len() != 6 { if data.target_mac.len() != 6 {
// invalid target_mac // 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; return;
} }
@ -1168,7 +1180,11 @@ pub async fn arp_reply_arrived(edge: &Node, data: SdlArpResponse) {
debug!("got arp response: {:?}", data); debug!("got arp response: {:?}", data);
if data.target_mac.len() != 6 { if data.target_mac.len() != 6 {
// invalid target_mac // 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; return;
} }
// TODO: construct the arp reply, and write to tun; // 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); 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) { pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) {
let dst_mac = edge.device_config.get_mac(); let dst_mac = edge.device_config.get_mac();
let dst_ip = edge.device_config.get_ip(); let dst_ip = edge.device_config.get_ip();
let hdr = ArpHdr{ let hdr = ArpHdr {
ethhdr: EthHdr { ethhdr: EthHdr {
dest: dst_mac, dest: dst_mac,
src: src_mac, src: src_mac,
@ -1198,7 +1214,10 @@ pub fn write_arp_to_device(edge: &Node, src_mac: Mac, src_ip: u32) {
shwaddr: src_mac, shwaddr: src_mac,
sipaddr: [((src_ip >> 16) as u16) & 0xffff, (src_ip as u16) & 0xffff], sipaddr: [((src_ip >> 16) as u16) & 0xffff, (src_ip as u16) & 0xffff],
dhwaddr: dst_mac, 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(); let data = hdr.marshal_to_bytes();