diff --git a/docs/api.md b/docs/api.md index dbc530e..943568e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -36,4 +36,11 @@ sdlan api的所有返回的消息体都遵循如下格式: ``` POST /peer/authorize + +HEADER: Token + +BODY: +{ + +} ``` diff --git a/docs/design.md b/docs/design.md index 1d47e75..91b369f 100644 --- a/docs/design.md +++ b/docs/design.md @@ -14,4 +14,16 @@ graph TD B --- D ``` -服务端1和服务端2通过udp连接,现在分别有个节点连接到对应的服务端, \ No newline at end of file +服务端1和服务端2通过udp连接,现在分别有个节点连接到对应的服务端, + +# sdlan设计 +sdlan首先使用参数初始化自身,然后加入一个多播组,然后循环接收消息。 + +在收到Packet消息时候,一方面检查来源等,将合法的内容写入到tun设备,同时,需要查看对端,在合适的实际向对端进行注册: + +* 首先从`known_peers`查找节点(通过ip,如果找不到,通过sock): + * 如果找到,就看当前注册的时间,如果时间过了,就从`known_peers`里面重新查找该节点,如果是从节点直接p2p过来的,就从`known_peers`删除,重新发送注册(加入到`pending_peers`,然后发送register)` + * 如果没找到,就直接注册(加入到`pending_peers`, 然后发送register)。 + +在重新注册过程中,如果消息来自sn转发,就通过配置的`register_ttl`,判断需不需要端口猜测,发送register给对端和sn. + diff --git a/docs/interactive.md b/docs/interactive.md index e829467..a4cea45 100644 --- a/docs/interactive.md +++ b/docs/interactive.md @@ -18,4 +18,4 @@ sdlan节点上线流程如下: 当一个节点上次用某个用户的token登录之后,然后下次使用同一个用户的另外的token登录,是否允许?(应该允许) -当一个节点上次用某个用户的token登录之后,下次使用另一个用户的token登录,是否允许? \ No newline at end of file +当一个节点上次用某个用户的token登录之后,下次使用另一个用户的token登录,是否允许?(是否应该之前的用户解除这个设备的绑定关系之后,才能被其他用户添加这个节点) \ No newline at end of file diff --git a/src/peer.rs b/src/peer.rs index 4676c89..14b3e12 100644 --- a/src/peer.rs +++ b/src/peer.rs @@ -142,6 +142,22 @@ impl IpSubnet { } } +pub fn is_sdlan_sock_equal(s1: &SdlanSock, s2: &SdlanSock) -> bool { + if s1.family != s2.family { + return false; + } + if s1.port != s2.port { + return false; + } + if s1.family == AF_INET { + return s1.v4 == s2.v4; + } else if s1.family == AF_INET6 { + return s1.v6 == s2.v6; + } + + false +} + /// SdlanSock: 对端对外的ip信息,包括ipv4和ipv6 #[derive(Debug, Serialize, Deserialize, PartialEq, sqlx::FromRow)] pub struct SdlanSock { @@ -166,13 +182,30 @@ impl SdlanSock { v6: self.v6, } } + + pub fn to_string(&self) -> String { + if self.family == AF_INET6 { + format!( + "[{:02x}{:x}:{:02x}{:x}:{:02x}{:x}:{:02x}{:x}:{:02x}{:x}:{:02x}{:x}:{:02x}{:x}:{:02x}{:x}]:{}", + self.v6[0], self.v6[1], self.v6[2], self.v6[3], + self.v6[4], self.v6[5], self.v6[6], self.v6[7], + self.v6[8], self.v6[9],self.v6[10], self.v6[11], + self.v6[12], self.v6[13], self.v6[14], self.v6[15], + self.port + ) + } else { + format!( + "{}.{}.{}.{}:{}", + self.v4[0], self.v4[1], self.v4[2], self.v4[3], self.port + ) + } + } } #[derive(Debug, Serialize, Deserialize, PartialEq, sqlx::FromRow)] pub struct V6Info { pub port: u16, - #[sqlx(try_from = "Vec")] pub v6: [u8; 16], } @@ -195,6 +228,7 @@ use std::borrow::Cow; use std::sync::Arc; use crate::config::AF_INET; +use crate::config::AF_INET6; use crate::utils::SDLanError; use std::pin::Pin; pub struct PeerMap { diff --git a/src/utils/myrsa.rs b/src/utils/myrsa.rs index c4352a2..c5735dd 100644 --- a/src/utils/myrsa.rs +++ b/src/utils/myrsa.rs @@ -6,21 +6,34 @@ use rsa::pkcs8::DecodePublicKey; use rsa::pkcs8::EncodePublicKey; use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey}; +use std::fs::File; use std::io::Read; +use std::path::Path; + +pub fn gen_rsa_keys(mut dirpath: &str) { + if dirpath.len() == 0 { + dirpath = ".data"; + } + dirpath = dirpath.trim_end_matches("/"); + + let pub_file = format!("{}/id_rsa.pub", dirpath); + if let Ok(_) = File::open(&pub_file) { + // file exists, just return + return; + } -pub fn gen_rsa_keys() { let mut rng = rand::thread_rng(); let bits = 2048; let priv_key = RsaPrivateKey::new(&mut rng, bits).unwrap(); let public_key = RsaPublicKey::from(&priv_key); - std::fs::create_dir_all(".data").expect("failed to create .data"); + std::fs::create_dir_all(dirpath).expect("failed to create .data"); priv_key - .write_pkcs1_pem_file(".data/id_rsa", rsa::pkcs8::LineEnding::LF) + .write_pkcs1_pem_file(format!("{}/id_rsa", dirpath), rsa::pkcs8::LineEnding::LF) .unwrap(); public_key - .write_public_key_pem_file(".data/id_rsa.pub", rsa::pkcs8::LineEnding::LF) + .write_public_key_pem_file(&pub_file, rsa::pkcs8::LineEnding::LF) .unwrap(); } @@ -102,7 +115,7 @@ mod tests { if std::fs::File::open(".data/id_rsa").is_ok() { return; } - gen_rsa_keys(); + gen_rsa_keys(""); } #[test]