You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5c38fc0
Browse filesBrowse the repository at this point in the historyBrowse files
fix(reassembly): the deferred TCP analyser dispatches on AppType, not bare ports
Follow-up to #2418, which made `Deferred` generic over what its analyser
dispatches on but left the TCP side of that constraint as `tuple[int, int]`.
The owner's note on it: we are still using int tuples for transport ports, so
move to AppType tuples.
* `TCP.submit` resolves `bufid[1]` / `bufid[3]` through `Transport._make_port`
before building the `Deferred`, in a new `TCP._make_ports` helper. A deferred
analysis now dispatches on a named service rather than on a number.
* `_KT`'s second constraint is `tuple[AppType_TCP, AppType_TCP]` -- the
per-transport registry `pcapkit.const.reg.apptype.tcp.TCP`, which is what the
resolution really answers with (`type(...) is TCP`, measured), not the base
`AppType`. `Transport.analyze` keeps the base, being the one method TCP, UDP
and SCTP share, and says so.
* `Transport.analyze` tests the chosen port against `__proto__` exactly as it
arrived and unwraps it to the registry's `int` key only when it is a member,
so a bare `int` caller keeps working -- the method is in v1.4.1 -- and
`(None, None)` or `(54321, '80')` still fall back to `Raw` as on mainline
rather than raising or dispatching.
* `_make_ports` reaches `_make_port` through `TCP` rather than through
`self.protocol`: `__protocol_type__` is an extension point whose analyser need
only define `analyze`, so `self.protocol._make_port` would be an
`AttributeError` for one that is not a `Transport`. Going through `_make_port`
rather than calling `AppType.get` directly is what keeps #2287's bool
rejection: `AppType.get(True, proto=tcp)` resolves `True` as port 1 and
answers `<TCP.tcpmux: 1 [tcp]>`, measured.
* `DatagramID`'s ports stay bare `int`s, and its docstring now says why: it is
the flow identity split out of `BufferID`, a dict key every toolkit adapter
builds from a plain port number and which is dumped as part of the report.
* Docs entries for `TCP._make_ports` and for `AppType.__hash__`, both now named
in public prose (#1940).
All 65,536 ports resolve to a member -- an assignment to its canonical service,
an IANA span to that span's label, anything else to an unregistered `unknown` --
none raise and the registry does not grow, so this adds no way for reassembly to
raise. For a registered port the member is the one `TCP.src` reads off a parsed
header; for an unassigned one the two are equal but not identical and named
apart, which the docstrings record rather than overstate. UDP and SCTP need no
change: neither has a reassembler, so `Transport.analyze` has no caller but
`TCP.submit`.
mypy over `pcapkit/` is byte-identical to mainline (98 errors, same set);
`pylint` with the Makefile flags reports the same two pre-existing
`_decode_next_layer` messages as mainline over the touched files; `isort -l100
-ppcapkit` is clean. Tests: `foundation` + `protocols/transport` + `interface`
with the annotation-name, tier and docstring guards, 997 tests / 4906 subtests;
the full CI selection was green on the pre-review revision at 6552 tests.
Reassembly over the sample captures resolves the same next layer as before, port
for port.
0 commit comments