Skip to content

TUIC 协议

MasakiMu319

Version

0x05

Overview

TUIC 协议依赖一个可多路复用的 TLS 加密流。所有转发任务都通过 Command 中的 Header 进行协商。

该协议不关心底层传输实现,但主要面向 QUIC 设计。详细机制见 Protocol Flow

除非特别说明,所有字段均为大端序(Big Endian)。

Command

+-----+------+----------+
| VER | TYPE |   OPT    |
+-----+------+----------+
|  1  |  1   | Variable |
+-----+------+----------+

其中:

Command Types

共有五种命令类型:

ConnectPacket 命令会携带有效载荷(流数据 / 分片数据)。

Command Type Specific Data

Authenticate

+------+-------+
| UUID | TOKEN |
+------+-------+
|  16  |  32   |
+------+-------+

其中:

Connect

+----------+
|   ADDR   |
+----------+
| Variable |
+----------+

其中:

Packet

+----------+--------+------------+---------+------+----------+
| ASSOC_ID | PKT_ID | FRAG_TOTAL | FRAG_ID | SIZE |   ADDR   |
+----------+--------+------------+---------+------+----------+
|    2     |   2    |     1      |    1    |  2   | Variable |
+----------+--------+------------+---------+------+----------+

其中:

Dissociate

+----------+
| ASSOC_ID |
+----------+
|    2     |
+----------+

其中:

Heartbeat

+-+
| |
+-+
| |
+-+

Address

Address 是一个用于编码网络地址的变长字段。

+------+----------+----------+
| TYPE |   ADDR   |   PORT   |
+------+----------+----------+
|  1   | Variable |    2     |
+------+----------+----------+

其中:

地址类型可能是:

None 地址类型用于 Packet 命令中“非首个分片”的场景。

端口号位于域名 / IP 地址之后,占 2 字节。

Protocol Flow

本节以 QUIC 作为底层传输,说明协议流程。

协议本身不强制底层传输管理方式。它甚至可以集成到已有服务中,例如 HTTP/3。

下面是 TUIC 在 QUIC 连接上的典型流程:

Authentication

客户端打开一个 unidirectional_stream,发送 Authenticate 命令。该过程可与其他命令并行。

服务端验证令牌。若有效,则连接完成认证,可继续处理转发任务。

若服务端在认证前收到了其他命令,应先解析命令头并暂停;认证完成后再恢复这些任务。

TCP relaying

Connect 用于初始化 TCP 转发。

客户端打开 bidirectional_stream 并发送 Connect。命令头发送完成后,客户端可立即开始转发,无需等待服务端响应。

服务端收到 Connect 后,向目标地址建立 TCP 连接,然后在 TCP 流与 QUIC 双向流之间转发数据。

UDP relaying

TUIC 通过在客户端和服务端之间同步 UDP 会话 ID(ASSOC_ID),实现 0-RTT 全锥形 UDP 转发。

双方应按每条 QUIC 连接维护 UDP 会话表,将每个 ASSOC_ID 映射到对应 UDP 套接字。

ASSOC_ID 由客户端生成,为 16 位无符号整数。若客户端希望服务端复用同一 UDP 套接字,应复用同一 ASSOC_ID

服务端收到 Packet 后会检查 ASSOC_ID 是否已存在。若不存在,则为该关联分配 UDP 套接字。服务端使用该套接字向外发送客户端请求的 UDP 流量,也从任意目标接收回包,再封装 Packet 头返回客户端。

一个 UDP 数据包可拆分为多个 Packet 命令。PKT_IDFRAG_TOTALFRAG_ID 用于识别和重组分片。

作为客户端,Packet 可以通过以下方式发送:

服务端在某个关联首次收到 Packet 后,下行回包应使用相同模式。

客户端可通过 QUIC unidirectional_stream 发送 Dissociate,解除一个 UDP 会话。服务端随后删除会话并释放对应 UDP 套接字。

Heartbeat

只要有转发任务进行中,客户端应周期性通过 QUIC datagram 发送 Heartbeat,以保持连接存活。

Error Handling

协议未为任何命令定义标准响应。若服务端收到非法命令,或在处理时出现错误(例如目标不可达、认证失败),协议层没有统一处理规范。具体行为由实现决定:服务端可以关闭 QUIC 连接,也可以忽略该命令。

例如,当服务端收到目标不可达的 Connect 时,可通过关闭对应 bidirectional_stream 来表示失败。

In-depth Protocol Analysis

深入看,TUIC 是一种现代高性能设计,能有效利用 QUIC 与 TLS;但其极简规范也把大量实现责任交给了工程方。

Executive Summary

TUIC 是一个紧凑、安全、面向低延迟的代理协议。它在多路复用 TLS 流(理想情况下是 QUIC)上使用简洁命令结构,并将加密与可靠性复杂度下放到下层传输。

其亮点是高效的 0-RTT 全锥形 UDP 转发,适合实时业务。

核心权衡是 错误处理未标准化、由实现定义。这让规范保持简洁,但把稳健性、安全性与互操作性负担转移给开发者。

Key Strengths

  1. 性能突出

    • TCP:客户端发送 Connect 后可立即开始传输。
    • UDPASSOC_ID 设计支持 0-RTT 全锥形转发。
    • 效率:心跳与 native UDP 模式基于 QUIC datagram,可降低额外开销。
  2. 安全性强

  3. 设计简洁

    • 协议职责聚焦、边界清晰;
    • 命令帧易于解析;
    • 避免重复实现传输层职责。

Critical Implementation Challenges & Recommendations

1. UDP ASSOC_ID 生命周期管理(DoS 风险)

2. UDP 分片缓冲区管理(DoS 风险)

3. 错误处理标准化

Conclusion

TUIC 是一个实用且强健的协议,适合安全、低延迟的混合 TCP/UDP 隧道场景。但“规范简洁”不等于“生产实现简单”。要做出生产级 TUIC,仍需仔细设计状态生命周期、资源治理和明确的失败语义,补齐规范未完全覆盖的工程空白。

Previous
Next-generation large language model interface architecture
Next
AI Agent上下文工程深度分析:在性能与鲁棒性之间寻求平衡