sdlan-rs/docs/protocol.md

4.8 KiB
Raw Blame History

sdlan交互协议

sdlan协议的总体格式如下

+-----------+------------+--------+----------+
| 2字节的长度 | 2字节消息id |  消息头 |  消息体   |
+-----------+------------+--------+----------+

1. 长度

2字节长度包含后面的所有字节的长度不包括自身

2. 消息id

用于匹配请求和响应占用2字节目前可以都先填写0

3. 消息头

在sdlan中有一个common头使用二进制协议消息头主要包含了协议版本消息来源id从哪个节点发出的节点标识消息ttl以及一些协议的flagflag标志以后可以扩充

消息头二进制格式如下:

+---------+----+-----+------+-----+
| version | id | ttl | flag | pc  |
+---------+----+-----+------+-----+

其中version占用一个字节用于标识协议版本。id用于唯一标识某个客户端为长度为32字节的uuid之后的ttl占用一个字节当ttl为0则直接丢弃该数据包。后面的flag占用2字节用于标识数据包属性目前拥有的标识如下

  • from_sn: 0x0020,表示这个数据包是从服务端发送过来的。
  • socket: 0x0040表示这个数据包里面包含了有用的socket信息通常在服务端转发的时候有用

最后的pc表示后面数据包的类型目前数据包类型如下

  • 0 —— invalid pkt type,表示无效的数据包类型
  • 1 —— register super,表示客户端像服务端发送的注册请求
  • 2 —— packet表示客户端向服务端或者客户端发送给客户端发送的来自tun的数据包。
  • 3 —— register数据包,表示客户端之间打洞请求消息
  • 4 —— register_ack数据包,表示客户端之间打洞请求消息
  • ... TODO

4. 消息体

消息提根据协议头中的pc不同拥有不同的结构结构体在json化之后添加到消息体的位置。

4.1. RegisterSuper包类型

register superpc为1表示客户端像服务端发送的注册请求该请求每隔15-20秒发送一次RegisterSuper的json结构如下


4.2. Packet数据包

packetpc为2表示客户端向服务端或者客户端发送给客户端发送的来自tun的数据包。packet数据包的json化之后的结构如下

{
    // 来源ip
    "src_ip": $uint32,
    // 目的ip
    "dst_ip": $uint32,
    // sock信息, sock信息包含了来自客户端的信息
    // 通常客户端发送一个packet数据包的时候不需要携带这个信息。
    // 而在服务端收到一个packet的数据包的时候在转发的时候会将客户端的信息放入这个结构然后发送给需要转发的客户端。所以在客户端收到转发的packet数据包的时候可以通过这个sock结构得知发送的客户端的端口信息。在sock结构有用的时候flags中的socket0x0040标识也会被置位。
    "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]
    },
    // data为二进制的字节数组为aes加密之后的tun流量。
    "data": []
}

其中,src_ip为tun的ip数据包的来源ipdst_ip为tun的ip数据包的目的ip。均为大端序的32位无符号整数。sock为转发时由sn填充的发送客户端的信息发送短不需要处理。data为tun的数据流量使用network_pass进行加密后的二进制数据。

在发送packet数据包之前消息体部分的数据为json化之后的packet使用header_pass进行aes加密后的二进制数据。

4.3. Register数据包

registerpc为3客户端向另一个客户端发送打洞请求的数据包。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