低速串行链路下IPUDPRTP数据包头的压缩RFC2508Word格式文档下载.docx
《低速串行链路下IPUDPRTP数据包头的压缩RFC2508Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《低速串行链路下IPUDPRTP数据包头的压缩RFC2508Word格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。
版权声明
Copyright(C)TheInternetSociety(1999).AllRightsReserved.
摘要
本文描述了一种对IP/UDP/RTP数据报头进行压缩的方法,它可以降低在低速串行链路上的网络开销。
多数情况下,三个头可压缩到2-4字节。
请赐教并将您的建议发送到工作组邮件列表rem-conf@或直接给作者。
本文中的关键字“必须”,“必须不”,“要求的”,“应该”,“不应该”,“会”,“不会”,“建议”,“或许”,“可选的”在RFC2119中解释。
目录
本备忘录的状态1
版权声明1
摘要1
1.介绍2
2.设想和折中2
2.1.单工与全双工3
2.2.分片与分层3
3.压缩算法3
3.1.基本概念3
3.2RTP数据包头压缩4
3.3协议5
3.4.RTCP控制包压缩12
3.5.非RTPUDP包压缩13
4.与分片的交互13
5.压缩协商13
6.致谢14
7.参考文献14
8.安全性考虑14
9.作者地址15
10.版权声明15
1.介绍
随着实时传输协议(RTP)成为正式的RFC[1]发行,人们对于利用RTP实现不同的网络音视频应用程序间互操作的兴趣也日益增长。
然而,我们也注意到,当使用低速链路如14.4Kb/s或28.8Kb/s拨号时,12字节的RTP头对于仅有20字节的负载而言开销实在太大。
(为了减少头占用的字节,一些已经在类似环境下存在的应用通常使用自定义的协议,而这样做的代价就是削减了RTP相关的功能。
)
事实上,正如在TCP中已经取得巨大成功,也可通过压缩技术来令IP/UDP/RTP包头变小。
这时,压缩可以针对于RTP头(在端到端应用中),或者IP,UDP,RTP的组合头(在Link-by-Link应用中)。
将40字节的组合头一起进行压缩比仅压缩12字节的RTP头更具实际效果,因为两种情况下的结果大小均为约2-4字节。
同时,由于延迟和丢失率都很低,对Link-by-Link应用进行压缩性能上也更好。
因此我们在这里定义的方法就是针对Link-by-link应用下IP/UDP/RTP头进行组合压缩。
本文定义的压缩方案可应用于IPv4包、IPv6包或封装了多个IP头的包。
为了能同时在IPv6和IPv4下使用,这里定义的IP/UDP/RTP压缩符合[3]中规定的通用压缩框架。
该框架把TCP和非TCP定义为IP之上的两个传输类。
本规范将IP/UDP/TCP从非TCP类中抽取出来创建为第三类。
2.设想和折中
本压缩方案的目标是,在不发送UDP校验和的情况下,将大多数包的IP/UDP/RTP头压缩到2个字节,在带校验和时则压缩到4个字节。
这一方案的提出主要是受使用14.4kb/s和28.8kb/s拨号调制解调器发送音视频时遇到的相关问题所引起。
这些链路提供全双工通信,所以协议利用了这点,尽管协议在用于单工链路时可能性能会有所下降。
该方案在本地链路上往返时间(RTT)很低,从而实现性能最高。
为了降低低速链路下的延迟,除了在第四节中确定了分片和压缩中可能使用的一些交互外,本规范并未提出大型数据包的分片和占先策略。
分片方案可能会单独定义并与本压缩方案配合使用。
应该注意到,实现的简单性是评价压缩方案的一个重要因素。
通信服务器可能要用一个处理器支持多达100个拨号调制解调器的数据压缩。
因此,如下的考虑都是比较恰当的,即在设计阶段为了实现简单而牺牲一些通用性,或者在设计上灵活通用但为了简单性可对设计进行子集化。
通过在压缩和解压器之间用更复杂的模型通信改变头字段还可以达成更好的压缩效果,但其复杂性却是没必要的。
下一节将讨论这里列出的一些折中方案。
2.1.单工与全双工
在没有其它限制的情况下,单工链路上的压缩方案应成为首选。
但为防止错误发生,单工链路上的操作需要用一个含有压缩状态信息的未压缩包头进行周期性的刷新。
如果明显的错误信号可以返回,则恢复延迟也可以实质性地缩短,无错误情况的开销也会降低。
为了实现这些性能的优化,本规范包括了一个可逆向发送的明显错误指示。
在单工链路中,可以使用周期性刷新来取代。
解压器一旦侦测到错误存在于某个特定的流中,它可以简单地放弃该流中所有的包直到接收到一个未压缩的头为止,然后继续解压。
其致命弱点在于可能要在恢复解压前要放弃大量的包。
周期性刷新的方法在[3]的3.3节中进行描述,它应用于单工链路的IP/UDP/RTP压缩,或者应用于其它非TCP包流的高延迟链路。
2.2.分片与分层
在低速链路上发送大型数据包所需时间而导致的延迟对于单向音频应用不算什么大问题,因为接收方可以适应延迟变动。
但对于交互式的交谈,最小端到端延迟是非常关键的。
对大的,非实时数据包进行分片以允许小的实时包在分片间隙进行传送可以降低这种延迟。
本规范只处理压缩,并且假定,如果包括分片,也将被处理为一个单独层。
将分片和压缩按这种方式进行集成并不可取,因为一旦如此,在没有必要或不可能进行分片的情况下,连压缩都不能使用。
类似地,应该避免预留协议的任何需求。
除了要求链路层提供一些包类型码,一个包长度指示和良好的错误检测外,该压缩方案可独立于任何其它机制而应用在本地链路的两端。
相反,单独对IP/UDP和RTP层进行压缩丢失了太多的压缩效率,这些效率可以通过将它们一起对待而得到。
由于相同的函数可以应用于所有层,实现跨越这些协议层边界的方案是恰当的。
3.压缩算法
本文定义的压缩算法主要利用了RFC1144[2]描述的TCP/IP头压缩的设计。
读者可以参考该RFC获取更多的关于对包头进行压缩的基本动机和通用原理。
3.1.基本概念
对TCP头压缩的研究发现,IP和TCP头有一半的字节在整个连接期间保持不变,这正是降低数据率的两个要素中的首要因素。
因此,在发送一次未压缩头之后,可以将这些字段从其后的压缩头中除去。
其余的压缩来自对变化字段进行区分编码以减少长度,以及在通常情况下根据包长度计算变化而完全删除掉变化字段。
这一长度由链路层协议指示。
对于RTP头的压缩也可以采用一些相同的技术。
不过最大的收获在于人们发现,尽管每个包中总有几个字节要发生变化,但包与包之间的区别却是恒定的,因此二次差分为0。
在会话期间,通过维护压缩与解压器共享的未压缩头与一次差分序列,所需通信的便只有二次差分为0的指示了。
在这种情况下,如果不考虑任何信息丢失,则解压器在收到一个压缩包后可以通过将一次差分结果加到保存的未压缩头来重建原始包头。
象TCP/IP头压缩为多个同时的TCP连接维护一个共享状态一样,IP/UDP/RTP压缩也应该为多个会话环境维护状态。
一个会话环境是由IP源地址和目的地址,UDP源端口和目的端口,以及RTP的SSRC字段定义。
解压器在实现时可以对这些字段使用哈希函数来检索存储的会话环境列表。
压缩包携带一个称为会话环境标识符或者CID的小整数来指示该包应该解释到哪个环境中。
解压方可以使用CID直接在存储的环境列表中来进行检索。
由于RTP压缩是无损压缩,它可应用于任何可从中受益的UDP通信。
当然最可能的例子就是RTP包,不过也可以使用试探法来判断一个包是否为RTP包,因为即便试探法给出的答案是错的也不会造成什么损害。
这样做需要对所有的UDP包或者至少对偶数端口号的包(见3.4节)执行压缩算法。
为了避免将来无谓地重试,大多数压缩器在实现时都要维护包流的一个“拒绝缓存”来记录那些多次作为RTP包尝试而压缩失败的包。
压缩失败往往意味着潜在的RTP包头中一些在多数时间应保持恒定字段却发生了变化,如负载类型字段。
即便其它类似的字段都保持不变,为了避免耗尽所有的可用会话环境,一个SSRC字段不断改变的包流也应放入拒绝缓存。
拒绝缓存可通过源IP地址和目的IP地址以及UDP端口对进行索引,而SSRC字段因为可能发生变化不能用来作为索引。
当RTP压缩失败,IP和UDP头仍然可以被压缩。
分片后不是初始片的IP包和长度不够容纳一个完整UDP头的包都不能作为FULL_HEADER发送。
另外,没有容纳至少12字节UDP数据的包也不能用于创建RTP环境。
如果这样的包作为FULL_HEADER包发送,它后面可以跟随COMPRESSED_UDP包但不能跟随COMPRESSED_RTP包。
3.2RTP数据包头压缩
在IPv4包头中只有总长度,包ID和校验和字段会发生改变。
因为在链路层已经提供了长度,这里总长度是冗余的,同时由于本压缩方案必须依靠链路层实现良好的错误检测(如PPP的CRC[4]),头校验和也可以省略掉。
于是只剩下了包ID,而在假定没有IP分片的情况下它也无参加通信。
不过为了保持无损压缩,包ID的变化也将被传输。
对每个包而言,包ID通常每次加1或者一个很小的整数值。
(有些系统中包ID的增量为交换的字节数,这对压缩效率有一些轻微的影响。
)而IPv6包头既没有包ID字段,也没有头校验和字段,只有负载长度字段会发生变化。
由于在IP层和链路层均有相应字段,UDP头中的长度字段也是冗余的。
如果选择不产生UDP校验和则UDP的校验和字段为常数0。
否则必须对校验和进行交互通信以保证无损压缩。
一个重要原则就是为需要的应用程序维护端到端的错误检测。
在RTP头中,作为特定环境标识的一部分,给定的环境的SSRC标识符是恒定不变的。
对大多数包而言,只有顺序号和时间戳是因包而异的。
如果没有包丢失或者乱序,顺序号应按步进值1逐包改变。
对音频包,时间戳应按采样周期增加。
对于视频,时间戳在每帧的第一个包是发生改变,而在后面该帧的其它包中保持不变。
如果每个视频帧只占据一个包,且视频帧按照恒定的速率产生,则帧与帧之间时间戳的变化也是恒定的。
注意到每当这种情况出现,顺序号和时间戳字段的二次差分均为0,所以下一个包头的相应字段值可通过前一个未压缩包头的该字段加上存在会话环境一次差分值得到。
当二次差分不为0时,变化量通常也要远小于字段中所有位的数目,所以可通过对新的一次差分进行编码并传输该编码来达到压缩的目的,不用传输绝对值。
一个音频会话峰(talkspurt)中M位将在第一个包中设置,而一个视频帧中M位在最后一个包中设置。
如果它作为一个常量字段则每次变化都要发送整个RTP头,如此会造成压缩效率明显下降。
因此,压缩头中的一位将明确地携带M位。
如果包通过RTP混合器流动,特别是音频数据,则CSRC列表和CC记数将发生改变。
但CSRC列表将在会话峰期间保持不变,所以它只需在发生变化时才发送。
3.3协议
压缩协议必须维护一个状态牢靠的压缩器和解压器的共享信息集合。
对每个IP/UDP/RTP包流都有一个单独的通过源地址IP,目的地址IP,UDP端口对和RTPSSRC字段组合定义的会话环境。
要维护的会话环境数目可通过双方协商而定。
每个环境通过一个8位或者16位的标识符来标识,具体范围要根据协商的环境数量决定,所以最大值为65536。
未压缩和压缩的包都必须携带环境ID和一个4位的用来检测包通信中丢失的顺序号。
每个环境都有自己的顺序号空间,所以单个包的丢失只会影响到一个环境。
每个环境共享的信息包括如下项目
*完整的IP,UDP和RTP头,对最后一个由压缩器发送或者解压器重建的包,可能还包括CSRC表。
*IPv4ID字段的一次差分结果,当收到环境中的一个未压缩IP头时初始化为1,每次收到一个压缩包中的deltaIPv4ID字段时更新。
*RTP时间戳字段的一次差分结果,当收到环境中的一个未压缩IP头时初始化为0,每次收到一个压缩包中的deltaRTP时间戳字段时更新。
*最后一个4位顺序号,用来检测双方通信时的包丢失情况。
*IPv6(见[3])UDP包的非差分编码当前产生号。
对于IPv4,如果没有使用下面定义的COMPRESSED_NON_TCP包类型,则产生号可设置为0。
*一个经过双方协商,可选的环境相关的delta编码表(见3.3.4节)。
为了在不同的压缩和解压器形式下进行通信,本协议依靠链路层为除IPv4和IPv6外的四种新的包格式提供指示:
FULL_HEADER–传送未压缩IP头和任何用来在解压方为特定环境建立未压缩头状态的后续头和数据。
FULL_HEADER包也携带了8或16位的会话环境标识符和4位的顺序号用来建立双方的同步。
格式见3.3.1节。
COMPRESSED_UDP–传送压缩到6字节或更少字节(如禁用UDP校验和则通常为2字节)的IP和UDP头,后面是任何未压缩形式的后续头(可能为RTP)和数据。
当RTP头的常量字段有所不同时才使用包类型。
RTP包头包括一个会变化的SSRC字段值,所以可能重定义会话环境。
其格式在3.3.3节定义。
COMPRESSED_RTP–表示RTP头和IP及UDP头一起压缩。
该头的大小可以是2个字节,或者当需要传送变化时更多一些。
当二次差分值(至少在通常的常量字段)为0时使用包类型。
它包括delta编码,它是为了能在未压缩RTP头发送后并当改变发生时对于那些变化字段建立一次差分队列。
其格式在3.3.2中定义。
CONTEXT_STATE–一种由解压器发送给压缩器的特殊包,用来传输已经或者可能已经失去同步的环境ID。
该包仅通过点到点链路发送,所以它不需要IP头。
其格式在3.3.5中定义。
当本压缩方案作为通用头压缩框架[3]的一部分用于IPv6时,还可使用另一种包类型:
COMPRESSED_NON_TCP–无须进行差分编码传输[3]定义的压缩IP/UDP包。
如果用于IPv4,为了能携带IPv4ID字段,它比前面所讲的COMPRESSED_UDP要多用1到2个字节。
而IPv6没有ID字段,这种非差分压缩在包丢失时更有弹性。
在PPP协议[4]中为这些包格式分配代码应由IANA决定。
3.3.1.FULL_HEADER(未压缩)包格式
此处定义的FULL_HEADER和[3]中所给出的定义是一致的。
在那里有关于各种方案的完整设计细节。
它在IPv4中通常就是一个IP头,后面接着是一个UDP头和UDP负载(可能为一个RTP头及其负载)。
不过,FULL_HEADER也可以携带IP封装的包,其中可能有两个IP头及其相应的UDP和RTP。
对于IPv6,该包还可能是IPv6和IPv4头的组合。
通常每个后续头都由前一个头的类型字段来指示。
FULL_HEADER包与IPv4或IPv6包的区别在于它必须携带压缩环境ID和4位的顺序号。
为了避免头变大,这些值被插入到IP和UDP头的长度字段中,因为实际的长度可以根据链路层提供的长度推算出来。
这里需要2个16位长的字段:
它们来自包中的头两个可用头。
对于IPv4/UDP包,第一个长度字段是IP头总长度字段,第二个字段是UDP头长度字段。
对于IPv4封装包,第一个长度字段为第一个IP头的总长度字段,第二个字段是第二个IP头的总长度字段。
如5.3.2节所规定,环境ID(CID)和4位顺序号的位置取决于是采用8位还是16位环境ID,如下图所示(16位宽,左边为最高位):
对于8位环境ID:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|1|Generation|CID|第一长度字段
|0|seq|第二长度字段
对于16位环境ID:
|1|1|Generation|0|seq|第一长度字段
|CID|第二长度字段
第一长度字段的起始位表示CID的长度。
CID的长度要么对于所有环境均相同,要么必须提供两个额外包类型来分别指示COMPRESSED_UDP和COMPRESSED_RTP包格式采用8位还是16位CID。
对于IP/UDP/RTP压缩方案,第一长度字段的第二位为1表示当前为4位顺序号。
在IPv6的COMPRESSED_NON_TCP包中使用Generation字段方法如[3]所述。
IPv4实现不使用COMPRESSED_NON_TCP包,压缩器应该将generation字段设置为0。
为了使IPv4和IPv6操作一致,当解压器接收到Generation值后就将它存在环境中,并在CONTEXT_STATE包中返回最近的值。
当接收到一个FULL_HEADER时,接收方将整个头存在由环境ID选择的环境中。
4位顺序号也存在环境中,从而可实现解压器和压缩器的同步。
在使用COMPRESSED_NON_TCP包时,顺序号插入到该包的“Data字段”中,并且D位设置参照[3]的第6节所述。
在接收到COMPRESSED_NON_TCP包后,接收方将Generation号和存在环境中的值进行比较。
如果不同,则环境已经过期,需要用该FULL_HEADER包来进行刷新。
如果一致,则压缩的IP和UDP头信息,顺序号,以及RTP头都存入已保存的环境中。
保存环境所需要的内存数量取决于FULL_HEADER中到底封装了多少个头。
最大头的大小可通过压缩/解压缩双方协商得到。
3.3.2.COMPRESSED_RTP包格式
如果包中RTP头的二次差分值为0,则解压器只需在前一个包的未压缩头上加上存储的一次差分值就可以重建该包。
双方之间只需传输会话环境标识符和顺序号就可以维持同步和检测出丢失包。
如果包中RTP头某些字段的二次差分值不为0,则要在双方要传输这些字段的新的一次差分结果的压缩编码。
除了要把新的一次差分值加到解压器会话环境的未压缩头上,也要加到那些二次差分为0的后续包的相应字段上并显式地存储到环境里。
每当一次差分改变时,都要对其进行传输和存储。
在实际应用中,唯一需要用到一次差分的字段就是IPv4ID字段和RTP时间戳字段。
RTP顺序号字段的增量为1。
如果顺序号变化不是1,则必须进行通信以报告该区别,但并不因此为下一个包重新设置期望的变化值。
期望的一次差分值仍然为1,这样如果下一个包按顺序来到就不用再为变化进行通信。
对于RTP时间戳,当发送FULL_HEADER,COMPRESSED_NON_TCP和COMPRESSED_UDP包刷新RTP状态时,存储的一次差分初始化为0。
如果下一个包的时间戳一样(如相同的视频帧),则二次差分值为0。
否则必须将两个包时间戳的差别作为新的一次差分传输并存入环境中,该值将被加到解压器环境存储的未压缩头时间戳上。
每当后续包的一次差分改变时,都要用该变化来更新环境。
类似地,由于IPv4ID字段每次递增1,当用FULL_HEADER刷新状态或以非压缩形式发送携带ID字段的COMPRESSED_NON_TCP包时,该字段的一次差分初始化为1。
然后,每当一次差分改变其变化都会重传并存到环境中。
这里还用了一个掩蔽码来表示哪个字段发生了非预期变化。
除了小链路顺序号外,要在压缩的IP/UDP/RTP头中进行传输的项列表如下:
I=IPv4包ID(非IPv4头为常数0)
U=UDP校验和
M=RTP标志位
S=RTP顺序号
T=RTP时间戳
L=RTPCSRC记数和列表
如果用4位作为链路顺序号来进行丢失检测,包头中就没有足够的位逐一分配给上面的几项并填充到一个单字节中随环境ID发送。
因为发送源要么在会话中所有的包里包括UDP校验和,要么就根本不用校验和,所以没必要显式地携带U位表示UDP校验和的存在。
如果以未压缩包头初始化会话状态时其校验和非0,就说明在所有的后续压缩包中都将插入16位的未编码校验和,直到发送了另一个未压缩包改变该设置。
对于剩余的几项,用于CSRC记数和列表的L位可能是使用频率最低的。
与其专门在掩蔽码中用一位来表示CSRC改变,还不如采用另外一种不常用的位组合。
该位组合称为MSTI。
如果IP包ID,RTP标志位,RTP顺序号和RTP时间戳的位都已经被使用,这种特殊情况表示其后可能有一种扩展形式的压缩RTP包头。
该包头将包括一个额外字节,其中含有4位加上CC记数的实际值。
当CSRC列表(长度由CC记数表示)出现在未压缩RTP头中时也将被包含其中。
假设RTP头中的其余字段(版本,P位,X位,负载类型和SSRC标识符)都保持相对恒定。
特别地,对于给定的环境SSRC标识符定义为常量,因为SSRC标识符是选择环境的一个因素。
如果任何其它字段发生变化,都必须按照3.3.3节要求发送未压缩RTP包。
下图中,带点划线的压缩IP/UDP/RTP头表示可选字段。
最高位为0。
多字节字段按照网络字节顺序发送(最高字节在先)。
Delta字段通常如图所示为单字节,但根据具体delta值也可能为2或3字节,如3.3.4节所解释。
01234567
+...............................+
:
会话环境ID的msb:
(如果使用16位CID)
+-------------------------------+
|会话环境ID的lsb|
+---+---+---+---+---+---+---+---+
|M|S|T|I|链路顺序号|
+UDP校验和+(如果环境中校验和为非0)
+"
RANDOM"
fields+(如果被封装)
M'
|S'
|T'
|I