Reassembly Integration

Where a new reassembly engine under pcapkit.foundation.reassembly plugs into the rest of the package. Points 1 to 3 are the owner’s ruling on the DTLS reassembly work, applied in review of #2451 (#2440); the issue itself does not hold it. Point 4 rests on #2469, which settled the DTLS case alone: in review of how DTLS sizes a handshake message’s buffer, the owner had DTLS reassembly follow its RFCs. No issue holds that ruling.

The Rule

  1. A protocol class does not handle or integrate reassembly itself. The protocol dissector stays a parser; it does not reach into pcapkit.foundation.reassembly directly. A public method that parses a reassembled unit from its own octets is still a parser, so a protocol class may offer one (#2496).

  2. A new engine needs a new pcapkit.toolkit helper that declares which output engines (dpkt, pyshark, scapy, the default) support it.

  3. A new engine’s reassembled outcome needs a new pcapkit.foundation.analysis method to parse that outcome into a usable result, rather than leaving the caller to interpret raw reassembled bytes. The package mirrors pcapkit.foundation.reassembly: a module per engine, whose public names the package, pcapkit.foundation and pcapkit.all export (#2496).

  4. Reassembly always follows the RFC’s own definition, never an algorithm this package invents. Where the RFC states no required algorithm – buffer the whole message, accept overlaps – the engine does the same and adds no timeout, cap or ordering rule the RFC does not call for.

TCP’s gap cap is a safety limit, not a reassembly rule. No RFC calls for TCP_GAP_LIMIT, the widest gap TCP reassembly zero-fills to merge a segment. It bounds the memory a capture can have zero-filled, as MAX_ZERO_PAD_LENGTH does for a field, and -1 lifts it to give the uncapped reassembly point 4 asks for. Ruled on #2546.

Parse Ownership

The protocol class owns the parse of a reassembled outcome, and pcapkit.foundation.analysis is a public layer over it. Ruled on #2622:

Compliance, Measured

Point 1 holds for every engine. None of IPv4, IPv6, TCP and DTLS imports or calls into pcapkit.foundation.reassembly at all. The real path is pcapkit.foundation.engines calling a pcapkit.toolkit.<engine> extraction function on an already-parsed frame, feeding the result to the reassembly instance the Extractor holds; for DTLS that function is pcapkit.toolkit.pcap.dtls_reassembly() (#2496). DTLS.read_handshake and DTLS.analyze_handshake are the parser methods the rule allows.

No engine meets point 2. No single pcapkit.toolkit helper enumerates which output engines support a given reassembly engine. Support is established ad hoc, per engine backend, by defining the extraction functions, by defining them raising UnsupportedCall, or by disabling reassembly at the engine level, as pcapkit.foundation.engines.pyshark does. DTLS defines them for the default engine and is disabled at the engine level on every other.

Point 3 holds for every engine. ip_datagram() parses a reassembled IPv4 or IPv6 datagram’s payload by its payload protocol type, through Protocol.analyze; tcp_datagram() parses a reassembled TCP datagram’s by its ports, through Transport.analyze; and dtls_handshake() decodes a reassembled DTLS handshake message (#2496), through DTLS.analyze_handshake (#2622). The owner chose on #2581 to give IP and TCP modules of their own, each function named for the datagram its engine reassembles, rather than leave their outcomes to those dispatchers with no analysis method, which kept the rule true for DTLS alone.

Where the rule is silent, DTLS takes the IP/TCP shape (#2531). IPv4, IPv6, TCP and DTLS reassembly each set __protocol_type__, and each reports its parsed outcome as a datagram’s packet, deferred to first read by Deferred. Each Deferred runs the parse behind its engine’s analysis function, so a packet is what that function returns. Each binds that parse to __protocol_type__, calling its analyze for IP and TCP (#2581) and its analyze_handshake for DTLS (#2622), so a subclass naming another protocol has its packet parsed by that one. The engines differ in what an incomplete outcome holds. IP and TCP parse a contiguous payload whether or not it is complete, as strict=False reports one, and hold None only for the received runs strict=True reports; DTLS holds None for any incomplete message.