10. Header Compression (Header-Kompression)
关于报文头压缩有大量已发布和正在进行的标准化工作. 然而, IPv6 over IEEE 802.15.4 的报文头压缩具有不同的约束, 总结如下:
-
现有工作假设任意两个设备之间有许多流 (Flows). 这里, 我们假设一种非常简单和低上下文 (Low-Context) 的报文头压缩风格. 虽然这独立于流工作 (可能有多个), 但它不使用任何特定于任何流的上下文. 因此, 它无法实现为每个要压缩的流构建单独上下文的方案所能达到的压缩程度.
-
鉴于数据包大小非常有限, 高度期望将第 2 层与第 3 层压缩集成, 这是传统上没有做的 (尽管现在由于 ROHC (RObust Header Compression, 鲁棒报文头压缩) 工作组而正在改变).
-
预计 IEEE 802.15.4 设备将部署在多跳网络 (Multi-Hop Networks) 中. 然而, 网状网络中的报文头压缩与通常的点对点链路场景不同, 在该场景中, 压缩器和解压缩器彼此直接和独占通信. 在 IEEE 802.15.4 网络中, 高度期望设备能够通过其任何邻居发送报文头压缩的数据包, 并尽可能少地进行初步的上下文构建.
报文头压缩所需的任何新数据包格式通过使用不同的分派值 (Dispatch Values) 重用第 5 节中定义的基本数据包格式.
报文头压缩可能导致对齐不落在八位字节边界上. 由于硬件通常无法以小于八位字节的单位传输数据, 因此必须使用填充 (Padding). 填充按如下方式完成: 首先, 排列整个连续压缩报文头系列 (本文档仅定义 IPv6 和 UDP 报文头压缩方案, 但其他方案可以在其他地方定义). 然后, 根据需要添加零比特以对齐到八位字节边界. 这抵消了报文头压缩造成的任何潜在未对齐, 因此后续字段 (例如, 未压缩的报文头或数据有效载荷) 从八位字节边界开始并按常规进行.
10.1. Encoding of IPv6 Header Fields (IPv6报文头字段的编码)
通过加入同一个 6LoWPAN 网络, 设备共享一些状态. 这使得无需显式构建任何压缩上下文状态即可压缩报文头. 因此, 6LoWPAN 报文头压缩不保留任何流状态; 相反, 它依赖于与整个链路相关的信息. 以下 IPv6 报文头值预计在 6LoWPAN 网络上很常见, 因此 HC1 报文头被构造为从一开始就有效地压缩它们:
- Version (版本) 是 IPv6
- IPv6 源地址和目标地址都是链路本地的 (Link Local)
- 源或目标地址的 IPv6 接口标识符 (底部 64 位) 可以从第 2 层源和目标地址推断 (当然, 这仅对从底层 802.15.4 MAC 地址派生的接口标识符可能)
- 数据包长度可以从第 2 层 (IEEE 802.15.4 PPDU 中的 "Frame Length") 或分片报文头中的 "datagram_size" 字段 (如果存在) 推断
- Traffic Class 和 Flow Label 都为零
- Next Header 是 UDP, ICMP 或 TCP
IPv6 报文头中唯一始终需要完整承载的字段是 Hop Limit (跳数限制, 8 位). 根据数据包与这种常见情况的匹配程度, 不同的字段可能无法压缩, 因此需要 "内联" (In-Line) 承载 (第 10.3.1 节). 这种常见的 IPv6 报文头 (如上所述) 可以压缩到 2 个八位字节 (1 个八位字节用于 HC1 编码, 1 个八位字节用于 Hop Limit), 而不是 40 个八位字节.
这样的数据包可以通过 LOWPAN_HC1 格式压缩, 方法是使用 LOWPAN_HC1 的分派值, 后跟 LOWPAN_HC1 报文头 "HC1 编码" 字段 (8 位) 来编码如下所示的不同组合.
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| HC1 encoding | Non-Compressed fields follow...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图 9: LOWPAN_HC1 (常见压缩报文头编码)
由 "HC1 编码" 编码的地址字段解释如下:
- PI: Prefix carried in-line (前缀内联承载)
- PC: Prefix compressed (前缀压缩, 假定链路本地前缀)
- II: Interface identifier carried in-line (接口标识符内联承载)
- IC: Interface identifier elided (接口标识符省略, 可从相应的链路层地址派生)
HC1 编码 (从比特 0 到比特 7):
IPv6 源地址 (比特 0 和 1):
00: PI, II01: PI, IC10: PC, II11: PC, IC
IPv6 目标地址 (比特 2 和 3):
00: PI, II01: PI, IC10: PC, II11: PC, IC
Traffic Class 和 Flow Label (比特 4):
0: 未压缩; 发送完整的 8 位 Traffic Class 和 20 位 Flow Label1: Traffic Class 和 Flow Label 为零
Next Header (比特 5 和 6):
00: 未压缩; 发送完整的 8 位01: UDP10: ICMP11: TCP
HC2 编码 (比特 7):
0: 没有更多报文头压缩比特1: HC1 编码紧接着根据 HC2 编码格式的更多报文头压缩比特. 比特 5 和 6 确定哪些可能的 HC2 编码适用 (例如, UDP, ICMP 或 TCP 编码).
10.2. Encoding of UDP Header Fields (UDP报文头字段的编码)
LOWPAN_HC1 的比特 5 和 6 允许压缩 IPv6 报文头中的 Next Header 字段 (用于 UDP, TCP 和 ICMP). 还可以进一步压缩这些协议报文头中的每一个. 本节解释如何压缩 UDP 报文头本身. 本节中的 HC2 编码是 HC_UDP 编码, 它仅在 HC1 中的比特 5 和 6 指示 IPv6 报文头后面的协议是 UDP 时适用.
HC_UDP 编码允许压缩 UDP 报文头中的以下字段: 源端口 (Source Port), 目标端口 (Destination Port) 和长度 (Length). UDP 报文头的校验和 (Checksum) 字段不压缩, 因此完整承载. 下面定义的方案允许将 UDP 报文头压缩到 4 个八位字节, 而不是原始的 8 个八位字节.
唯一可以从其他地方可用的信息推断其值的 UDP 报文头字段是 Length. 其他字段必须完整或以部分压缩的方式内联承载 (第 10.3.2 节).
1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|HC_UDP encoding| Fields carried in-line follow...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图 10: HC_UDP (UDP常见压缩报文头编码)
UDP 的 "HC_UDP 编码" (从比特 0 到比特 7):
UDP 源端口 (比特 0):
0: 未压缩, 内联承载1: 压缩到 4 位. 实际的 16 位源端口通过计算获得: P + short_port 值. P 的值是数字 61616 (0xF0B0). short_port 表示为 4 位值, 内联承载
UDP 目标端口 (比特 1):
0: 未压缩, 内联承载1: 压缩到 4 位. 实际的 16 位目标端口通过计算获得: P + short_port 值. P 的值是数字 61616 (0xF0B0). short_port 表示为 4 位值, 内联承载
Length (比特 2):
0: 未压缩, 内联承载1: 压缩, 长度从 IPv6 报文头长度信息计算. UDP 长度字段的值等于 IPv6 报文头的 Payload Length, 减去 IPv6 报文头和 UDP 报文头之间存在的任何扩展报文头的长度
保留 (比特 3 到 7)
10.3. Non-Compressed Fields (未压缩字段)
10.3.1. Non-Compressed IPv6 Fields (未压缩的IPv6字段)
此方案允许 IPv6 报文头被压缩到不同程度. 因此, 仅需要发送未压缩的字段, 而不是整个 (标准) IPv6 报文头. 后续报文头 (由原始 IPv6 报文头中的 Next Header 字段指定) 紧接在 IPv6 未压缩字段之后.
muss (MUST) 始终存在的未压缩 IPv6 字段是 Hop Limit (8 位). 此字段必须 (MUST) 始终跟随编码字段 (例如, 如图 9 所示的 "HC1 编码", 可能包括其他未来的编码字段). 其他未压缩字段必须 (MUST) 按照 "HC1 编码" 所暗示的顺序跟随 Hop Limit, 与上面 (第 10.1 节) 所示的顺序完全相同: 源地址前缀 (64 位) 和/或接口标识符 (64 位), 目标地址前缀 (64 位) 和/或接口标识符 (64 位), Traffic Class (8 位), Flow Label (20 位) 和 Next Header (8 位). 实际的下一个报文头 (例如, UDP, TCP, ICMP 等) 跟随未压缩字段.
10.3.2. Non-Compressed and Partially Compressed UDP Fields (未压缩和部分压缩的UDP字段)
此方案允许 UDP 报文头被压缩到不同程度. 因此, 仅需要发送未压缩或部分压缩的字段, 而不是整个 (标准) UDP 报文头.
UDP 报文头中的未压缩或部分压缩字段必须 (MUST) 始终跟随 IPv6 报文头及其任何相关的内联字段. 存在的任何 UDP 报文头内联字段必须 (MUST) 以与正常 UDP 报文头 [RFC0768] 中相应字段出现的相同顺序出现, 例如, 源端口, 目标端口, 长度和校验和. 如果源端口或目标端口采用 "short_port" 表示法 (如压缩的 UDP 报文头所示), 则内联端口号取 4 位而不是 16 位.