摘要

  • IPComp 对每个 IP 数据报独立、无损地压缩;因为报文可能乱序或丢失,接收方不能依赖前一个报文的字典,并且必须同时接受压缩包与原始包。
  • 非扩张规则把优化变成硬边界:若压缩载荷加上四字节 IPComp 头不比原载荷小,发送方必须发送原始形式,不能附加 IPComp 头。
  • CPI 是由解压方选择、结合目的地址解释的方向性索引,不是凭据或全局算法身份证。协商只证明能力存在,不能证明某个报文实际压缩、成功解压或获得净收益。

同一条关联里可以没有 108

人们习惯把协议协商理解成开关:开了,抓包里就应该一直看到相应头部;没看到,就是配置失败。IPComp 恰好把这种推断拆开。节点可以拥有有效的 IPComp Association,而某个报文的 IPv4 Protocol 或 IPv6 Next Header 仍然不是 108,因为这个报文被正确地以原始形式发送了。

这不是异常回退,而是规范要求。关联回答“如果压缩包到来,接收方怎样还原”;它不回答“每个包都必须变成压缩包”。压缩是否划算取决于眼前字节:重复结构可能明显变小,极短控制包可能变大,已经在应用层压缩过的内容可能只消耗 CPU 而不省空间。

加密之前,压缩才看得到结构

RFC 2393 在 1998 年提出 IPComp,出发点之一就是 IPsec。加密会让数据呈现近似随机的形态,到了下层再压缩,通常已无重复结构可利用。因此需要两者时,压缩必须先发生,加密和认证随后发生。

处理顺序也由此固定。出站先压缩,再进行 IP 安全处理,最后才允许分片;入站则先重组分片并完成认证、解密,之后才解压。压缩器面对原始载荷,解压器只有在外层保护完成后才接触被压缩的内容。

IPv4 外层头和选项不参与压缩;若采用隧道模式,内层 IP 头属于外层载荷,可以进入压缩范围。IPv6 中需要沿途节点检查的头部留在外面,Fragment Header 与 IPComp 同时出现时,前者必须排在 IPComp 之前。

这正是“最小初始规范”的价值:共同层只规定无损、顺序、边界与识别方法,不替本地实现决定未来每个数据报是否值得压缩。

每个数据报都必须从零开始

IPComp 在报文之间无状态。每个包自己携带足以独立解压的结果,不能借用前一个包的字典。原因不是追求简单,而是尊重 IP 的现实:前一包可能晚到,也可能永远不到。

因此一次成功不能成为下一次的授权。第 41 包压得很好,不代表第 42 包也应该带 IPComp。实现可以利用近期失败来节省计算,但这只是本地策略。RFC 3173 允许连续若干次压缩失败后暂时跳过一些报文,再恢复测试;也允许算法在处理中判断不可压缩而提前退出。连续次数、跳过长度和判断阈值都不进入共同头部。

DEFLATE 的 RFC 2394 给出一个具体建议:基于非正式测试,不应尝试压缩小于 90 字节的缓冲区。90 不是 IPComp 的全球常数,更不是对所有算法、CPU、链路和流量都适用的分界线。它只说明性能选择应由运行环境承担。

四字节开销也必须参加比较

非扩张规则比较的不是“压缩载荷是否比原载荷短”,而是“压缩载荷加四字节 IPComp 头是否更短”。若答案是否定的,报文必须原样发送,不添加 IPComp 头。

这条规则同时保护计算与 MTU。没有节省就不让接收端白做解压,也不允许一个原本能装进路径 MTU 的报文,因为尝试优化反而变大并触发分片。

于是,抓包中的缺席变得多义。没有 108,可能因为报文低于阈值,可能被自适应计数器跳过,可能被快速判定为不可压缩,也可能压过但连头计算后不省字节。仅凭线上报文不能还原哪一个本地分支发生了。

反过来,看到报文变短也不等于获得净收益。省下的字节可能抵不过 CPU、排队和时延。压缩率也不能证明内容类型、拥塞改善或业务价值。IPComp 保证无损复原和不把压缩结果扩张到线上,不保证任何链路上都更快。

CPI 是本地索引,不是算法身份证

真正压缩时,外层 Protocol 或 Next Header 变为十进制 108。四字节 IPComp 头保存原来的 Next Header、一个保留 Flags 字节和 16 位 Compression Parameter Index。解压成功后,接收方删除 IPComp 头,恢复原 Next Header,把原载荷送回正常协议分派路径。

CPI 容易被误读成算法的全球编号。实际上,0 至 63 是知名变换,另有协商区间和私用区间。两个方向可以独立选择 CPI;发送方必须使用解压方为入站方向选择的值。CPI 与目的地址结合,才标识这个报文需要的压缩特征。

同一个数值在另一个目的上下文里可以有不同意义。如果两个会话复用同一个知名 CPI,而寿命或自适应计数又不同,关联甚至会失去唯一性。RFC 3173 因而建议在需要区分时使用协商区间。数值是查表输入,不是授权记录,更不提供认证。

没有默认算法,也没有压缩的隐形惯例

IPComp Association 保存 CPI、模式、算法及必要参数。策略可以覆盖节点之间所有报文,也可以只覆盖选定会话。两个方向可以采用不同算法。

规范明确没有默认压缩算法,也没有每个 IPComp 实现都必须支持的算法。双方必须显式找到共同选择,不能因为都写着“compression”就假定一定是 DEFLATE。

RFC 3173 主要修订了 IKE/IPsec 场景下的协商细节。后来的 IKEv2 延续了边界:请求方可以提出多个算法,响应最多接受一个;实现不得使用没有提出并被接受的算法。虚拟压缩关联也没有独立于 ESP 或 AH Child SA 的生命,Child SA 消失时它随之消失,不另发 Delete。

但共享寿命不等于共享能力。IKEv2 仍把压缩协商与密码参数协商分开。CPI 不是加密密钥,接受 IPComp 也不证明某个报文已经认证。

把内容折叠,也会改变谁能看见什么

不配合 IPsec 使用时,IPComp 可能让边界设备失去原有的过滤或计费依据。原 Protocol 值被移进 IPComp 头,端口等传输层字段则变成压缩字节。没有共享关联的设备,无法按原位置直接读取它们。

这并不意味着压缩提供保密性。问题是解析权:中间设备缺少恢复策略字段所需的状态。若环境要求每个包都可过滤或可计量,RFC 3173 要求以安全方式把相关 IPComp Association 传给过滤设备。

运维记录至少应拆成六件事:策略已配置、关联已接受、某包进入尝试、结果值得带头、接收端查到正确关联、载荷成功还原。把它们压成一个“已启用压缩”,会同时掩盖合法的原样发送和真正的失配。

IPComp 留下的历史价值,正是把优化置于运行数据之下。共同协议提供理解压缩结果的最小条件;至于这一次是否值得,报文本身保留否决权。

来源