Repository navigation
refactor(ipv6): rename IPv6_GenericExt to IPv6_Ext and make it the shared base (#917) - #924
Conversation
|
GOOD TO GO on the code, from a Sonnet cross-review (the author was Opus). But one thing needs your call before merge, so I have labelled this The rename leaves no backward-compatibility alias, and the break is complete. Measured by me on both trees, printing Both The question: ship it bare, or leave a deprecated alias? The reviewer found no alias-on-rename convention anywhere under Everything else confirmed, independently derived rather than taken from the PR:
One item UNVERIFIED, not blocking: no side-by-side Also worth recording, since I checked it rather than relaying: the reviewer's "main" comparison ran against a different checkout at |
|
No more |
|
Ruling recorded, verbatim:
Verified, and it retires the concern entirely rather than merely overruling it. The name never shipped: Added today, by #904. And across every release tag — So the break the cross-review flagged has no victims. There is no third-party code that can import Removing |
|
I think on subclassing, we might wanna keep this convention: if the IPv6 extension header is only usable as an extension header, then it only inherit from |
|
Ruling recorded, verbatim:
The PR already satisfies this for six of the eight, including both of your examples. Current bases:
But the convention cannot be settled mechanically, and I want to flag one probable misfit rather than guess. Two measurements, both on
Labelled |
956fb9a to
b7090ea
Compare
|
Rebased onto Verified after the rebase:
|
|
So my suggestion is to read through the RFCs to figure out any of the defined IPv6 extension headers are extension header only or standalone protocol as well. Then we can decide if they should inherit only |
|
Ruling recorded, verbatim:
Dispatched. The research is running against primary sources rather than my recollection: the IANA "IPv6 Extension Header Types" registry — which is the decisive list of what actually is an extension header — the Protocol Numbers registry and its IPv6-Extension-Header column, RFC 8200 §4, and the per-header RFCs already cited in the modules (RFC 4302/4303 for AH/ESP, 6275 for MH, 7401/7402 for HIP, 5095/6554 for IPv6-Route, 5533 for Shim6). Two things I asked it to widen beyond your eight, so this is settled once rather than revisited:
One thing I explicitly told it not to use as evidence: HIP is the one I expect to matter most, and it may be a larger finding than the inheritance question: if IANA does not mark 139 in the extension-header column at all, then HIP is not an IPv6 extension header in RFC 8200's sense, and its place under
|
|
RFC classification is in. One change the evidence supports:
HIP meets your standalone test on a primary source. RFC 7401 App. C.2 "IPv4 HIP Packet (I1 Packet)" shows The "HIP is not an extension header" possibility I flagged does not fire. I fetched IANA's MH is the one your test decides, and it turns on which ground counts. RFC 6275 §6.1.1 defines its checksum over a pseudo-header of "IPv6 header fields" with no IPv4 variant, and the IPv4 equivalent function is not protocol 135 at all — RFC 5944 carries Mobile IPv4 over UDP port 434. So it is a protocol in its own right but structurally cannot be an IPv4 payload. Under your wording — "useable as a standalone protocol itself" — MH goes either way depending on whether IPv4-capability or own-protocol-hood is the operative test. Shim6 (140) is identical, so whichever way you rule covers both. Two by-products, neither part of this PR:
|
|
do the update in this PR. |
…ared base (#917) - `git mv` `pcapkit/protocols/internet/ipv6_generic_ext.py` -> `ipv6_ext.py`, plus the matching `data/` and `schema/` modules, docs page and test file; the class, its alias (`IPv6-GenericExt` -> `IPv6-Ext`) and its name follow. - `IPv6_Ext` is now generic in `_PT`/`_ST`, like `IPsec`, and serves both roles: the shared base of all 8 IPv6 extension headers and the RFC 6564 fallback. - Re-parent `HOPOPT`, `IPv6_Route`, `IPv6_Frag`, `IPv6_Opts`, `HIP` and `MH` onto `IPv6_Ext[…]`; `AH(IPsec, IPv6_Ext)` and `ESP(IPsec, IPv6_Ext)`. - Scope the fallback-only members so the base cannot shadow a real header: `protocol` and the `version` gate discriminate on `__data__`; `alias` spelled out on `HOPOPT`/`MH`/`AH`/`ESP`, which took `ProtocolBase`'s class-name default before; `name`/`alias`/`__length_hint__` widened to `str`/`int`; `make` made keyword-only; `read`'s `alias`/`error` moved into `**kwargs`. - `ESP` gains the extension-mode contract: `payload` and `protochain` from the base, `protocol` spelled out, so its `_extf` is load-bearing (#895). - New test class holds every `IPv6_Ext` subclass found at runtime to defining `name`, `alias`, `protocol`, `length` and `__index__` itself. 331 passed / 1420 subtests (was 317 / 1346); `ipv6_ext.py` coverage 87% -> 100%; mypy 321 errors, identical to `main`; pylint 627 messages against `main`'s 629.
b7090ea to
1f413a2
Compare
|
Ruling recorded, verbatim:
Done — new head 1. 2. A test that pins the classification, so the convention cannot rot into prose. Proven to fail without the fix — reverting only HIP's second base: 3. Two prose corrections in I read your ruling as covering HIP only, and left Verified: 31 tests in |
|
GOOD TO GO re-confirmed at Capture parity — this is what proves the double-base change shadowed nothing. Generated the fixtures in a clean tree at this head and counted every HIP-bearing protochain:
MRO is explicit, not changed. Scope, measured by me. The three files are +101/−5 exactly. The other 11 paths in Prose corrections check out against live sources. RFC 8200 §4.5 reads "For this purpose, the Encapsulating Security Payload (ESP) is not considered an extension header.", with ESP listed among upper-layer header examples in the next sentence — so the new wording is accurate and "says outright" was the overstatement. IANA's registry has exactly 11 rows with 147 absent, and One honest nuance from the reviewer, worth recording: 31/31 tests pass. |
…se (#918) (#929) * Retitle *Registry Conventions* -> *House Conventions* and widen the preamble: the page now carries a protocol-class ruling as well as `pcapkit.const` ones, and records the standing ask that a ruling is written here in the same change that implements it. * Correct the five passages #927 left for this issue: the `FEATCode` name miss raises `EnumKeyError` rather than a bare `KeyError`; a `_validate_value` rejection propagates unwrapped with no usable `default`; #877's phase 2 has landed for 17 of the 24 non-registry enumerations rather than "not happened yet"; `TransportProtocol.get` is now only a case fold and `Criticality.get` is gone. * New "What a Failed Lookup Raises" for #923's provenance-and-shape ruling. * New "Which bases an IPv6 extension header names" for #924's subclassing ruling, the RFC census behind it, the retired `IPv6_GenericExt` name, and why ESP is an extension header that still cannot short-circuit the chain walk. * Document `EnumValueError`, which had no `autoexception` entry, so five references to it on this page rendered as plain text. 15 new tests pin the checkable claims. tests/project 193 OK, test_sentinel_exports_unit 18 OK, test_ipv6_ext_unit + FEATCode + enum-lookup-base 77 OK; docs build clean, every new cross-reference resolved in the rendered HTML.
Please follow the guide below
make pylint,make mypy,make isort)make testpasses, and a test case covers the changedocs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A, changelog centralised in docs(changelog): shared 1.5.0 changelog — long-lived, merges last (#610, #616, #617, #618, #620) #657What is the purpose of your pull request?
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingchore— anything elseDescription of your pull request and other information
Closes #917.
IPv6_GenericExtbecomesIPv6_Extand serves both roles the ownerasked for: the shared base of all 8 IPv6 extension headers, and the RFC 6564 fallback
parser. Generic in
_PT/_STlikeIPsec, soAH(IPsec, IPv6_Ext)andESP(IPsec, IPv6_Ext)carry two identically-parameterised generic bases — bothlinearise, and mypy and pylint both accept them (#891 had left that unverified).
The re-parent is not free, and three shadowing traps were measured rather than
assumed. A concrete base shadows anything a subclass does not override:
HOPOPT,MH,AHandESPnever declaredalias— they tookProtocolBase's class-name default. They would have inherited'IPv6-Ext',renaming each in every
ProtoChainstring and packet-dict key. Spelled out now,at exactly the old values. (The issue's premise that all eight already shadow
nameandaliasholds only forname.)protocolasreturn super().protocol, which now lands on thebase — whose
protocolis repointed at the fallback's ownExtensionHeaderidentity. Measured:
AttributeErroron all eight. The base discriminates on__data__(notisinstance(self._info, …), which breaks amake-only instance).version == 6gate would rejectAH/ESP, which default toversion=4:ProtocolError: ESP: only valid for IPv6, got version=4. Scoped tothe fallback role too.
#895 is discharged.
ESPinherits the_extfguards onpayload/protochainand gets
protocolby hand, so_extf— assigned and never read before — is nowload-bearing. Its
readstill has noif extension: returnshort-circuit; thatsaves work rather than changing behaviour, and is not part of this change.
Verified: all 8 keep their
protochainsegment,payload/protocol/protochainguards and
length; codes 147/253/254 still giveprotochain='IPv6:Raw:Raw'withsrc/dst intact (#904's point);
nextis a new shared member, previouslyAttributeErroron all eight. 331 passed / 1420 subtests (main: 317 / 1346), zerofailures.
ipv6_ext.pycoverage 87% → 100%. mypy 321 errors — identical tomain, every category; pylint 627 messages againstmain's 629, no new errors.The new test class walks
IPv6_Ext.__subclasses__()at runtime and requires eachsubclass to define
name,alias,protocol,lengthand__index__itself(checked against
__dict__, sincegetattrcannot tell an override from aninherited fallback answer). Deleting
HOPOPT.namefails it:One deliberate deviation from the issue: the alias assertion is "no underscore, and
alias.lstrip('IPv6-').lower()is a usable key" rather than "is hyphenated", becauseHOPOPT/MH/AH/ESPhave noIPv6prefix forlstripto bite on — requiring ahyphen of them would demand a rename, not test an invariant.