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 更復雜;