From fad345becbc08da78e27575d797ccdffd87db6c2 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 23 Dec 2025 10:30:33 +0800 Subject: [PATCH] 15353's parse is ok, should restore /etc/resolv.conf while exitting --- src/bin/punchnet/main.rs | 20 ++++++++++++++++- src/lib.rs | 8 +++++++ src/network/async_main.rs | 31 ++++++++++++++++++++++++++ src/network/device.rs | 4 ++++ src/network/node.rs | 14 ++++++++++++ src/network/tun_linux.rs | 46 +++++++++++++++++++++++++++++++++------ 6 files changed, 115 insertions(+), 8 deletions(-) diff --git a/src/bin/punchnet/main.rs b/src/bin/punchnet/main.rs index cbadb8b..a0b1a50 100755 --- a/src/bin/punchnet/main.rs +++ b/src/bin/punchnet/main.rs @@ -10,6 +10,7 @@ use sdlan_sn_rs::log; use sdlan_sn_rs::utils::gen_uuid_u64; use tracing::error; +use std::net::ToSocketAddrs; use std::time::Duration; use structopt::StructOpt; @@ -31,7 +32,23 @@ async fn main() { // println!("port is {}", cmd.port); let (tx, rx) = std::sync::mpsc::channel(); - let server = "punchnet.aioe.tech".to_owned(); + + let hostname = "punchnet.aioe.tech".to_owned(); + let host = format!("{}:80", hostname); + let mut server = String::new(); + if let Ok(addrs) = host.to_socket_addrs() { + for addr in addrs { + let h = addr.to_string().split(":").take(1).collect::>()[0].to_owned(); + server = h + } + } + if server.is_empty() { + println!("failed to resolv host ip"); + return; + } + + println!("server is {}", server); + let _ = run_sdlan( CommandLine { sn: server.clone()+":1265", @@ -51,6 +68,7 @@ async fn main() { }, tx, &punchnet::get_install_channel(), + server, Some(format!("{:08x}", gen_uuid_u64() as u32)), None, ) diff --git a/src/lib.rs b/src/lib.rs index d73b64e..ff89854 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ mod pb; mod tcp; mod utils; +use std::sync::Arc; use std::{sync::atomic::AtomicU8, time::Duration}; use std::net::{SocketAddr, ToSocketAddrs}; @@ -12,6 +13,7 @@ pub use network::get_edge; pub use network::get_install_channel; use network::{async_main, init_arp, init_edge, NodeConfig}; use serde::{Deserialize, Serialize}; +use tokio::net::UdpSocket; use tokio::sync::mpsc::{channel, Sender}; use tokio_util::sync::CancellationToken; use tracing::{debug, error}; @@ -44,6 +46,8 @@ pub async fn run_sdlan( sender: std::sync::mpsc::Sender, install_channel: &str, + server_ip: String, + hostname: Option, connecting_chan: Option>, // start_stop_sender: Sender, // start_stop_receiver: Receiver, @@ -56,6 +60,8 @@ pub async fn run_sdlan( let hostname = hostname.unwrap_or("".to_owned()); + let sock = Arc::new(UdpSocket::bind("0.0.0.0:0").await?); + if let Err(e) = init_edge( &args.token, &args.network_code, @@ -64,7 +70,9 @@ pub async fn run_sdlan( start_stop_sender, args.mtu, connecting_chan.clone(), + sock, hostname, + server_ip, ) .await { diff --git a/src/network/async_main.rs b/src/network/async_main.rs index 331d94a..79237e5 100755 --- a/src/network/async_main.rs +++ b/src/network/async_main.rs @@ -20,6 +20,7 @@ use sdlan_sn_rs::peer::{SdlanSock, V6Info}; use sdlan_sn_rs::utils::{get_current_timestamp, ip_to_string, is_multi_broadcast, rsa_decrypt}; use sdlan_sn_rs::utils::{Mac, Result}; use tokio::io::AsyncWriteExt; +use tokio::net::UdpSocket; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio_util::sync::CancellationToken; @@ -537,6 +538,19 @@ pub async fn loop_socket_v4( debug!("loop_socket_v4 exited"); } +async fn receive_dns_reply(sock: &Arc) -> Option> { + let mut reply = vec![0;1024]; + if let Ok((size, _from)) = sock.recv_from(&mut reply).await { + if size == 0 { + // closed + return None; + } + reply.truncate(size); + return Some(reply); + } + None +} + async fn loop_tap(eee: &'static Node, cancel: CancellationToken) { debug!("loop tap"); let (tx, mut rx) = channel(10); @@ -550,6 +564,23 @@ async fn loop_tap(eee: &'static Node, cancel: CancellationToken) { drop(rx); break; } + reply = receive_dns_reply(&eee.udp_sock_for_dns) => { + if reply.is_none() { + drop(rx); + break; + } + let reply = reply.unwrap(); + let dstmac = eee.device_config.get_mac(); + let srcmac = eee.device_config.dns_mac; + let mut packet = Vec::with_capacity(14+reply.len()); + packet.extend_from_slice(&dstmac); + packet.extend_from_slice(&srcmac); + packet.push(0x08); + packet.push(0x00); + packet.extend_from_slice(&reply); + eee.device.handle_packet_from_net(&packet, &Vec::new()).await; + println!("got 15353's reply"); + } buf = rx.recv() => { if buf.is_none() { break; diff --git a/src/network/device.rs b/src/network/device.rs index a388639..3717111 100755 --- a/src/network/device.rs +++ b/src/network/device.rs @@ -10,17 +10,21 @@ pub struct DeviceConfig { pub mtu: u32, pub mac: RwLock, pub ip: IpSubnet, + + pub dns_mac: Mac, } impl DeviceConfig { pub fn new(mtu: u32) -> Self { let mac = generate_mac_address(); + let dns_mac = generate_mac_address(); println!("self mac: {}", mac_to_string(&mac)); debug!("self mac: {}", mac_to_string(&mac)); DeviceConfig { mtu, mac: RwLock::new(mac), ip: IpSubnet::new(0, 0), + dns_mac, } } diff --git a/src/network/node.rs b/src/network/node.rs index 7f4430a..8b193d0 100755 --- a/src/network/node.rs +++ b/src/network/node.rs @@ -1,6 +1,7 @@ use dashmap::DashMap; use rsa::RsaPrivateKey; use sdlan_sn_rs::config::{AF_INET, AF_INET6}; +use tokio::net::UdpSocket; use std::net::SocketAddr; use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, AtomicU8, Ordering}; use std::sync::{Arc, Mutex, RwLock}; @@ -38,7 +39,9 @@ pub async fn init_edge( start_stop: Sender, mtu: u32, connecting_chan: Option>, + udpsock_for_dns: Arc, hostname: String, + server_ip: String, ) -> Result<()> { // gen public key let rsa_path = format!("{}/.client", get_base_dir()); @@ -83,6 +86,8 @@ pub async fn init_edge( mtu, connecting_chan, hostname, + udpsock_for_dns, + server_ip, ); do_init_edge(edge)?; @@ -123,6 +128,9 @@ pub struct Node { pub hostname: String, + pub udp_sock_for_dns: Arc, + pub server_ip: String, + pub tcp_pong: Arc, start_stop_sender: Sender, @@ -266,6 +274,8 @@ impl Node { mtu: u32, connecting_chan: Option>, hostname: String, + udpsock_for_dns: Arc, + server_ip: String, ) -> Self { let mode = if cfg!(not(feature = "tun")) { Mode::Tap @@ -277,6 +287,9 @@ impl Node { packet_id: AtomicU32::new(1), network_id: AtomicU32::new(0), hostname, + + udp_sock_for_dns: udpsock_for_dns, + _token: Mutex::new(token.to_owned()), network_code: Mutex::new(network_code.to_owned()), @@ -322,6 +335,7 @@ impl Node { packet_id_match: DashMap::new(), nat_cookie: AtomicU32::new(1), cookie_match: DashMap::new(), + server_ip, } } diff --git a/src/network/tun_linux.rs b/src/network/tun_linux.rs index ffe5db3..327e6f2 100755 --- a/src/network/tun_linux.rs +++ b/src/network/tun_linux.rs @@ -25,6 +25,8 @@ use crate::tcp::PacketType; use super::device::{DeviceConfig, Mode}; use super::TunTapPacketHandler; +const DNS_IP: u32 = (100<<24) + (100<<16) + (100<<8) + 100; + // #[link(name = "tuntap", kind="static")] #[link(name = "tuntap")] extern "C" { @@ -186,11 +188,39 @@ impl TunTapPacketHandler for Iface { data: Vec, encrypt_key: &[u8], ) -> std::io::Result<()> { + use etherparse::PacketHeaders; + debug!("in tap mode2"); let edge = get_edge(); - match Ethernet2Header::from_slice(&data) { - Ok((hdr, _)) => { + let Ok(headers) = PacketHeaders::from_ethernet_slice(&data) else { + error!("failed to parse packet"); + return Ok(()); + }; + + if let Some(eth) = headers.link { + if let Some(hdr) = eth.ethernet2() { + if let Some(ip) = headers.net { + match ip { + etherparse::NetHeaders::Ipv4(ipv4, _) => { + println!("3, target = {}.{}.{}.{}", ipv4.destination[0], ipv4.destination[1], ipv4.destination[2], ipv4.destination[3]); + if u32::from_be_bytes(ipv4.destination) == DNS_IP { + // should send to dns + println!("got dns request"); + if let Err(e) = edge.udp_sock_for_dns.send_to(&data[14..], format!("{}:15353", edge.server_ip)).await { + println!("failed to send request to 15353: {}", e); + } + // edge.udp_sock_for_dns.send_to() + return Ok(()) + } + } + _other => { + // just ignore + } + } + + } + let target = hdr.destination; if is_ipv6_multicast(&target) { return Ok(()); @@ -212,11 +242,13 @@ impl TunTapPacketHandler for Iface { let msg = encode_to_udp_message(Some(data), PacketType::Data as u8).unwrap(); send_packet_to_net(edge, target, &msg, size as u64).await; + } else { + println!("erro 2"); } - Err(_) => { - error!("failed to parse packet from device"); - } - }; + } else { + println!("erro 1"); + } + Ok(()) } } @@ -365,7 +397,7 @@ impl TunTapPacketHandler for Iface { } } Err(e) => { - error!("failed to parse tap packet: {}", e); + error!("failed to parse tun packet: {}", e); return Ok(()); } }