register and register ack

This commit is contained in:
asxalex 2024-02-23 14:08:29 +08:00
parent 7e80578038
commit 939a0514db
7 changed files with 91 additions and 6 deletions

View File

@ -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加密后的二进制数据。
在发送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表示ipv410表示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

View File

@ -83,6 +83,8 @@ pub enum PacketType {
PKTPacket,
// 打洞消息
PKTRegister,
// 打洞消息ACK
PKTRegisterACK,
}
impl std::convert::From<u8> for PacketType {
@ -92,6 +94,7 @@ impl std::convert::From<u8> 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,
}
}
}

View File

@ -9,3 +9,6 @@ pub use packet::*;
mod register;
pub use register::*;
mod register_ack;
pub use register_ack::*;

View File

@ -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<SdlanSock>,
pub data: Vec<u8>,
}
@ -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(),
};

View File

@ -9,7 +9,7 @@ pub struct Register {
// 目的ip
pub dst_ip: u32,
// supernode转发时开到的发送者的外网ip信息
pub sock: SdlanSock,
pub sock: Option<SdlanSock>,
// 发送者的tun的ip信息
pub dev_addr: IpSubnet,
}

View File

View File

@ -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<peer::SdlanSock>,
@ -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,