TURN(Traversal Using Relays around NAT)协议是一个网络协议,旨在解决 NAT(网络地址转换)和防火墙 环境下的 UDP/TCP通信问题。它通常与 STUN 和 ICE 协议一起使用,广泛应用于 WebRTC、SIP 和视频会议等实时通信场景中。
为什么需要 TURN?
- NAT 问题
NAT 会屏蔽内网客户端的真实地址,使两个处于不同 NAT 环境的客户端 无法直接建立连接。
- STUN 的局限
STUN 可以帮助客户端获取自己的公网 IP 和端口,但当:
- 双方都在对称型 NAT 后面,
- 或者存在严格的防火墙时,
STUN 穿透失败,这时就需要 TURN。
工作原理
TURN 的基本思想是:
通过中继服务器(TURN Server)转发媒体流量,绕过 NAT/防火墙。
工作流程
-
阶段1:客户端与 TURN Server 建立连接(Allocate)
-
Step 1.1:客户端发起 Allocate 请求
- 类型:
Allocate Request
- 内容:希望使用的传输协议(UDP/TCP)、Lifetime 等
- 信令方式:基于 STUN over UDP/TCP
Client A --> TURN Server Message: Allocate Request Attributes: REQUESTED-TRANSPORT=UDP
- 类型:
-
Step 1.2:TURN Server 分配中继地址
-
返回:
Allocate Success Response
-
包含字段:
XOR-RELAYED-ADDRESS
(中继地址)、XOR-MAPPED-ADDRESS
(客户端映射地址)
TURN Server --> Client A Message: Allocate Success XOR-RELAYED-ADDRESS: 203.0.113.1:54320 ← 中继地址
-
-
-
阶段2:建立 Permission(通信授权)
为了安全,TURN Server 默认不允许所有对端通信,必须显式授权。
-
Step 2.1:CreatePermission 请求
Client A --> TURN Server Message: CreatePermission XOR-PEER-ADDRESS: 对端 B 的公网地址
-
Step 2.2:成功响应
-
若授权成功,返回
CreatePermission Success Response
-
默认权限 300 秒失效
-
-
阶段3:数据通道建立(Send Indication 或 ChannelBind)
TURN 支持两种数据通道:
通道方式 | 描述 | 性能 |
---|---|---|
Send/Receive Indication | 使用完整 STUN 消息发送数据 | 灵活,开销大 |
ChannelData | 映射通道编号,提高效率 | 更快,推荐 |
- Step 3.1:发送 ChannelBind 请求
Client A --> TURN Server
Message: ChannelBind
XOR-PEER-ADDRESS: Client B
CHANNEL-NUMBER: 0x4000-0x7FFF(客户端分配)
-
Step 3.2:TURN Server 回复成功绑定
- 之后,Client A 可以通过
ChannelData
消息直接发送媒体数据。
- 之后,Client A 可以通过
-
阶段4:媒体数据中继传输
- A → B 流程
Client A --> TURN Server Message: ChannelData 或 Send Indication
TURN Server --> Client B Message: UDP/TCP 数据包
-
B → A 反向流
Client B --> TURN Server(发往分配的 relayed address) TURN Server --> Client A(通过 Channel 或 Data Indication)
-
阶段5:Refresh 保活
-
TURN allocation 默认 600秒过期
-
客户端需周期性发送
Refresh Request
保活Client A --> TURN Server Message: Refresh Request LIFETIME: 600
-
流程时序图:
客户端A TURN服务器 客户端B| | ||-------- Allocate Request --------->| ||<------ Allocate Response ----------| || | ||--- CreatePermission (B的IP) ----->| ||<--- CreatePermission Success ------| || | ||-------- ChannelBind (B的IP) ----->| ||<----- ChannelBind Success ---------| || | ||---- ChannelData(B的数据) ------->| || |-----> 转发数据到 客户端B ---------->|| |<----- 客户端B发来响应数据 -----------||<--- ChannelData(返回数据) -------| || | ||--------- Refresh Request --------->| ||<-------- Refresh Response ---------| |
TURN 与 STUN、ICE 的关系
协议 | 作用 |
---|---|
STUN | 获取公网地址,尝试打洞 |
TURN | 中继传输,保证连接 |
ICE | 综合使用 STUN/TURN,选择最优路径(直接连接优先) |
TURN 是一种最后手段,因为它会增加 延迟 和 带宽成本。
协议详解
协议标准
TURN 协议定义在以下 RFC 中:
- RFC 5766:TURN 协议标准
- RFC 5389:STUN 基础
- RFC 6062:支持 TCP 的 TURN
- RFC 6156:IPv6 支持
通信流程详细图解
客户端A ---------> TURN服务器 <--------- 客户端BAllocate Send IndicationRefresh Data ChannelSend/Receive Permissions
主要步骤:
- Allocate Request:客户端请求分配中继地址;
- Allocate Success Response:服务器返回一个公网 IP+端口(Relayed Address);
- CreatePermission:允许某个对端向这个中继地址发送数据;
- Send Indication / Data Indication:发送或接收数据;
- Refresh:保持分配有效(每300秒刷新);
- Channel Bind(可选):绑定 Channel,降低通信成本;
消息结构(基于 STUN)
TURN 消息与 STUN 类似,由以下字段组成:
- Message Type:请求/响应/指示类型
- Transaction ID:用于匹配请求与响应
- Attributes:
- XOR-RELAYED-ADDRESS:返回的中继地址
- LIFETIME:分配有效期
- DATA:要中继的实际数据
- XOR-PEER-ADDRESS:目标地址
TURN Server 实现
常见开源 TURN Server:
名称 | 简介 |
---|---|
Coturn | 最流行的 TURN server,支持 STUN、TURN、TLS 等协议 |
restund | 轻量级实现 |
rfc5766-turn-server | 老旧项目,已被 Coturn 替代 |
Coturn 配置文件示例:
listening-port=3478
relay-ip=your_public_ip
realm=yourdomain.com
user=username:password
优缺点
优点:
- 100% 可达性:即使双方都在对称 NAT 后,也能通信;
- 标准化:已被 WebRTC、SIP 等广泛采用;
缺点:
- 服务器成本高:带宽开销大;
- 延迟增加:所有流量都要绕行服务器;
- 复杂度增加:协议较 STUN 更复杂;