Repository navigation
fix(hip): correct 7 HIP parameter wire defects - #2400
Conversation
…2281, #2282, #2283, #2299) Seven independent RFC-level defects in HIP parameter makers and readers, fixed together since all seven edit pcapkit/protocols/internet/hip.py: - #2271: TRANSACTION_ID/OVERLAY_ID lost their leading zero octets on rebuild, since len was sized from the integer's own bit_length rather than the wire width. A new id_len field keeps the original width; a new shared HIP._make_identifier_width helper sizes from it, falling back to bit_length only when building from scratch (mirrors #653's _make_puzzle_field_width). - #2275: HIP_TRANSFORM's maker had no version gate, though its reader rejects a HIPv2 parameter. Added the matching ProtocolError. - #2276: LOCATOR_SET's maker set len=5 for an spi= locator but left type=0, a combination locator_value_selector itself rejects. type now defaults to None and is derived from whether spi is given (1 with spi, else 0); an explicitly contradicting type raises naming both values. - #2281: REG_INFO/REG_REQUEST/REG_RESPONSE lifetimes read as raw seconds via timedelta(seconds=octet); RFC 8003 section 4.1 defines a non-zero octet as 2**((v-64)/8) seconds and 0 as a dedicated zero case. New _read_registration_lifetime/_make_registration_lifetime/ _make_lifetime_octet mirror PUZZLE's #1323 precedent; makers take either a duration or a raw exponent, and the raw octet stays the round-trip source on the data models. - #2282: OVERLAY_TTL's ttl parsed as a timedelta, though RFC 6079 defines it as a hop count. ttl is now a plain int throughout schema/data/maker. - #2283: CERT's group decoded through the DH Group registry, though RFC 8002 section 2 defines no such registry for it. cert_group is now a plain int (UInt8Field), decode-side enum lookup dropped. - #2299: HOST_ID's maker prefixed errors "[HIPv2]" instead of the house "HIPv{version}: [ParamNo {code}]" form used elsewhere. Breaking data-model and signature changes carry versionchanged:: 1.5.0 notes. Tests: new tests/protocols/internet/test_hip_wire_semantics_unit.py (15 tests, fail-without-fix verified for 14 of them against origin/main; the 15th is a deliberate no-regression control). tests/protocols/internet/ test_hip_unit.py updated for the three issues it pinned the old wrong semantics for. tests/project/test_rfc_constants_one_home_1739_unit.py gains a 65535 UNRELATED allowance matching schema/internet/hip.py's existing entry, since the new id_len field's two-octet Length bound collides with the homed IP_MAX_LENGTH constant.
7b6f167 to
e99e058
Compare
|
Review: GOOD TO GO at Two real, small corrections applied in this amend (both prose-only, verified against the suite afterward):
Also folded the review's flooring finding into judgment call #2: round-tripping a decoded Non-blocking, not acted on (flagging for visibility): #2276's |
|
Coverage: 91.67% (unit tier, Python 3.15,
Per-file detail: the |
make testpasses, and a test case covers the changeWhat is the purpose of your pull request?
fix — bug fixDescription
Closes #2271. Closes #2275. Closes #2276. Closes #2281. Closes #2282. Closes #2283. Closes #2299.
Seven independent RFC-level defects, fixed together since all seven edit
hip.py:TRANSACTION_ID/OVERLAY_IDlost their leading zero octets on rebuild —lenwas sized from the integer's ownbit_lengthrather than the wire width. A newid_lenfield keeps the original width; a sharedHIP._make_identifier_widthhelper sizes from it, falling back tobit_lengthonly when building from scratch (mirrors Re-serialising a parsed HIP PUZZLE or SOLUTION loses leading zero octets: a len=20 parameter rebuilds as len=6 #653's_make_puzzle_field_width).HIP_TRANSFORM's maker had no version gate, though its reader rejects a HIPv2 parameter. Added the matchingProtocolError.LOCATOR_SET's maker setlen=5for anspi=locator but lefttype=0, a combinationlocator_value_selectoritself rejects.typenow defaults toNoneand is derived from whetherspiis given; an explicitly contradictingtyperaises naming both values.REG_INFO/REG_REQUEST/REG_RESPONSElifetimes read as raw seconds viatimedelta(seconds=octet); RFC 8003 §4.1 defines a non-zero octet as2**((v-64)/8)seconds and0as a dedicated zero case. New helpers mirrorPUZZLE's fix(hip): PUZZLE lifetime as a timedelta cannot round-trip most exponents #1323 precedent; makers take either a duration or a raw exponent, and the raw octet stays the round-trip source.OVERLAY_TTL'sttlparsed as atimedelta, though RFC 6079 defines it as a hop count.ttlis now a plainintthroughout schema/data/maker.CERT'sgroupdecoded through the DH Group registry, though RFC 8002 §2 defines no such registry for it.cert_groupis now a plainint.HOST_ID's maker prefixed errors[HIPv2]instead of the houseHIPv{version}: [ParamNo {code}]form used elsewhere.Breaking data-model/signature changes carry
versionchanged:: 1.5.0notes.Judgment calls flagged for a second look:
REG_INFO's default max-lifetime wire octet moves from0x0fto0x5f, since the maker's numeric default (15) is now read as 15 seconds (encoding to octet0x5f, ~14.67s) rather than copied as the raw octet0x0f(~14.3ms). RFC 8003 §5 sets a 10s MUST-floor on this value, which0x0f's ~14.3ms violated and0x5f's ~14.67s satisfies — the new default happens to be more RFC-correct, though that wasn't the point of the change.timedeltastraight back into the maker is lossier still — 103 of 255 non-zero octets land one octet low (e.g. 127 → 126, 255 → 254), from float/microsecond rounding compounding the floor, not from the RFC itself.(type == 1) != (spi is not None)) meanstype=2with anspiraises the new error, whiletype=2without one still falls through tolocator_value_selector's existingFieldValueError— both reject, but via different exceptions.cert_groupbeing a plainintstill silently accepts anEnum.Groupmember at the call site (stored as the enum) — no guard added, since only the decode path was the actual defect.Test: new
tests/protocols/internet/test_hip_wire_semantics_unit.py(15 tests). Fail-without-fix: 14 of 15 fail againstorigin/main(the 15th is a deliberate no-regression control for #2276's unchanged path).test_hip_unit.pyupdated for the three issues it pinned the old wrong semantics for.