公网传输技术之SRT协议解析(下)

LiveVideoStack 2022年5月17日

作者:张博力

编辑:Alex

摘  要: 本文从SRT协议的工作流程谈起,着重介绍和解析了SRT协议的数据包结构,并举例说明如何利用Wireshark抓包软件进行链路故障分析,从而解决实际工作中的问题。

引  言

SRT(Secure Reliable Transport)协议即安全可靠传输协议,是一种新兴的视音频传输协议,能够在公共互联网环境下实现高质量低延时的实时视音频传输。

公网传输技术之SRT协议解析(上)着重讨论了如何衡量SRT协议的可靠程度,以及如何在不同应用场景下配置SRT链路的参数。本文作为下篇,将从SRT协议的工作流程入手,对SRT协议的数据包结构进行解析,之后举例介绍如何利用Wireshark软件进行抓包分析,从而排除链路故障或者获取链路信息。

1、SRT协议工作流程

SRT协议中最常用的工作模式为**“呼叫-监听”(Caller-Listener)**模式,监听方(Listener)会持续监听本方的固定UDP端口,呼叫方(Caller)通过访问监听方的公网IP地址和该固定端口来建立SRT连接。呼叫和监听的角色主要在SRT协议握手阶段起作用,无论是编码端还是解码端都可以担任呼叫者或监听者的角色。

图1表示了SRT协议的工作流程,整个流程包括握手、参数交换、数据传输、连接关闭等步骤。另外在传输有效数据时,双方会发送控制数据来完成丢包恢复、连接保持等功能。

图片

图1  SRT协议工作流程

2、SRT数据包结构

SRT协议根据 UDT协议(UDP-based Data Transfer Protocol) 改进而来,已经在2020年3月10日向IETF提交了RFC草案,这也表示SRT协议进入了比较稳定的发展轨道。

众所周知,SRT的传统优势领域是点对点的实时音视频传输,而近两年,SRT协议在上行推流方面有了迅速的发展,很多主流平台和公司都支持使用SRT协议来代替RTMP协议进行上行推流,其中的关键点就是SRT的StreamID功能,而StreamID功能就包含在SRT握手数据包的配置扩展模块中。

总的来说,SRT协议中包含两类数据包:信息数据包(Data Packet)和控制数据包(Control Packet),他们通过SRT首部的最高位(标志位)来区分,0代表信息数据包,1代表控制数据包。控制数据包又包含了 握手(Handshake)、肯定应答(ACK)、否定应答(NAK)、对肯定应答的应答(ACKACK),保持连接(Keepalive)、关闭连接(Shutdown) 等多种类型。

2.1 信息数据包结构

图2展示了SRT信息数据包的结构,其承载了需要传输的有效数据。SRT首部长度为16字节,最高位为标志位,SRT信息数据包首部包含四个区域:数据包序列号、报文序号、时间戳、目的地端套接字ID

  • 数据包序列号:SRT使用基于序列号的数据包发送机制,发送端每发送一个数据包,数据包序列号加1。

  • 报文序号:报文序号独立计数,在它之前设置了四个标志位(见图2)。

  • 时间戳:以连接建立时间点(StartTime)为基准的相对时间戳,单位为微秒。

  • 目的地端套接字ID:在多路复用时用来区分不同的SRT流。

图片

图2  SRT信息数据包

2.2 握手数据包结构

握手数据包分为HSv4版本(SRT版本<1.3)和HSv5版本(SRT版本>=1.3),图3为HSv5版本握手数据包的结构,HSv5握手数据包主要包含五个区域:SRT首部、握手控制信息(cif.hsv5)、握手请求/响应扩展模块(hsreg/hsrsp)、加密扩展模块(kmreg/kmrsp)、配置扩展模块(config)。这里重点介绍前三个区域,握手数据包的结构参见图3:

图片

图3  HSv5握手数据包

1. 所有SRT控制数据包的首部是基本相同的,均包含四个区域:控制类型和保留区域、附加信息、时间戳、目的地端套接字,其中控制类型字段为0代表握手数据包

2. 握手控制信息区域(cif.hsv5)中比较重要的字段如下:

  • ISN:随机生成的数据包初始序列号,之后所有的信息数据包以此为基准计数。

  • 握手类型:该字段第一个作用是表示该握手数据包所处的握手阶段(以“呼叫-监听”模式为例,其握手分为诱导阶段Induction和结尾阶段Conclusion),第二个作用对于用户来说更为重要,在握手失败后“握手类型”字段会显示相应的错误码,错误码所对应的错误类型见表1。

错误码

错误类型

错误码

错误类型

1000

未知原因

1008

对端版本过旧

1001

系统功能错误

1009

集合模式套接字冲突

1002

对端拒绝

1010

密码错误

1003

资源分配问题

1011

需要密码

1004

握手中的错误数据

1012

Stream标志位冲突

1005

监听方Backlog溢出

1013

拥塞控制类型冲突

1006

内部程序错误

1014

包过滤器冲突

1007

该套接字已关闭

1015

组冲突

表1 错误码和错误类型对应表1

  • SRT套接字ID:该字段需要和SRT首部中的目的地端套接字ID加以区分,该字段只作用于握手阶段,而目的地端套接字ID作用于数据传输全过程。

  • 同步cookie:在“呼叫-监听”模式下,出于防止DoS攻击的目的,只由监听方生成同步cookie,该cookie由监听方的主机、端口和当前时间生成,精确度为1分钟。

3. 握手请求扩展模块(HSREG)中比较重要的字段如下:

  • SRT版本:只要有任何一方的SRT版本低于1.3,双方就会以HSv4版本握手方式来建立连接,HSv4方式握手会有三次或四次往返,而最新的HSv5握手只需要两次往返。出于兼容性的考虑,即使双方的SRT版本都高于1.3,第一个握手请求信息也是HSv4格式。

  • SRT标志位:共有8位标志位,来实现SRT的不同模式和功能。

  • 发送方向延时和接收方向延时:SRT协议1.3版本实现了双向传输功能,双向传输可以分别设定不同方向的固定延时。对于常规的单向传输,假设A向B发送数据,该方向的延时量Latency应该是A的发送方向延时(PeerLatency)和B的接收方向延时(RecLatency)的最大值,该延时量在握手阶段就已由双方协商确定。在单向传输时,有一些编解码器将它的PeerLatency和RecLatency设置成统一的值,这种简易设置方法并不会影响单向传输的工作。

4. 加密扩展模块KMREQ和配置扩展模块CONFIG

  • 由于篇幅的原因,最后两个非必需的扩展模块不再详细讨论。其中加密扩展模块(KMREQ)主要负责SRT的AES128/AES192/AES256加密功能的实现。而配置扩展模块(CONFIG)包含了四种:SRT_CMD_SID、SRT_CMD_CONGESTION、SRT_CMD_FILTER、SRT_CMD_GROUP,其中SRT_CMD_SID扩展模块就是负责SRT上行推流中不可或缺的StreamID功能,有兴趣的朋友可以自行抓包查看。

2.3 ACK数据包结构

ACK数据包是由SRT接收端反馈给发送端的肯定应答,发送端收到ACK后便会认为相应数据包已经成功送达。ACK数据包中还包含了接收端估算的链路数据,可以作为发送端拥塞控制的参考。ACK数据包结构见图4,其中几个比较重要的字段如下:

图片

图4 ACK控制数据包

  • 控制类型:该字段等于2便表示ACK数据包。

  • 附加信息:其中包含了独立计数的ACK序列号,该序列号主要用于ACK包和ACKACK包的一一对应。

  • 最近一个已接收数据包的序列号+1:该字段的值等于最近一个已收到的信息数据包的序列号加1,例如ACK包中该字段为6,便表示前5个数据包均已收到,发送端可以将它们从缓冲区中踢出。需要注意本字段是和数据包序列号有关,与ACK序列号无关。

  • 往返时延RTT估值:通过ACK数据包和ACKACK数据包估算出的链路往返时延。

  • 往返时延RTT估值的变化量:该变化量能够衡量RTT的波动程度,数值越大表示链路RTT越不稳定。

  • 接收端可用缓冲数据:表示目前接收端缓冲区有多少缓冲数据可供解码,该数值越大越好,其最大值由延时量参数(Latency)决定。

  • 链路带宽估值:对本次链路带宽的估算值。

  • 接收速率估值:接收端下行网络带宽的估算值。

2.4 NAK数据包结构

当SRT接收端发现收到的数据包序列号不连续时,便会判断有数据包丢失,并立刻向发送方回复否定应答(NAK)数据包。此外SRT接收端还会以一定间隔发送周期NAK报告,其中包括了间隔期的所有丢失包序列号,这种重复发送NAK的机制主要为了防止NAK数据包在反向传输中丢失。NAK数据包结构见图5,其控制类型字段等于3,包内含有丢失数据包的序列号列表。

图片

图5 NAK控制数据包

2.5 ACKACK数据包结构

ACKACK的主要作用是用来计算链路的往返时延(RTT),而RTT作为重要的链路信息会包含在ACK数据包中,ACKACK数据包结构参见图6。首先ACK数据包和ACKACK数据包都包含有精准的时间戳和ACK序列号,当发送端传输给接收端ACK数据包时,接受端会立刻返回一个ACKACK数据包,之后发送端会根据“ACK序列号”将ACK包和ACKACK包一一对应起来,并通过将他们的时间戳相减从而得到链路的往返时延(RTT)。

图片

图6 ACKACK数据包结构

2.6 连接保持和连接关闭数据包结构

SRT中最后两个数据包类型是连接保持(Keepalive)数据包和连接关闭(Shutdown)数据包,它们的数据包结构参见图7和图8。

图片

图7 连接保持数据包结构

图片

图8 连接关闭数据包结构

3、Wireshark抓包分析

Wireshark是被业界广泛使用的开源数据包分析软件,它可以截取各类网络数据包,并显示数据包的详细信息。随着广电行业IP化的不断推进,Wireshark的使用也越来越频繁,其重要性可类比于波形监视器对于SDI信号的作用,以及码流分析仪对于TS流信号的作用。

下面列举了两个利用Wireshark软件进行链路分析的例子:

3.1 场景一 连接失败

在SRT链路的搭建过程中,难免会遇到连接失败的情况,其原因是多种多样的,这时我们便可以利用Wireshark的抓包分析功能来判断错误的类型。

图9是连接失败后的抓包数据,抓包视频可参见下方视频。首先可以观察到双方在不停的交换握手数据包,说明握手没有成功,但另一方面也说明IP地址和端口号是设置正确的,双方能够正常通信。

在双方SRT版本都高于1.3的情况下,SRT握手过程需要两次往返,既有四个握手数据包,并且第一个握手数据包一定是HSv4版本握手数据包,由此我们可以定位出第一个握手数据包。接着观察到第四个握手数据包的“Handshake Type”字段是1002-Reject,含义是“对端拒绝”,这表示双方可能在某个参数上不匹配而导致了握手失败。

我们接着查看第二个握手包,这是监听方发给呼叫方的响应,其中“Encryption Field”区域为AES-128,即要求对方以AES-128的方式响应加密。再查看第三个握手包,这是呼叫方发给监听方的,其中“Extended Field”区域的KMREQ模块为NOT,表示该握手包没有加密扩展模块,即没有响应对方的加密要求

经过以上的分析,我们可以得知这次连接失败是因为Listener方要求对端以AES-128的方式响应加密要求,而Caller方并没有做出加密的响应。如果要成功连接,我们就需要获知Listener方的加密密码,并在Caller方选择AES-128的加密方式。

图片

图9 场景一:通过抓包分析找出故障原因

3.2 场景二 获取链路信息

互联网链路中单次往返时延(RTT-Round Trip Time) 表示了数据在发送端和接收端之间往返一次花费的时间。链路的RTT值以及RTT的波动程度决定了SRT链路延时量参数的设置,但实际工作中由于防火墙等原因往往难以直接获得RTT值,这时我们可以通过Wireshark软件对ACK数据包进行分析来获得相应信息。

通过图10可以看到,链路的RTT是20.61毫秒,而RTT的变化量是9.786毫秒,这也说明了该条链路的RTT并不稳定,而RTT波动意味着丢包重传需要的时间也会随之波动,从而带来整条SRT链路差错控制能力的波动,这也意味着我们必须依照该条链路的特性进行参数调整。

图片

图10 场景二:RTT估值和RTT估值的变化量

总  结

SRT协议由于其优异的性能、较低的软硬件要求、开源免费的特性,在各个领域的应用越来越广泛,最近两年在上行推流方面也有了长足的发展。掌握好SRT协议的数据包结构能够帮助我们使用抓包软件进行故障分析和判断,从而快速准确地解决实际工作中出现的问题,希望本文能够给大家带来一些帮助,也欢迎大家讨论和交流。

参考文献:

[1]https://datatracker.ietf.org/doc/html/draft-sharabayko-mops-srt/

[2]SRT Protocol Technical Overview[M/OL].(2018-10) [2020-07]. https://www3.haivision.com/e/38322/srt-tech/8mwjcv/1293755769?h=XZ8B52VndjJ2-4BgYxY0yd2XSxpPXDU78YojBOTOmMs

[3]https://github.com/Haivision/srt/blob/master/docs/API.md

[4]SRT Deployment Guide,v1.1,Issue 01[M/OL].(2018-10) [2020-07].www3.haivision.com/srt-alliance-guide.

延伸阅读:

公网传输技术之SRT协议解析(上)

作者简介:

张博力,安徽广播电视台工程师。

还可输入800
全部评论
作者介绍

LiveVideoStack

音视频技术社区

文章

粉丝

视频

阅读排行
  • 2周
  • 4周
  • 16周
热门视频

用互联网发展视角看元宇宙创新

龙明康/AI工程院常务副院长

单目3D人体姿态估计的挑战和探索

宋波/人工智能高级工程师