@@ -5,64 +5,60 @@ Protocol Family Grouping
55
66A protocol family is a base class named after the family plus its member classes.
77What the base and each member return from
8- :meth: `~pcapkit.protocols.protocol.Protocol.id ` decides what every selector matches,
9- so the tuples are settled here rather than re-derived per family. Set on
10- :issue: `2441 `, :issue: `2446 ` and :issue: `2462 `.
8+ :meth: `~pcapkit.protocols.protocol.Protocol.id ` is what the selectors on
9+ :class: `~pcapkit.protocols.protocol.Protocol ` match against, so the tuples are
10+ settled here rather than re-derived per family. Set on :pr: `2441 `, :pr: `2443 `,
11+ :pr: `2446 ` and :issue: `2462 `.
1112
1213The ``id() `` Criterion
1314~~~~~~~~~~~~~~~~~~~~~~
1415
15- **A family base lists its direct concrete subclasses, and nothing else . ** An abstract
16- intermediate is left out, and so is everything beneath it, since that intermediate
17- carries its own tuple. :issue : `2441 `.
16+ **A family base lists its direct concrete subclasses. ** An abstract intermediate is
17+ left out, and so is everything beneath it, since that intermediate carries its own
18+ tuple. :pr : `2441 `.
1819
19- * :meth: `IP.id() <pcapkit.protocols.internet.ip.IP.id> ` is ``('IPv4', 'IPv6') ``.
20- :class: `~pcapkit.protocols.internet.ah.AH ` and
21- :class: `~pcapkit.protocols.internet.esp.ESP ` are not in it: they belong to the
22- separate abstract :class: `~pcapkit.protocols.internet.ipsec.IPsec `.
23- * :meth: `IPsec.id() <pcapkit.protocols.internet.ipsec.IPsec.id> ` is
24- ``('AH', 'ESP') ``.
20+ The member list takes either of these forms:
21+
22+ * **Members only. ** :meth: `IP.id() <pcapkit.protocols.internet.ip.IP.id> ` is
23+ ``('IPv4', 'IPv6') ``; :class: `~pcapkit.protocols.internet.ah.AH ` and
24+ :class: `~pcapkit.protocols.internet.esp.ESP ` are not in it, since they belong to
25+ the separate abstract :class: `~pcapkit.protocols.internet.ipsec.IPsec `, whose
26+ :meth: `~pcapkit.protocols.internet.ipsec.IPsec.id ` is ``('AH', 'ESP') ``.
27+ * **The base's own name, then the members. **
28+ :meth: `VLAN.id() <pcapkit.protocols.link.vlan.VLAN.id> ` is
29+ ``('VLAN', 'C_Tag', 'S_Tag') ``,
30+ :meth: `L2TP.id() <pcapkit.protocols.link.l2tp.L2TP.id> ` is ``('L2TP', 'L2TPv2') ``
31+ and :meth: `HTTP.id() <pcapkit.protocols.application.http.HTTP.id> ` is
32+ ``('HTTP', 'HTTPv1', 'HTTPv2') ``.
33+
34+ :meth: `ARP.id() <pcapkit.protocols.link.arp.ARP.id> ` is ``('ARP',) `` alone; see
35+ :ref: `protocol-family-shapes `.
2536
2637Abstract Family Names
2738~~~~~~~~~~~~~~~~~~~~~
2839
29- **A family name composes its members even when the base also parses. **
30- :class: `~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext ` is concrete -- it is the
31- fallback :class: `~pcapkit.protocols.internet.ipv6.IPv6 ` substitutes when a dedicated
32- extension-header parser fails -- but its name is the family's, so its ``id() `` is to
33- list its direct concrete members, and each member narrows its own ``id() `` to itself.
34- :issue: `2462 `.
35-
36- The rejected alternative gave the base only its own name, because it also parses
37- ``Shim6 ``, which has no member class and which every member's name would then select.
38- That case ends once ``Shim6 `` gets its own parser, so the ruling does not wait for it.
39-
40- One consequence is accepted: once composed, an
41- :class: `~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext ` standing in for a header whose
42- own parser failed matches every member's name.
43-
44- Grouping by Name and History
45- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46-
47- **Members share a base because they share a name and a lineage, not a wire format. **
48- SSL is the case that settled it: its family covers every SSL version, TLS (a rebrand
49- of SSL) and DTLS, although the SSL versions are not wire-compatible with each other.
50- The same reading puts HTTP/1 and HTTP/2 under
51- :class: `~pcapkit.protocols.application.http.HTTP `, IPv4 and IPv6 under
52- :class: `~pcapkit.protocols.internet.ip.IP `, and AH and ESP under
53- :class: `~pcapkit.protocols.internet.ipsec.IPsec `. :issue: `2441 `.
54-
55- Shared parsing code is an implementation detail and does not decide the grouping.
56- Nor does a family base need dispatcher logic: :class: `~pcapkit.protocols.internet.ip.IP `
57- and :class: `~pcapkit.protocols.internet.ipsec.IPsec ` have none, and each member is
58- bound directly. :class: `~pcapkit.protocols.application.http.HTTP ` dispatches
59- because it has to guess a version its wire format does not state, not because it is
60- a family base.
40+ **An abstract family name composes its members. **
41+ :class: `~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext ` carries the family's name, so
42+ its ``id() `` is to list its direct concrete members, and each member narrows its own
43+ ``id() `` to itself. :issue: `2462 `.
44+
45+ Grouping by Name
46+ ~~~~~~~~~~~~~~~~
47+
48+ **Members share a base because they share a name, not a wire format. ** HTTP/1 and
49+ HTTP/2 share :class: `~pcapkit.protocols.application.http.HTTP `, IPv4 and IPv6 share
50+ :class: `~pcapkit.protocols.internet.ip.IP `, and AH and ESP share
51+ :class: `~pcapkit.protocols.internet.ipsec.IPsec `. A family base needs no dispatcher
52+ logic: :class: `~pcapkit.protocols.internet.ip.IP ` and
53+ :class: `~pcapkit.protocols.internet.ipsec.IPsec ` have none, and each member is bound
54+ directly. :pr: `2441 `.
55+
56+ .. _protocol-family-shapes :
6157
6258Member Shapes
6359~~~~~~~~~~~~~
6460
65- Three shapes are in use. Pick by how far a sibling's selector should reach.
61+ Pick a member's shape by how far a sibling's selector should reach.
6662
6763.. list-table ::
6864 :header-rows: 1
@@ -85,11 +81,15 @@ Three shapes are in use. Pick by how far a sibling's selector should reach.
8581 :class: `~pcapkit.protocols.link.l2tpv2.L2TPv2 ` ``('L2TP', 'L2TPv2') ``
8682 * - One parser, dynamic alias
8783 - fixed, whichever protocol was read
88- - :class: `~pcapkit.protocols.link.arp.ARP ` ``('ARP',) `` parses ARP, InARP,
89- RARP and DRARP and reports which through
84+ - :class: `~pcapkit.protocols.link.arp.ARP ` ``('ARP',) `` reads the operation
85+ code and reports ARP, InARP, RARP or DRARP through
9086 :attr: `~pcapkit.protocols.protocol.Protocol.alias `;
9187 :class: `~pcapkit.protocols.link.arp.InARP ` ``('InARP',) `` is a thin
92- subclass that exists for explicit construction
88+ subclass that exists for explicit construction.
89+ :class: `~pcapkit.protocols.application.rarp.RARP ` ``('RARP', 'DRARP') `` and
90+ :class: `~pcapkit.protocols.application.rarp.DRARP ` ``('DRARP',) `` are
91+ separate classes, bound to EtherType ``0x8035 ``
92+ (:attr: `~pcapkit.const.reg.ethertype.EtherType.Reverse_Address_Resolution_Protocol `)
9393
9494A family-inclusive member is selected by any sibling's registry key, because both
9595expand to the shared family name (see :ref: `below <protocol-family-selectors >`). A
@@ -102,16 +102,23 @@ Canonical Names
102102
103103**A class name may carry a version that the protocol's own name does not. ** Where
104104the defining RFC names the protocol without a version, a versioned class and module
105- name are fine for telling the members apart in code, but ``id() `` returns the RFC's
106- canonical name and :attr: `~pcapkit.protocols.protocol.Protocol.name ` follows the
107- RFC's title, with no version string added. :issue: `2446 `.
105+ name may tell the members apart in code; ``id() `` is then expected to drop the
106+ version for the RFC's canonical name, and
107+ :attr: `~pcapkit.protocols.protocol.Protocol.name ` to follow the RFC's title with no
108+ version string. :pr: `2446 `.
108109
109110.. _protocol-family-selectors :
110111
111112Selector Matching
112113~~~~~~~~~~~~~~~~~
113114
114- What a selector reaches is defined by
115+ **A family name selects every version, and each version name selects its own. **
116+ :pr: `2443 `. The narrow-to-self shape gives exactly that: ``'IP' in frame `` is
117+ ``True `` for an IPv4 frame and an IPv6 frame alike, and ``'IPv6' in frame `` is
118+ ``False `` for an IPv4 frame. Under the family-inclusive shape a version name also
119+ selects its siblings, as the second bullet below shows for HTTP.
120+
121+ What a selector on a frame or a layer reaches is defined by
115122:meth: `~pcapkit.protocols.protocol.Protocol.expand_comp `,
116123:meth: `~pcapkit.protocols.protocol.Protocol.__contains__ `,
117124:meth: `~pcapkit.protocols.protocol.Protocol.__getitem__ ` and ``Protocol.__eq__ ``.
@@ -126,7 +133,13 @@ All comparisons are case-insensitive.
126133 ``True `` for an IPv4 frame, and ``'HTTPv2' in frame `` is ``True `` for an HTTP/1.1
127134 frame, since both sides carry ``'HTTP' ``.
128135* A string that is **not ** a registry key is matched by name alone against each
129- layer's ``id() ``. An alias such as ``'HTTP/1.1' `` matches nothing.
136+ layer's class and ``id() ``, so an alias such as ``'HTTP/1.1' `` selects no layer:
137+ ``'HTTP/1.1' in frame `` is ``False ``.
138+
139+ :class: `~pcapkit.corekit.protochain.ProtoChain ` matches more widely: its
140+ :meth: `~pcapkit.corekit.protochain.ProtoChain.index `,
141+ :meth: `~pcapkit.corekit.protochain.ProtoChain.count ` and ``in `` also compare each
142+ layer's alias, so ``'HTTP/1.1' in frame.protochain `` is ``True ``.
130143
131144So adding a name to an ``id() `` tuple widens every ``in `` and ``[] `` selector that
132145can reach it; check the reach before choosing a shape.
@@ -139,7 +152,6 @@ No Invented Suffixes
139152:class: `~pcapkit.protocols.internet.ipsec.IPsec `,
140153:class: `~pcapkit.protocols.application.http.HTTP `,
141154:class: `~pcapkit.protocols.link.vlan.VLAN ` and
142- :class: `~pcapkit.protocols.link.l2tp.L2TP ` are the precedent. No ``_Family `` base
143- exists, and none is to be minted. Where a member already holds the family name, the
144- member takes its versioned class name instead, as :ref: `above
145- <protocol-family-canonical-names>`. :issue: `2446 `.
155+ :class: `~pcapkit.protocols.link.l2tp.L2TP ` are the precedent. No ``_Family `` base is
156+ to be minted. A member that shares the family's protocol name may take a versioned
157+ class name, as :ref: `above <protocol-family-canonical-names >`. :pr: `2446 `.
0 commit comments