系列文章目录
第一篇 基于SRS 的 WebRTC 环境搭建
第二篇 基于SRS 实现RTSP接入与WebRTC播放
第三篇 centos下基于ZLMediaKit 的WebRTC 环境搭建
第四篇 WebRTC学习一:获取音频和视频设备
第五篇 WebRTC学习二:WebRTC音视频数据采集
第六篇 WebRTC学习三:WebRTC音视频约束
第七篇 WebRTC学习四:WebRTC常规视觉滤镜
第八篇 WebRTC学习五:从视频中提取图片
第九篇 WebRTC学习六:MediaStream 常用API介绍
第十篇 WebRTC学习七:WebRTC 中 STUN 协议详解
文章目录
- 系列文章目录
- 前言
- 一、STUN 协议的作用
- 二、STUN 协议的交互过程
- 1.客户端与 STUN 服务器的交互
- (1) 客户端发送请求:
- (2) STUN 服务器处理请求:
- (3) STUN 服务器返回响应:
- (4) 客户端获取公网地址:
- 2.客户端之间的交互准备
- 三、STUN 协议报文格式详解
- STUN Message Header(RFC5389/RFC8489)
- STUN Message Body
- 四、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 技术具有重要意义。