You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
5.0 KiB

# Mux.Cool 协议
Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。
## 版本
当前版本是 1 Beta。
## 依赖
### 底层协议
Mux.Cool 必须运行在一个已建立的可靠数据流之上。
## 通讯过程
一个 Mux.Cool 连接中可传输若干个子连接,每个子连接有一个独立的 ID 和状态。传输过程由帧Frame组成每一帧用于传输一个特定的子连接的数据。
### 客户端行为
当有连接需求时并且没有现有可用的连接时,客户端向服务器发起一个新连接,以下称为“主连接”。
1. 一个主连接可用于发送若干个子连接。客户端可自主决定主连接可承载的子连接数量。
1. 对于一个新的子连接,客户端必须发送状态`New`以通知服务器建立子连接,然后使用状态`Keep`来传送数据。
1. 当子连接结束时,客户端发送`End`状态来通知服务器关闭子连接。
1. 客户端可自行决定何时关闭主连接,但必须确定服务器也同时保持连接。
1. 客户端可使用 KeepAlive 状态来避免服务器关闭主连接。
### 服务器端行为
当服务器端接收到新的子连接时,服务器应当按正常的连接来处理。
1. 当收到状态`End`时,服务器端可以关闭对目标地址的上行连接。
1. 在服务器的响应中,必须使用与请求相同的 ID 来传输子连接的数据。
1. 服务器不能使用`New`状态。
1. 服务器可使用 KeepAlive 状态来避免客户端关闭主连接。
## 传输格式
Mux.Cool 使用对称传输格式,即客户端和服务器发送和接收相同格式的数据。
### 帧格式
| 2 字节 | L 字节 | X 字节 |
| ------------ | ------ | -------- |
| 元数据长度 L | 元数据 | 额外数据 |
### 元数据
元数据有若干种类型。所有类型的元数据都包含 ID 和 Opt 两项,其含义为:
- ID: 子连接的唯一标识
- 对于一般 Mux 子连接ID 由 1 开始累加
- 对于 Xray 实现的 [Single XUDP](https://github.com/XTLS/Xray-core/blob/main/common/xudp/xudp.go)ID 始终为 0
- Opt:
- D(0x01): 有额外数据
当选项 Opt(D) 开启时,额外数据格式如下:
| 2 字节 | X-2 字节 |
| -------- | -------- |
| 长度 X-2 | 数据 |
### 新建子连接 (New)
| 2 字节 | 1 字节 | 1 字节 | 1 字节 | 2 字节 | 1 字节 | A 字节 | 8 字节 |
| ------ | ------ | -------- | ---------- | ------ | ---------- | ------ | ---------------- |
| ID | 0x01 | 选项 Opt | 网络类型 N | 端口 | 地址类型 T | 地址 A | Global ID (XUDP) |
其中:
- 网络类型 N
- 0x01TCP表示当前子连接的流量应当以 TCP 的方式发送至目标。
- 0x02UDP表示当前子连接的流量应当以 UDP 的方式发送至目标。
- 地址类型 T
- 0x01IPv4
- 0x02域名
- 0x03IPv6
- 地址 A
- 当 T = 0x01 时A 为 4 字节 IPv4 地址;
- 当 T = 0x02 时A 为 1 字节长度L + L 字节域名;
- 当 T = 0x03 时A 为 16 字节 IPv6 地址;
- Global ID (XUDP)
- 客户端计算出 UDP 来源二元组的全局独特 ID服务端用以确保当 XUDP 断线重连时,仍使用同一个端口与目标通信。
在新建子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。
### 保持子连接 (Keep)
TCP
| 2 字节 | 1 字节 | 1 字节 |
| ------ | ------ | -------- |
| ID | 0x02 | 选项 Opt |
UDP
| 2 字节 | 1 字节 | 1 字节 | 1 字节 | 2 字节 | 1 字节 | A 字节 |
| ------ | ------ | -------- | ---------- | ------ | ---------- | ------ |
| ID | 0x02 | 选项 Opt | 网络类型 N | 端口 | 地址类型 T | 地址 A |
在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。
XUDP 在 Opt(D) 之后加 UDP 地址,格式同新建子连接,但没有 Global ID。
### 关闭子连接 (End)
| 2 字节 | 1 字节 | 1 字节 |
| ------ | ------ | -------- |
| ID | 0x03 | 选项 Opt |
在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。
### 保持连接 (KeepAlive)
| 2 字节 | 1 字节 | 1 字节 |
| ------ | ------ | -------- |
| ID | 0x04 | 选项 Opt |
在保持连接时:
- 若 Opt(D) 开启,则这一帧所带的数据必须被丢弃。
- ID 可为随机值。
## 应用
Mux.Cool 协议与底层协议无关,理论上可以使用任何可靠的流式连接来传输 Mux.Cool 的协议数据。
在目标导向的协议如 Shadowsocks 和 VMess 协议中,连接建立时必须包含一个指定的地址。
为了保持兼容性Mux.Cool 协议指定地址为“v1.mux.cool”。即当主连接的目标地址与之匹配时则进行 Mux.Cool 方式的转发否则按传统方式进行转发。这是一个程序内的标记VMess 和 VLESS 并不会在数据包中发送“v1.mux.cool”地址