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 技术具有重要意义。

相关推荐
海尔辛28 分钟前
学习黑客Active Directory 入门指南(一)
windows·学习·ad
兔子坨坨2 小时前
pycharm连接github(详细步骤)
windows·git·学习·pycharm·github
虾球xz3 小时前
游戏引擎学习第293天:移动Familiars
c++·学习·游戏引擎
lichuangcsdn3 小时前
【springcloud学习(dalston.sr1)】Eureka服务端集群的搭建(含源代码)(二)
学习·spring cloud·eureka
名誉寒冰3 小时前
RPC框架源码分析学习(二)
qt·学习·rpc
m0_738206546 小时前
嵌入式学习的第二十二天-数据结构-栈+队列
数据结构·学习
向上的车轮12 小时前
MATLAB学习笔记(七):MATLAB建模城市的雨季防洪排污的问题
笔记·学习·matlab
前端小崔12 小时前
从零开始学习three.js(18):一文详解three.js中的着色器Shader
前端·javascript·学习·3d·webgl·数据可视化·着色器
龙湾开发13 小时前
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(二)法线贴图
c++·笔记·学习·图形渲染·贴图
liang_202614 小时前
【HT周赛】T3.二维平面 题解(分块:矩形chkmax,求矩形和)
数据结构·笔记·学习·算法·平面·总结