From 50db315c799484d36062a4f623b87704e5b69388 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 10 Mar 2026 15:13:38 +0800 Subject: [PATCH] no identity id is checked --- src/bin/punchnet/main.rs | 23 +++++++++++++-- src/network/packet.rs | 61 +++++++++++++++++++++++++-------------- src/tcp/identity_cache.rs | 46 ++++++++++++++++++++--------- 3 files changed, 94 insertions(+), 36 deletions(-) diff --git a/src/bin/punchnet/main.rs b/src/bin/punchnet/main.rs index ab19a50..c99f4db 100755 --- a/src/bin/punchnet/main.rs +++ b/src/bin/punchnet/main.rs @@ -1,9 +1,11 @@ mod api; use std::fs::File; +use std::fs::OpenOptions; use std::process; use std::env; +use std::time::Duration; use clap::Parser; use daemonize::Daemonize; use punchnet::CachedLoginInfo; @@ -28,6 +30,7 @@ use sdlan_sn_rs::utils::Result; use sdlan_sn_rs::utils::create_or_load_uuid; use tokio::io::AsyncWriteExt; use tokio::io::stdout; +use tokio::time::sleep; use tracing::error; use std::net::ToSocketAddrs; @@ -336,18 +339,34 @@ async fn main() { if should_daemonize { + let stdout = OpenOptions::new() + .create(true) + .append(true) + .write(true) + .open("/tmp/punchnet.out").unwrap(); + let stderr = OpenOptions::new() + .create(true) + .append(true) + .write(true) + .open("/tmp/punchnet.err").unwrap(); + let daemonize = Daemonize::new() .pid_file("/tmp/punchnet.pid") .chown_pid_file(true) .working_directory(get_base_dir()) - .stdout(File::create("/tmp/punchnet.out").unwrap()) - .stderr(File::create("/tmp/punchnet.err").unwrap()) + .stdout(stdout) + .stderr(stderr) .privileged_action(|| { }); match daemonize.start() { Ok(_) => { + loop { + println!("guard is {:?}", _guard); + sleep(Duration::from_secs(3)).await; + } daemonize_me(connect_info, remembered, client_id, mac).await; + } Err(e) => { eprintln!("failed to daemonize: {}", e); diff --git a/src/network/packet.rs b/src/network/packet.rs index 6ea1aba..a0cb614 100755 --- a/src/network/packet.rs +++ b/src/network/packet.rs @@ -1,5 +1,6 @@ use std::{net::SocketAddr, sync::atomic::Ordering, time::Duration}; +use crate::network::IdentityID; use crate::pb::SdlPolicyRequest; use crate::tcp::{NatType, get_quic_write_conn, is_identity_ok}; use crate::{network::TunTapPacketHandler, utils::mac_to_string}; @@ -820,8 +821,39 @@ pub fn print_hex(key: &[u8]) { println!("[{}]", value.join(" ")) } +async fn renew_identity_request(eee: &Node, identity: u32) { + let policy_request = SdlPolicyRequest { + pkt_id: eee.get_next_packet_id(), + src_identity_id: identity, + dst_identity_id: eee.identity_id.load(), + version: 1, + }; + + 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 stream = get_quic_write_conn(); + if let Err(e) = stream.send(data).await { + error!("failed to write to quic: {}", e.as_str()); + } +} + async fn check_identity_is_ok(eee: &Node, identity: u32, protocol: u8, port: u16) -> bool{ - match is_identity_ok(identity, protocol, port) { + true +} + +async fn check_identity_is_ok2(eee: &Node, identity: u32, protocol: u8, port: u16) -> bool{ + let result = is_identity_ok(identity, protocol, port); + if result.1 { + renew_identity_request(eee, identity).await; + } + match result.0 { Some(true) => { // identity is ok true @@ -832,26 +864,10 @@ async fn check_identity_is_ok(eee: &Node, identity: u32, protocol: u8, port: u16 false } None => { - - let policy_request = SdlPolicyRequest { - pkt_id: eee.get_next_packet_id(), - src_identity_id: identity, - dst_identity_id: eee.identity_id.load(), - version: 1, - }; - - 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 stream = get_quic_write_conn(); - if let Err(e) = stream.send(data).await { - error!("failed to write to quic: {}", e.as_str()); + if !result.1 { + renew_identity_request(eee, identity).await; + } else { + // has been sent } false // no such identity, should request for it @@ -896,6 +912,8 @@ async fn handle_tun_packet( ip_number::TCP => { let tcp_header = headers.transport.unwrap().tcp().unwrap(); let port = tcp_header.destination_port; + let src_port = tcp_header.source_port; + println!("tcp srcport={}, dstport={}", src_port, port); if !check_identity_is_ok(eee, pkt.identity_id, protocol.0, port).await { return; } @@ -921,6 +939,7 @@ async fn handle_tun_packet( + debug!("sending packet to tun, {} bytes", data.len()); if let Err(e) = eee .device .handle_packet_from_net(&data, key.as_slice()) diff --git a/src/tcp/identity_cache.rs b/src/tcp/identity_cache.rs index 8392f38..c08997f 100644 --- a/src/tcp/identity_cache.rs +++ b/src/tcp/identity_cache.rs @@ -1,6 +1,6 @@ -use std::{collections::HashMap, sync::OnceLock}; +use std::{collections::{HashMap, HashSet}, sync::{OnceLock, atomic::{AtomicU64, Ordering}}, time::{SystemTime, UNIX_EPOCH}}; -use dashmap::DashMap; +use dashmap::{DashMap, DashSet}; use tracing::debug; type IdentityID = u32; @@ -13,8 +13,9 @@ pub struct RuleInfo { pub port: Port, } +static RULE_CACHE: OnceLock>)>> = OnceLock::new(); -static RULE_CACHE: OnceLock>>> = OnceLock::new(); +// static RULE_CACHE: OnceLock>>> = OnceLock::new(); pub fn init_identity_cache() { RULE_CACHE.set(DashMap::new()).unwrap(); @@ -25,30 +26,49 @@ pub fn set_identity_cache(identity: IdentityID, infos: Vec) { let cache = RULE_CACHE.get().expect("should set first"); let mut temp = HashMap::new(); + + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + for info in &infos { - let mut protomap = HashMap::new(); - protomap.insert(info.proto, true); + let mut protomap = HashSet::new(); + protomap.insert(info.proto); temp.insert(info.port, protomap); } cache.remove(&identity); - cache.insert(identity, temp); + cache.insert(identity, (now, temp)); } -pub fn is_identity_ok(identity: IdentityID, proto: Proto, port: Port) -> Option { +// result.1 is should renew +pub fn is_identity_ok(identity: IdentityID, proto: Proto, port: Port) -> (Option, bool) { let cache = RULE_CACHE.get().expect("should set first"); + let mut should_renew = false; + let result: Option; match cache.get(&identity) { Some(data) => { - if let Some(proto_info) = data.get(&port) { - if let Some(_has) = proto_info.get(&proto) { - return Some(true); - } + let tm = data.0; + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + if tm + 10 < now { + should_renew = true; + } + + if let Some(proto_info) = data.1.get(&port) { + if let Some(_has) = proto_info.get(&proto) { + result = Some(true); + // return Some(true); + } else { + result = Some(false); + } + } else { + result = Some(false); + } - Some(false) } None => { - None + result = None; } } + return (result, should_renew); + }