流媒体传输协议之 RTP(下篇) (5)

一个数据源可能发现自己的或者别人的报文被循环发送了。无论是报文循环还是 SSRC 的碰撞都会导致同一个现象,即 SSRC 相同但是传输地址不同的报文。因此,如果数据源改变了自己的传输地址,那它就需要同时改变自己的 SSRC 来避免被检测成环形报文。有一个需要注意的内容是,如果一个 Translator 再重启的过程中改变了自己的传输地址,那么这个 Translator 转发的所有数据都会被检测成环。这类情况的解决方案一般有如下两个:

重启的时候不改变传输地址。

接收者的超时机制。

如果循环或者碰撞发生在离 Translator 和 Mixer 很远的地方,我们就不能通过传输地址来发现。但是我们仍然可以通过 CNAME 的不同来发现 SSRC 碰撞。

为了解决上述问题,RTP 的实现必须包含一个类似如下的算法。这个算法不包括多个数据源 SSRC 碰撞的情况,这类情况通常下都是先用原来的 SSRC 发送一个 BYE 然后重新选择一个新的 SSRC。

这个算法需要维护一个 SSRC 和传输地址的映射关系。因为 RTP 的数据和 RTCP 传输使用的是两个不同的端口,所以一个 SSRC 对应的是两个传输地址。

每次收到 RTP 报文和 RTCP 报文都会将其 SSRC 和 CSRC 在上述的表中进行比对。如果发现了传输地址对不上的情况,我们就可以说发现了一个循环或者碰撞。对于 RTCP 数据来说,可能每个数据块都有自己独立的 SSRC,比如 SDES 数据,对于这种情况就需要分别比对。如果没有在表中找到这个 SSRC 或者 CSRC,就需要新添加一项。当收到 BYE 报文时,需要先比对这个 BYE 的传输地址,如果传输地址匹配上了,就将这一项从表中删除。或者基于超时机制,将超时的数据从表中移除。

为了追踪自己的数据报文循环情况,必须维护另一个列表,这个表存储冲突报文的传输地址和收到该报文的时间。如果超过 10 个 RTCP 周期都没有收到这个传输地址的冲突报文,就将该项从表中删除。

下面的算法还假设参与者自己的 SSRC 和状态都包含在 SSRC 表中,它会先比对自己的 SSRC。

if (SSRC or CSRC identifier is not found in the source identifier table) { create a new entry storing the data or control source transport address, the SSRC or CSRC and other state; } /* Identifier is found in the table */ else if (table entry was created on receipt of a control packet and this is the first data packet or vice versa) { store the source transport address from this packet; } else if (source transport address from the packet does not match the one saved in the table entry for this identifier) { /* An identifier collision or a loop is indicated */ if (source identifier is not the participant's own) { /* OPTIONAL error counter step */ if (source identifier is from an RTCP SDES chunk containing a CNAME item that differs from the CNAME in the table entry) { count a third-party collision; } else { count a third-party loop; } abort processing of data packet or control element; /* MAY choose a different policy to keep new source */ } /* A collision or loop of the participant's own packets */ else if (source transport address is found in the list of conflicting data or control source transport addresses) { /* OPTIONAL error counter step */ if (source identifier is not from an RTCP SDES chunk containing a CNAME item or CNAME is the participant's own) { count occurrence of own traffic looped; } mark current time in conflicting address list entry; abort processing of data packet or control element; } /* New collision, change SSRC identifier */ else { log occurrence of a collision; create a new entry in the conflicting data or control source transport address list and mark current time; send an RTCP BYE packet with the old SSRC identifier; choose a new SSRC identifier; create a new entry in the source identifier table with the old SSRC plus the source transport address from the data or control packet being processed; } } 层级编码

对于不同 Session 的层级编码传输,一般都是所有层都使用同一个 SSRC,如果其中某一层发现了 SSRC 冲突,那么只改变这一层的 SSRC,而且他层的 SSRC 不做改变。

安全

下层协议可能会提供 RTP 应用所需要的所有安全服务,包括认证,数据完整性,数据保密性。这些服务在 IP 协议中都有解决方案。因为 Audio 和 Video 初始化过程中需要数据加密,而这时候 IP 协议这一层的安全服务还没有提供。所以,RTP 需要实现一个 RTP 专用的保密服务。这个保密服务是非常轻量级的,而且保密部分的服务向后兼容,以后可以随时进行更换。或者,某些预设会提供这部分加密服务,比如 SRTP(Secure Real-time Transport Protocol),SRTP 是基于 Advanced Encryption Standard (AES) 提供了一个比 RTP 默认加密服务更强大的实现。

保密性

保密性是指我们的报文只希望一些特定的接收者可以解码成明文,而其他人只能得到无用的信息,保密性是通过加密编码来提供的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxjzf.html