RObust Header Compression (ROHC): Corrections and Clarifications to RFC 3095
updates
- rfc-3095 — RObust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed
- rfc-3241 — Robust Header Compression (ROHC) over PPP
- rfc-3843 — RObust Header Compression (ROHC): A Compression Profile for IP
- rfc-4019 — RObust Header Compression (ROHC): Profiles for User Datagram Protocol (UDP) Lite
- rfc-4362 — RObust Header Compression (ROHC): A Link-Layer Assisted Profile for IP/UDP/RTP
Extracted elements (30)
Two separate interpretation interval values (p) exist for TS encoding: for timer-based compression (TIME_STRIDE ≠ 0), p = 2^(k-1) − 1 as per RFC 3095 Section 4.5.4; otherwise p = 2^(k-2) − 1 as per RFC 3095 Section 5.7. RFC 3095 was ambiguous about which value to use; the choice depends on whether timer-based compression is active.
RFC 3095 did not specify the CRC algorithm for 3-, 7-, and 8-bit CRCs. RFC 4815 clarifies that all three CRC widths are calculated using the algorithm defined in RFC 1662 (PPP in HDLC-like Framing). A Perl reference implementation is provided in Appendix A.
RFC 3095 only defined TS decompression when TS bits are present, omitting the case where no TS bits appear in the compressed header. RFC 4815 adds that when no TS bits are received, the scaled TS is reconstructed by linear extrapolation: delta_TS = delta_SN * default-slope(TS). If Tsc=0 and no TS bits are present, the decompressor MUST discard the packet.
RFC 3095 Section 5.7.5 was ambiguous about how the R-P (RTP Padding) bit is updated in the context via Extension 3. The corrected rule: if R-PT=1, R-P carries the absolute RTP padding bit value and updates context(R-P); if R-PT=0, context(R-P) is updated to zero regardless.
RFC 3095 Section 5.7.7.6 was unclear about how the RTP X (eXtension) bit is updated via the dynamic chain. The corrected rule: if RX=1, X carries the RTP header X bit value and updates context(X); if RX=0, context(X) is updated to zero.
RFC 3095 Section 5.9.1 incorrectly stated that the IR/IR-DYN CRC covers the entire packet excluding payload and including any Add-CID octet. The corrected text excludes Padding octets and the Add-CID octet for CID 0 from CRC calculation.
RFC 3095 Sections 5.8.4.2 and 5.8.4.4 incorrectly described AH and GRE sequence number omission as requiring linear increase relative to RTP SN. The corrected rule mirrors the ESP profile: the AH or GRE sequence number may be omitted only when the offset from the compressed header SN is constant and the compressor is confident the decompressor has established the correct offset.
The CRC feedback option (RFC 3095 Section 5.7.6.3) was incomplete: the 8-bit CRC over the feedback payload must exclude the packet type, the 'Size' field, and the 'Code' octet—not just the packet type and code octet as previously stated. The 'Size' field is an extension of 'Code' and must be treated identically.
The RFC 3095 scaled TS compression formula 'TS_SCALED = TS / TS_STRIDE' was incorrect because it excluded TS_OFFSET and prohibited TS_STRIDE=0. The corrected algorithm: (1) send TS_STRIDE and an unscaled TS for initialization; (2) compress TS_SCALED; (3) decompress as TS = TS_SCALED * TS_STRIDE + TS_OFFSET; (4) on TS wraparound when TS_STRIDE is not a power of two, compressor SHOULD reinitialize TS_OFFSET by sending unscaled TS.
RFC 3095 Section 4.5.3 required the decompressor to detect and handle TS wraparound internally for scaled encoding. This was deemed non-interoperable and non-robust; the corrected algorithm instead requires the compressor to reinitialize TS_OFFSET by sending an unscaled TS at wraparound, eliminating the decompressor-side wraparound detection requirement.
After ROHC channel negotiation, the agreed PROFILES parameter MUST NOT include more than one variant of any given profile. Since only the 8 LSB bits of a 16-bit profile identifier appear in compressed headers, the compressor and decompressor must have agreed unambiguously on which variant to use.
All feedback sent by the decompressor during a mode transition MUST be protected by the CRC option. The compressor MUST ignore feedback related to mode transitions if the feedback is not CRC-protected.
An established decompressor context with a CID within the negotiated MAX_CID space MUST be kept by the decompressor until the CID is reused, the channel is taken down, or the channel is renegotiated. The decompressor implicitly agrees to provide memory for at least MAX_CID+1 contexts.
An implementation of ROHC-over-PPP (RFC 3241) MUST ensure the same profile set is negotiated for both IPv4 (IPCP) and IPv6 (IPV6CP). The PROFILES sub-option cannot use logical union across IPCP/IPV6CP negotiations, as this would produce an ambiguous profile set.
During mode transition when D_TRANS=I, a decompressor in R-mode MUST use the sequence number of the packet that last updated the context (not R-0 or R-1* packets) when sending acknowledgements, since R-0 and R-1* do not carry CRCs and thus do not update context.
For list encoding types 1 (insertion), 2 (removal), and 3 (removal/insertion), the ref_id field MUST refer to a non-empty reference list, regardless of operating mode. Using these encoding types with an empty reference list is prohibited.
IR packets update only the fields they carry, not the entire context. Fields not updated by an IR (e.g., list compression translation tables) MUST NOT be invalidated by the decompressor when it assumes context damage.
The compressor MUST set both occurrences of the CC field (one in the RTP dynamic chain header, one inside the Generic CSRC list Encoding Type 0) to the same value. The decompressor MUST use the CC value from the Encoding Type 0 inside the Generic CSRC list and MUST ignore the first occurrence.
The CRC coverage for the ESP NULL header (RFC 3095 Section 5.8.7) must be interpreted as covering only the initial SPI and sequence number fields, not the trailer part at the end of the payload—identical to the coverage for the regular ESP header profile.
UO-1-ID packets update only TS, SN, IP-ID, and sequence numbers of IP extension headers; other extension field values do not update the context. The decompressor MUST still update its translation table whenever an (Index, item) pair is received, even in UO-1-ID packets.
When a 7-bit bit mask is used in list compression and the reference list has more than seven items, the decompressor MUST NOT modify items with an index not covered by the 7-bit mask; only items within the first seven positions may be changed.
When a CID is reused for a context based on a different profile, both compressor and decompressor MUST start operation in that profile's initial mode. A CID currently in R-mode SHOULD NOT be reused for a different profile due to the risk of packet type misinterpretation if the initiating IR packets are lost.
When multiple CRC options appear in a feedback packet, all such options MUST be identical (they are computed over the same header); the compressor MUST discard the feedback packet if any CRC options differ.
When multiple non-identical IP extension headers of the same type appear in a header chain, each MUST be assigned its own list compression index. When a shared index appears multiple times and its value is updated, the compressor MUST transmit the updated value for every occurrence of that index.
When the compressor receives a NACK and uses UOR-2 to repair context, it SHOULD include TS_STRIDE and TIME_STRIDE fields that it has updated since context establishment. When the compressor receives a static-NACK, it MUST include in the IR header both TS_STRIDE and TIME_STRIDE values it has ever updated for that context.
When there are two M (RTP Marker) bit fields in a compressed header (in both base header and Extension 3 RTP part), the compressor MUST set both to the same value. If a decompressor receives a packet where the two M field values differ, the packet MUST be discarded.
When TS_STRIDE is present in Extension 3 (Tss=1) along with scaled TS (Tsc=1), the decompressor MUST ignore and discard field(TS_STRIDE), because unscaled TS is required to correctly recalculate TS_OFFSET. Scaled TS always uses context(TS_STRIDE), not value(TS_STRIDE) as RFC 3095 Section 5.7.5 incorrectly stated.
Whenever a compressed packet carrying an unscaled TS value is received, the decompressor MUST recalculate TS_OFFSET (= RTP TS modulo TS_STRIDE) to ensure correct decompression of subsequent packets, even when TS_STRIDE itself has not changed.
RFC 4815 introduces no changes to the security properties of ROHC. The security considerations of RFC 3095 apply without additions, as this document provides only corrections and clarifications to protocol behavior.
The D_TRANS decompressor transition parameter is extended to include a PENDING (P) state in addition to INITIATED (I) and DONE (D). While D_TRANS=P, the decompressor need not send feedback for every packet but MUST continue sending feedback periodically with the CRC option, preventing deadlocks during mode transitions with sparse feedback.