From 939a0514db3c727f7c7e2ccf1606ba95677460f5 Mon Sep 17 00:00:00 2001 From: asxalex Date: Fri, 23 Feb 2024 14:08:29 +0800 Subject: [PATCH] register and register ack --- docs/protocol.md | 43 ++++++++++++++++++++++++++++++++++-- src/packet/common.rs | 4 ++++ src/packet/mod.rs | 3 +++ src/packet/packet.rs | 6 ++--- src/packet/register.rs | 2 +- src/packet/register_ack.rs | 0 src/packet/register_super.rs | 39 ++++++++++++++++++++++++++++++++ 7 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 src/packet/register_ack.rs diff --git a/docs/protocol.md b/docs/protocol.md index b1295dd..6c381e7 100644 --- a/docs/protocol.md +++ b/docs/protocol.md @@ -34,13 +34,19 @@ sdlan协议的总体格式如下: * `0` —— `invalid pkt type`,表示无效的数据包类型 * `1` —— `register super`,表示客户端像服务端发送的注册请求 * `2` —— `packet`,表示客户端向服务端(或者客户端发送给客户端)发送的来自tun的数据包。 +* `3` —— `register`数据包,表示客户端之间打洞请求消息 +* `4` —— `register_ack`数据包,表示客户端之间打洞请求消息 * ... TODO ## 4. 消息体 消息提根据协议头中的pc不同,拥有不同的结构,结构体在json化之后,添加到消息体的位置。 ### 4.1. RegisterSuper包类型 -`register super`,pc为1,表示客户端像服务端发送的注册请求,该请求每隔15-20秒发送一次 +`register super`,pc为1,表示客户端像服务端发送的注册请求,该请求每隔15-20秒发送一次,RegisterSuper的json结构如下: + +```json + +``` ### 4.2. Packet数据包 `packet`,pc为2,表示客户端向服务端(或者客户端发送给客户端)发送的来自tun的数据包。packet数据包的json化之后的结构如下: @@ -71,4 +77,37 @@ sdlan协议的总体格式如下: 其中,`src_ip`为tun的ip数据包的来源ip,`dst_ip`为tun的ip数据包的目的ip。均为大端序的32位无符号整数。`sock`为转发时由sn填充的发送客户端的信息,发送短不需要处理。`data`为tun的数据流量,使用`network_pass`进行加密后的二进制数据。 -在发送packet数据包之前,消息体部分的数据,为json化之后的packet使用`header_pass`进行aes加密后的二进制数据。 \ No newline at end of file +在发送packet数据包之前,消息体部分的数据,为json化之后的packet使用`header_pass`进行aes加密后的二进制数据。 + +### 4.3. Register数据包 +`register`,pc为3,客户端向另一个客户端发送打洞请求的数据包。json格式如下: + +```json +{ + // 源ip + "src_ip": $uint32, + // 目的ip + "dst_ip": $uint32, + // supernode转发时开到的发送者的外网ip信息 + "sock": { + // family表示客户端的ip协议版本,2表示ipv4,10表示ipv6 + "family": 2|10, + // 客户端开放的端口, u16 + "port": $uint16, + // 如果family为2,则v4有用,一个四字节的数组,表示ipv4 + "v4": [1,2,3,4], + // 如果family为10,则v6有用,一个16字节的数组,表示ipv6地址 + "v6": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] + }, + // 发送者的tun的ip信息 + "dev_addr": { + // tun设备的ip,大端序的32位无符号 + "net_addr": $uint32, + // 子网掩码1的位数,一般为24 + "net_bit_len": $uint8, + }, +} +``` + +### 4.4. RegisterACK数据包 +pc为4 \ No newline at end of file diff --git a/src/packet/common.rs b/src/packet/common.rs index 818cb7a..f7cb879 100644 --- a/src/packet/common.rs +++ b/src/packet/common.rs @@ -83,6 +83,8 @@ pub enum PacketType { PKTPacket, // 打洞消息 PKTRegister, + // 打洞消息ACK + PKTRegisterACK, } impl std::convert::From for PacketType { @@ -92,6 +94,7 @@ impl std::convert::From for PacketType { 1 => Self::PKTRegisterSuper, 2 => Self::PKTPacket, 3 => Self::PKTRegister, + 4 => Self::PKTRegisterACK, _ => Self::PKTInvalid, } } @@ -104,6 +107,7 @@ impl PacketType { Self::PKTRegisterSuper => 1, Self::PKTPacket => 2, Self::PKTRegister => 3, + Self::PKTRegisterACK => 4, } } } diff --git a/src/packet/mod.rs b/src/packet/mod.rs index 0bc9909..f935454 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -9,3 +9,6 @@ pub use packet::*; mod register; pub use register::*; + +mod register_ack; +pub use register_ack::*; diff --git a/src/packet/packet.rs b/src/packet/packet.rs index 63b96fa..0e0166a 100644 --- a/src/packet/packet.rs +++ b/src/packet/packet.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; pub struct Packet { pub src_ip: u32, pub dst_ip: u32, - pub sock: SdlanSock, + pub sock: Option, pub data: Vec, } @@ -23,12 +23,12 @@ mod test { let packet = Packet { src_ip: 1, dst_ip: 2, - sock: SdlanSock { + sock: Some(SdlanSock { family: AF_INET, port: 80, v4: [1; 4], v6: [1; 16], - }, + }), data: data.into_bytes(), }; diff --git a/src/packet/register.rs b/src/packet/register.rs index b1e837e..b77304c 100644 --- a/src/packet/register.rs +++ b/src/packet/register.rs @@ -9,7 +9,7 @@ pub struct Register { // 目的ip pub dst_ip: u32, // supernode转发时开到的发送者的外网ip信息 - pub sock: SdlanSock, + pub sock: Option, // 发送者的tun的ip信息 pub dev_addr: IpSubnet, } diff --git a/src/packet/register_ack.rs b/src/packet/register_ack.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/packet/register_super.rs b/src/packet/register_super.rs index 58771a1..52d468a 100644 --- a/src/packet/register_super.rs +++ b/src/packet/register_super.rs @@ -6,6 +6,10 @@ use serde::{Deserialize, Serialize}; pub struct RegisterSuper<'a> { // pass, 用于给registersuper一个初步的雁阵,固定8位 pub pass: &'a str, + + // used to match register_super, register_super_ack, + // register_super_nak, register_super_acknowledge + pub cookie: u32, // 自身的sock信息 pub sock: Option, @@ -37,6 +41,40 @@ mod test { use super::*; + #[derive(Serialize, Deserialize, Debug)] + struct RegisterSuperWithoutNone<'a> { + // pass, 用于给registersuper一个初步的雁阵,固定8位 + pub pass: &'a str, + // 自身的sock信息 + pub sock: peer::SdlanSock, + + // 自身的ip信息 + pub dev_addr: peer::IpSubnet, + + // 自身的公钥 + pub pub_key: &'a str, + + // user's token, can be used to specify a user + pub token: &'a str, + } + + #[test] + #[should_panic] + fn test_without_none() { + let pkt1 = RegisterSuper { + pass: "encrypt!", + cookie: 0, + sock: None, + dev_addr: peer::IpSubnet::new(192, 24), + pub_key: "public key", + token: "user's token", + }; + let res = serde_json::to_string(&pkt1).unwrap(); + println!("unmarshaled as {}", res); + let pkt2: RegisterSuperWithoutNone = serde_json::from_slice(res.as_bytes()).unwrap(); + println!("got pkt2: {:?}", pkt2); + } + fn prepare_data() -> (Common<'static>, RegisterSuper<'static>) { let cmn1 = Common { version: 1, @@ -47,6 +85,7 @@ mod test { }; let pkt1 = RegisterSuper { pass: "encrypt!", + cookie: 0, sock: Some(SdlanSock { family: AF_INET, port: 1,