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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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”地址