WebRTC学习七:WebRTC 中 STUN 协议详解

系列文章目录

第一篇 基于SRS 的 WebRTC 环境搭建

第二篇 基于SRS 实现RTSP接入与WebRTC播放

第三篇 centos下基于ZLMediaKit 的WebRTC 环境搭建

第四篇 WebRTC学习一:获取音频和视频设备

第五篇 WebRTC学习二:WebRTC音视频数据采集

第六篇 WebRTC学习三:WebRTC音视频约束

第七篇 WebRTC学习四:WebRTC常规视觉滤镜

第八篇 WebRTC学习五:从视频中提取图片

第九篇 WebRTC学习六:MediaStream 常用API介绍

第十篇 WebRTC学习七:WebRTC 中 STUN 协议详解


文章目录

  • 系列文章目录
  • 前言
  • [一、STUN 协议的作用](#一、STUN 协议的作用)
  • [二、STUN 协议的交互过程](#二、STUN 协议的交互过程)
    • [1.客户端与 STUN 服务器的交互](#1.客户端与 STUN 服务器的交互)
      • [(1) 客户端发送请求:](#(1) 客户端发送请求:)
      • [(2) STUN 服务器处理请求:](#(2) STUN 服务器处理请求:)
      • [(3) STUN 服务器返回响应:](#(3) STUN 服务器返回响应:)
      • [(4) 客户端获取公网地址:](#(4) 客户端获取公网地址:)
    • 2.客户端之间的交互准备
  • [三、STUN 协议报文格式详解](#三、STUN 协议报文格式详解)
    • [STUN Message Header(RFC5389/RFC8489)](#STUN Message Header(RFC5389/RFC8489))
    • [STUN Message Body](#STUN Message Body)
  • [四、zlmediakit 中STUN 协议抓包](#四、zlmediakit 中STUN 协议抓包)
  • 总结

前言


最近在看zlmediakit源码,发现webrtc部分涉及到STUN和DTLS协议,为了更方便的看懂这部分代码,网上查了下STUN协议和DTLS协议,将STUN协议部分先做个记录,后面结合代码如果有更深入的理解,再来更新其中的内容。

在 WebRTC(Web Real - Time Communication)技术体系里,STUN(Session Traversal Utilities for NAT,NAT 会话穿越应用程序)协议发挥着关键作用。WebRTC 旨在实现浏览器之间的实时音视频通信,但由于网络中广泛存在的 NAT(网络地址转换)设备,会对直接通信造成阻碍,而 STUN 协议则是解决这一问题的重要工具。


一、STUN 协议的作用

STUN 协议主要用于帮助处于 NAT 设备之后的客户端发现自己的公网 IP 地址和端口,也就是确定自己在公网上的可达地址。这样,即使客户端处于私有网络中,也能让对端知道如何与自己建立直接的连接,从而实现 WebRTC 通信的端到端连接。

二、STUN 协议的交互过程

1.客户端与 STUN 服务器的交互

(1) 客户端发送请求:

处于 NAT 之后的客户端向 STUN 服务器发送一个 Binding Request(绑定请求)消息。这个请求消息中包含了客户端的一些信息,例如客户端希望服务器返回的信息类型等。

(2) STUN 服务器处理请求:

STUN 服务器接收到请求后,会记录下接收到该请求的源 IP 地址和端口,这就是客户端经过 NAT 转换后的公网地址和端口。

(3) STUN 服务器返回响应:

STUN 服务器将客户端的公网地址和端口信息封装在 Binding Response(绑定响应)消息中,发送回客户端。

(4) 客户端获取公网地址:

客户端接收到响应消息后,就可以从消息中提取出自己的公网地址和端口信息,并将这些信息用于后续的 WebRTC 通信。

2.客户端之间的交互准备

客户端获取到公网地址和端口后,会将这些信息通过信令服务器发送给对端客户端。对端客户端收到信息后,就可以尝试与该客户端建立直接的连接。

三、STUN 协议报文格式详解

RFC5389(Session Traversal Utilities for NAT)是在RFC3489(Simple Traversal of UDP Through NAT)的基础上增加了对TCP的支持,使其不仅适用于UDP,还适用于TCP协议,从而提供更全面的NAT穿越解决方案‌。具体来说,RFC5389将STUN描述为一系列穿越NAT的工具,而不仅仅是基于UDP的简单穿透方法‌。

相比之下,RFC8489是对RFC5389的进一步扩展和标准化,但它并没有引入新的功能或协议变化,而是对现有的STUN协议进行了标准化和规范化‌。

目前RFC3489已经废弃,更多的用的是RFC5389和RFC8489。

STUN协议包含20字节的STUN Message header和STUN Message Body部分,body中可以含有0或多个Attribute.

STUN Message Header(RFC5389/RFC8489)

STUN 报文的头部固定为 20 字节,其具体含义如下:

最前面的2bit 00:不同的协议复用同一端口时,用于与其它协议做区分。

STUN Message Type :STUN 消息类型,定义了消息 class 和消息 method,用于标识该消息是请求、响应还是错误消息等。STUN Message Type的结构如下

其中C0和C1合起来定义class,M0-M11 定义了method。class 四个值定义如下表:

C1C0的值 含义
0b00 request
0b01 indication
0b10 success response
0b11 error response

method只定义了一个方法,即Binding,0b000000000001(0x0001);

因此Binding的request的消息类型为0x0001,Binding的success response的消息类型为0x0101。

Message Length(2 字节): :消息长度,表示整个消息除去头部的长度,单位为字节。
Magic Cookie(4 字节) :固定值 0x2112A442,用于快速识别 STUN 消息。
Transaction ID(96bit, 12 字节):用于唯一标识一个事务,客户端和服务器通过这个 ID 来匹配请求和响应。

STUN Message Body

20字节的STUN消息头之后是0个或者多个属性。每个属性进行TLV编码,每个属性的长度不固定,但都是 4 字节的整数倍。

属性的结构如下


Type(2 字节): :16字节属性类型。
Length(4 字节) :属性长度,Value的长度,单位是字节,必须是4字节的整数倍。
Value:属性的数据。

属性定义表

Type 属性名 含义 备注
0x0001 MAPPED-ADDRESS 表示服务器观察到的客户端经NAT转换后的外网地址和端口,主要用于兼容遵循RFC 3489的旧版STUN客户端。
0x0002 RESPONSE - ADDRESS 客户端通过此属性告知服务器将响应消息发送到指定的地址和端口,即客户端期望接收响应的目标地址。
0x0003 CHANGE - REQUEST 客户端使用该属性请求服务器在发送响应时变更IP地址、端口或两者都变更,用于检测NAT的行为。
0x0004 SOURCE - ADDRESS 服务器发送响应消息时所使用的源地址和端口,客户端可以通过该属性了解服务器的实际发送地址。
0x0005 CHANGED - ADDRESS 服务器告知客户端,如果客户端发送CHANGE - REQUEST请求,服务器将使用此地址和端口发送响应,是服务器的备用响应地址。
0x0006 USERNAME 用于消息完整性检查和认证过程,标识消息完整性验证中使用的用户名,该值为可变长度的UTF - 8编码序列,且需经过SASLprep处理。
0x0007 PASSWORD 与认证相关,通常与USERNAME属性配合使用,用于验证客户端身份,但在RFC 5389中较少直接使用,更多结合其他认证机制。
0x0008 MESSAGE-INTEGRITY 该属性包含STUN消息的HMAC - SHA1哈希值(20字节),用于确保消息在传输过程中未被篡改,保证消息的完整性和真实性。
0x0009 ERROR-CODE 用于错误响应消息,包含一个300到699范围内的数字错误代码,以及一个UTF - 8编码的文本短语,用于描述错误的具体信息。
0x000A UNKNOWN-ATTRIBUTES 当服务器收到包含其不识别属性的STUN消息时,会在错误码为420的错误响应中使用该属性列出这些未知属性的类型。
0x000C REFLECTED - FROM 指示STUN消息是从哪个地址反射过来的,通常用于记录消息的传输路径信息。
0x0014 REALM 可出现在请求和响应消息中,包含符合特定语法的文本,用于长期凭据认证。它是一个UTF - 8编码序列,长度少于128个字符,且经过SASLprep处理,出现该字段表示使用长期凭据认证方式。
0x0015 NONCE 由服务器生成的一个可变长度的不透明值,用于防止重放攻击。客户端在后续请求中需要包含相同的NONCE值,服务器通过检查NONCE值确保消息的新鲜性和唯一性。 需UTF - 8编码且经SASLprep处理
0x001C MESSAGE-INTEGRITY-SHA256 与MESSAGE - INTEGRITY类似,但使用SHA256算法计算消息的HMAC哈希值,提供更高的安全性,用于保证消息的完整性。
0x001D PASSWORD-ALGORITHM 用于指定认证过程中所使用的密码算法,告知对端采用何种加密算法对密码进行处理和验证。
0x001E USERHASH 对用户名进行哈希处理后的值,用于在不直接传输明文用户名的情况下进行用户标识和认证,增强了用户信息的安全性。
0x0020 XOR - MAPPED - ADDRESS 是MAPPED - ADDRESS的改进版本,使用XOR运算对地址和端口进行加密处理,提高了地址信息在传输过程中的安全性,避免地址信息被轻易截取和分析。 格式见后面
0x0024 PRIORITY 在ICE(交互式连接建立)过程中,用于指示候选地址的优先级。客户端会收集多个候选地址,每个地址都有对应的优先级,服务器或对端可根据该优先级决定优先使用哪个候选地址建立连接。 RFC 8445 ICE 扩展定义
0x0025 USE-CANDIDATE 用于通知对端立即使用指定的ICE候选地址对进行连接,跳过部分候选地址筛选和验证过程,加速连接的建立。 RFC 8445 ICE 扩展定义
0x8002 PASSWORD-ALGORITHMS 列出服务器支持的所有密码算法,客户端可以根据这些信息选择合适的算法进行认证。
0x8003 ALTERNATE-DOMAIN 提供一个备用的域名,用于在主域名不可用时作为替代,可能用于引导客户端到备用的服务或资源。
0x8022 SOFTWARE 携带生成该STUN消息的软件或设备的相关信息,如软件名称、版本号等,有助于网络故障排查和统计分析。
0x8023 ALTERNATE - SERVER 提供备用的STUN或TURN服务器地址,当主服务器不可用时,客户端可以尝试连接这些备用服务器。
0x8028 FINGERPRINT 对消息计算的CRC - 32值,用于快速验证消息完整性。接收方重新计算CRC - 32值并与该属性值比较,若一致则消息未被篡改。
0x8029 ICE-CONTROLLED 在ICE连接建立过程中,标识一个端点处于受控(Controlled)角色,该端点需遵循控制者端点的决策来建立连接。 RFC 8445 ICE 扩展定义
0x802A ICE-CONTROLLING 在ICE连接建立过程中,标识一个端点处于控制(Controlling)角色,该端点负责协调和决定使用哪个候选地址对来建立连接。 RFC 8445 ICE 扩展定义

四、zlmediakit 中STUN 协议抓包

总结

STUN 协议在 WebRTC 通信中是实现端到端连接的重要基础。通过客户端与 STUN 服务器的交互,客户端能够发现自己的公网地址和端口,为后续的直接通信提供了可能。了解 STUN 协议的交互过程和报文格式,对于深入研究 WebRTC 技术具有重要意义。

相关推荐
虾球xz12 分钟前
游戏引擎学习第123天
学习·游戏引擎
LuckyLay13 分钟前
Golang学习笔记_38——享元模式
笔记·学习·设计模式·golang·享元模式
深夜食堂-20 分钟前
2025年第16届蓝桥杯嵌入式竞赛学习笔记(十):ADC测量电压
笔记·学习·蓝桥杯
虾球xz2 小时前
游戏引擎学习第121天
学习·游戏引擎
陈无左耳、2 小时前
HarmonyOS学习第5天: Hello World的诞生之旅
学习·华为·harmonyos
勤不了一点3 小时前
【GO】学习笔记
笔记·学习·golang·go
前端熊猫3 小时前
C语言基本输入输出学习笔记
c语言·笔记·学习
PyAIGCMaster3 小时前
50周学习go语言:第五周 复合类型与词频统计
服务器·学习·golang
我要吐泡泡了哦5 小时前
GAMES104:18 网络游戏的架构基础-学习笔记
笔记·学习·架构
青い月の魔女6 小时前
C++---了解STL
开发语言·c++·笔记·学习