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

相关推荐
陌言不会python1 小时前
谷粒微服务高级篇学习笔记整理---thymeleaf
笔记·学习·微服务
Y1nhl3 小时前
Pyspark学习一:概述
数据库·人工智能·深度学习·学习·spark·pyspark·大数据技术
能来帮帮蒟蒻吗3 小时前
Go语言学习(15)结构体标签与反射机制
开发语言·笔记·学习·golang
Aphelios3806 小时前
Java全栈面试宝典:线程机制与Spring IOC容器深度解析
java·开发语言·jvm·学习·rbac
日暮南城故里6 小时前
Java学习------源码解析之StringBuilder
java·开发语言·学习·源码
安全方案9 小时前
精心整理-2024最新网络安全-信息安全全套资料(学习路线、教程笔记、工具软件、面试文档).zip
笔记·学习·web安全
士别三日&&当刮目相看9 小时前
JAVA学习*Object类
java·开发语言·学习
序属秋秋秋10 小时前
算法基础_基础算法【高精度 + 前缀和 + 差分 + 双指针】
c语言·c++·学习·算法
爱吃馒头爱吃鱼10 小时前
QML编程中的性能优化二
开发语言·qt·学习·性能优化
白夜易寒11 小时前
Docker学习之容器虚拟化与虚拟机的区别(day11)
学习·docker·容器