diff --git a/Cargo.toml b/Cargo.toml index 7166e61..6c3ffe5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ aes = "0.8.4" byteorder = "1.5.0" cbc = "0.1.2" dashmap = "5.5.3" +futures = "0.3.30" # lazy_static = "1.4.0" once_cell = "1.19.0" rand = "0.8.5" diff --git a/docs/protocol.md b/docs/protocol.md index d6a1b60..e1af4ab 100644 --- a/docs/protocol.md +++ b/docs/protocol.md @@ -173,6 +173,11 @@ sdlan协议的总体格式如下: // 如果family为10,则v6有用,一个16字节的数组,表示ipv6地址 "v6": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] }, + // 如果没有ipv6,则不用填写 + "v6_info": { + "port": $uint16, + "v6": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] + } } ``` diff --git a/src/packet/query_peer.rs b/src/packet/query_peer.rs index 23db42a..447eff8 100644 --- a/src/packet/query_peer.rs +++ b/src/packet/query_peer.rs @@ -4,8 +4,6 @@ use crate::peer::SdlanSock; #[derive(Serialize, Deserialize)] pub struct QueryPeer { - // query peer some flag. - pub flag: u16, // 询问人的ip pub src_ip: u32, // 询问对方的ip diff --git a/src/packet/register.rs b/src/packet/register.rs index 5eef7d1..314932f 100644 --- a/src/packet/register.rs +++ b/src/packet/register.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -use crate::peer::SdlanSock; +use crate::peer::{SdlanSock, V6Info}; #[derive(Serialize, Deserialize)] pub struct Register { @@ -11,6 +11,9 @@ pub struct Register { pub dst_ip: u32, // supernode转发时开到的发送者的外网ip信息 pub sock: Option, + + // ipv6 信息 + pub has_v6: Option, // 发送者的tun的ip信息 // pub dev_addr: IpSubnet, } diff --git a/src/packet/register_super.rs b/src/packet/register_super.rs index cab0bd4..7979ea9 100644 --- a/src/packet/register_super.rs +++ b/src/packet/register_super.rs @@ -2,7 +2,7 @@ use crate::peer::{self, V6Info}; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Debug)] pub struct RegisterSuper<'a> { // pass, 用于给registersuper一个初步的雁阵,固定8位 pub pass: &'a str, @@ -19,7 +19,7 @@ pub struct RegisterSuper<'a> { pub dev_addr: peer::IpSubnetNonAtomic, // 自身的公钥 - pub pub_key: &'a str, + pub pub_key: String, // user's token, can be used to specify a user pub token: &'a str, @@ -73,7 +73,7 @@ mod test { net_addr: 192, net_bit_len: 24, }, - pub_key: "public key", + pub_key: "public key".to_string(), token: "user's token", }; let res = serde_json::to_string(&pkt1).unwrap(); @@ -110,7 +110,7 @@ mod test { net_addr: 192, net_bit_len: 24, }, - pub_key: "public key", + pub_key: "public key".to_string(), token: "user's token", }; (cmn1, pkt1) diff --git a/src/peer.rs b/src/peer.rs index 851fe4d..7ac1935 100644 --- a/src/peer.rs +++ b/src/peer.rs @@ -1,6 +1,7 @@ #![allow(unused)] use super::utils::Result; use dashmap::DashMap; +use futures::future::BoxFuture; use serde::{Deserialize, Serialize}; use sqlx::prelude::FromRow; use std::default::Default; @@ -13,6 +14,7 @@ pub struct Peer { // pub id: Mutex, // 对端阶段的udp信息,包括ipv4地址和子网掩码位数 pub dev_addr: IpSubnet, + // 对端对外开放的ip和端口信息 pub sock: RwLock, // peer's local v6 info @@ -192,6 +194,7 @@ use std::sync::Arc; use crate::config::AF_INET; use crate::utils::SDLanError; +use std::pin::Pin; pub struct PeerMap { pub peers: DashMap>, // ip to peer's uuid, the ip is the logical ip @@ -225,14 +228,16 @@ impl PeerMap { } // pub fn peer_match) -> bool>( - pub fn peer_match(&self, id: &str, f: F) -> Option<(String, Arc)> + pub async fn peer_match(&self, cmp: &str, f: F) -> Option<(String, Arc)> where - F: Fn(&Arc) -> bool, + // F: for<'a> Fn(&'a str, &'a Arc) -> BoxFuture<'a, bool>, + F: for<'c> Fn(&'c str, &'c Arc) -> Pin + 'c>>, { - if let Some(v) = self.peers.get(id) { - if f(&*v) { + for v in self.peers.iter() { + if f(cmp, v.value()).await { return Some((v.key().to_owned(), v.clone())); } + return Some((v.key().to_owned(), v.clone())); } None } @@ -263,6 +268,7 @@ impl PeerMap { mod test { use crate::config::AF_INET; use crate::utils::gen_uuid; + use futures::future::FutureExt; use super::*; @@ -303,4 +309,20 @@ mod test { panic!("failed to get peer with sock"); } } + + async fn test_fn() { + use crate::utils::gen_uuid; + use futures::future::FutureExt; + let id = gen_uuid(); + + let pm = PeerMap::new(); + let m = 10u32; + let res = pm + .peer_match(&id, |uid, info| { + async { info.dev_addr.net_addr() == uid.len() as u32 }.boxed() + }) + .await; + + println!("res = {:?}", res); + } } diff --git a/src/utils/error.rs b/src/utils/error.rs index 9ce47d9..9224fb6 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -1,4 +1,4 @@ -use std::convert::From; +use std::{convert::From, net::AddrParseError, string::ParseError}; pub type Result = std::result::Result; @@ -35,3 +35,15 @@ impl From for SDLanError { Self::DBError(value.to_string()) } } + +impl From for SDLanError { + fn from(value: ParseError) -> Self { + Self::ConvertError(value.to_string()) + } +} + +impl From for SDLanError { + fn from(value: AddrParseError) -> Self { + Self::ConvertError(value.to_string()) + } +} diff --git a/src/utils/helper.rs b/src/utils/helper.rs index 00f1685..913b53c 100644 --- a/src/utils/helper.rs +++ b/src/utils/helper.rs @@ -18,8 +18,8 @@ impl MyDashMap { None } - pub fn insert(&self, key: String, value: T) -> Option> { - self.0.insert(key, Arc::new(value)) + pub fn insert(&self, key: String, value: Arc) -> Option> { + self.0.insert(key, value) } pub fn remove(&self, key: &str) -> Option<(String, Arc)> { @@ -45,8 +45,11 @@ use super::{gen_uuid, Result}; use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; -pub fn create_or_load_uuid() -> Result { - let filepath = Path::new("./.id"); +pub fn create_or_load_uuid(mut idfile: &str) -> Result { + if idfile.len() == 0 { + idfile = "./.id"; + } + let filepath = Path::new(idfile); if filepath.exists() { let mut result = String::new(); File::open(filepath)?.read_to_string(&mut result)?;