摘要

  • comp=sigcomp 放在下一跳 URI 时支配请求,放在最上层 Via 时支配响应,放在 Contact 或 Record-Route 时又影响后续消息;同一场对话可以逐跳、分方向采用不同编码。
  • 这个标记同时表达“支持”与“此刻愿意接收”。它不证明线上确实发送了压缩字节,更不证明 SIP 已解析、消息已送达、对端已认证或会话已建立。

理解 RFC 3486,最重要的不是先问“是否开启 SigComp”,而是问“哪一个字段正在决定下一次动作”。请求要看下一跳 SIP 或 SIPS URI;响应要看最上层 Via;对话内未来的请求,则可能由 Contact、Route 和 Record-Route 共同塑造。标记的拼写不变,权限边界却随着消息方向和路由位置移动。

这套设计源于组合爆炸。SIP 客户端原本可通过 NAPTR 与 SRV 发现 UDP、TCP 或 SCTP。若再为传输、TLS 与压缩的每一种组合分别建立 DNS 记录,两个传输加上安全与压缩就会迅速产生多种条目。RFC 3486 因而把压缩意愿放到应用层。普通 SIP 与 SigComp 消息可以抵达同一端口,接收方根据压缩消息开头的 cookie 位进行分流。

规范选择了很短的语法:comp=sigcomp。它出现在 URI 中,表示发往那个下一跳的请求应当使用 SigComp;它出现在最上层 Via 中,表示响应应当压缩后返回。只记录字符串而不记录它所在的字段、方向与对应接收方,就已经丢失了规范赋予它的主要含义。

更关键的是,这个参数并非单纯的能力声明。RFC 3486 明确把“支持”与“愿意接收”绑在一起。某个实体可能实现了 SigComp,却不愿在当前时刻或当前路径上承受解压处理。实现能力不是永久授权,接收方可以通过是否公布参数来影响发送方的选择。

因此规范划出一条硬边界:客户端不知道下一跳服务器是否支持 SigComp 时,不得发送压缩请求。不过,它可以先发送一条未压缩请求,同时在自己的最上层 Via 中放入该参数。若服务器具备能力,就可以返回压缩响应。去程没有压缩,不妨碍回程获得独立许可;一个方向的事实不能替另一个方向作证。

首个 INVITE 又带来启动难题。此时对话尚未形成 Route 集合,客户端却最希望尽早减少等待。RFC 3486 允许手工配置,也允许先向出站代理发送未压缩的 OPTIONS。代理可在 200 响应的 Contact 中给出带参数的替代 URI。这个响应只证明代理提供了一条可供后续使用的路线,不能证明下一条请求实际选用了它,更不能证明线上字节已经压缩。

对话建立后,Contact 与 Record-Route 把偏好带入未来。希望接收后续压缩请求的用户代理在 Contact 中加入参数;希望留在信令路径上的代理在 Record-Route 中表达自身位置。响应返回时,代理查看上游的下一跳,再决定在自己的 Record-Route 条目中增加还是删除参数。后续路由由这些局部决定重写,并不是首个 INVITE 一次性赋予的全局属性。

RFC 中的示例把这种非均匀性画得很清楚。四个 SIP 元素参与交互,多处支持压缩,但只有编号 1、6 与 7 的消息被压缩。第一个代理收到压缩 INVITE,却向下一个代理发送普通 INVITE;响应先经过未压缩链路,再根据最上层 Via 压缩到客户端;ACK 到某个代理时压缩,转发给服务器时又恢复普通形式。同一对话同时包含多套局部现实。

双重 Record-Routing 也不会把它们统一。位于两张网络之间、像防火墙一样工作的代理,可以为两个接口各放一条路由记录,以避免返回时重写。即便如此,它仍可从一侧接收压缩消息、向另一侧发送普通消息。如果发现下一跳就是自己、消息根本不离开设备,即使 URI 带有参数,也可以不做无意义的压缩。

失败路径留下更尖锐的证据断层。一个不理解 SigComp 的服务器可能连压缩请求中的 Via 都解析不到,于是没有地址可回送正常 SIP 错误。客户端看到的只是事务超时。RFC 3486 规定此后应以未压缩形式重试同一请求,但这项恢复规则并没有把“沉默”变成“对端确定不支持”的诊断结论。丢包、响应丢失或其他故障仍可能产生相同外观。

TCP 的恢复边界更严格。客户端应关闭承载压缩请求的旧连接,再建立新连接发送未压缩请求。若继续使用原字节流,不理解 SigComp 的服务器可能无法识别新 SIP 消息从哪里开始。第一次尝试、超时、未压缩重试与新连接,是四个应分别保留的事件。

这个标记也不会认证插入者。攻击者若能篡改消息、加入 comp=sigcomp,就可能诱使某个实体向不支持的接收方发送压缩数据,所以规范要求适当的完整性机制。解压还比单纯解析普通 SIP 多消耗一些处理资源,使拒绝服务压力略有增加。参数传递的是指令,不是身份凭证。

IANA 登记 comp 与 sigcomp,只是稳定命名。RFC 3320 定义 SigComp 解压架构,RFC 3485 固定 SIP/SDP 静态字典;RFC 5049 后来更新 SIP/SigComp 绑定,补充资源下限、compartment 与状态管理,同时继续依赖 RFC 3486 的发现机制。RFC 4077、RFC 4896、RFC 5112 与 RFC 5626 又处理其他边界。标准谱系不等于部署统计。

因此,重建一次真实交互时,应先保存精确的下一跳 URI、最上层 Via、Contact、Route 与 Record-Route,保存参数完整性、消息方向、线上编码、传输与连接身份。OPTIONS 发现要与后续使用分开;发生沉默时,要另存超时、未压缩重试以及 TCP 是否重开。只有在这些局部凭据齐全之后,才能拼接解压结果、SIP 解析、认证、对话状态与用户可见结果。

按照 Heng Lu 对声明层与结果层的区分,comp=sigcomp 最多建立了一项局部试用许可。它解决了无需扩张 DNS 组合即可协商压缩的问题,却没有把路径变成同质管道。RFC 3486 的历史价值,恰恰在于它把能力、意愿与执行限制在可追问的下一跳。

来源