Skip to content

feat(transport): dissect DCCP, with its checksum over the IP pseudo-header - #2593

Merged
JarryShaw merged 1 commit into
mainfrom
feat/2489-dccp
Nov 2, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
feat/2489-dccp

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

What is the purpose of your pull request?

  • feat — adds a feature

Description of your pull request and other information

DCCP (RFC 4340, plus DCCP-Listen from RFC 5596) gets a full dissector in pcapkit.protocols.transport.dccp, replacing the NotImplemented stub. IP protocol 33 dispatches to it.

  • Header and fields: the generic header with 48- or 24-bit sequence numbers (the X bit chooses), each packet type's extra fields, and every RFC 4340 option. Unknown options and types are kept raw, and reserved bits are kept as captured.
  • Malformed input: a fuzz of every option type against every length octet leaves no input that both parses and fails to rebuild byte-exact. Every input either rebuilds byte-exact or is refused, which under IP means Raw.
  • Checksum: it follows pep.rst's checksum design. Verification is opt-in with a recorded ChecksumStatus, and the coverage is CsCov's (§9.2). make() writes CsCov 0 when the coverage reaches the end of the packet, as Linux's dccp_csum_outgoing did.
  • Registries: DCCP.register_option plus the register_dccp and register_dccp_option wrappers. There are six IANA registries, as crawlers plus generated const modules that regenerate byte-identically.

Settled on the worker's recommendations, open to the owner:

  1. A CsCov that runs past the packet is INVALID and raises a ChecksumWarning.
  2. DCCP has no NOT_COMPUTED exemption, because it has no "no checksum" value.
  3. Option lengths behave as in TCP: an impossible length refuses the layer.

Follow-ups:

Closes #2489

@JarryShaw JarryShaw added feat Pull requests that add a new capability (feat: subject prefix) review: good-to-go Cross-review at the current head says ready; CI state is separate labels Nov 1, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

GOOD TO GO at 0bfbe212f. Two Sonnet reviews covered it, the dissector first and then its fix round, and I checked the rebase myself.

  • Malformed options: fuzzing every option type against every length octet gives 0 parse→rebuild mismatches. 448 inputs are refused at parse and 56,928 rebuild byte-exact.
  • Checksum: CsCov coverage follows RFC 4340 §9.2. make()'s CsCov 0 matches Linux's dccp_csum_outgoing.
  • Lint and tests: mypy is clean on the DCCP modules, and the protocols/transport leg ran 566 tests, OK.
  • Rebase: onto f4aa57742, patch-identical outside two registry test tables, where refactor(application)!: dispatch HTTP to HTTPv1/HTTPv2 under the RFC names (#2524) #2544's HTTPv2 rename and the DCCP rows both stay.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Question for the owner: make() takes type as PacketType | int, resolved with PacketType.get. It does not use the type/type_default/type_namespace/type_reversed group that ICMP uses, which pep.rst's "Deterministic Construction Arguments" calls fragile.

  1. Keep it as PacketType | int (recommended). New dissectors should not take on the group pep.rst flags.
  2. Use the ICMP group, for consistency with existing dissectors.
    The PR implements 1 and is otherwise complete.

@JarryShaw JarryShaw added the needs: decision Waiting on the maintainer to decide — not blocked by other work label Nov 1, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Would prefer 1. But if that is so, we need to rework all other make paths to follow this convention.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Owner chose 1, paraphrased: make(type=...) keeps taking PacketType | int, and every other make() should follow the same convention. So this PR stands as written. The rollout across the other make() methods (dropping the X_default/X_namespace/X_reversed groups) is filed as #2594, with one sub-question for the owner: remove the shipped keywords in 1.6.0, or deprecate them first.

@JarryShaw JarryShaw removed the needs: decision Waiting on the maintainer to decide — not blocked by other work label Nov 1, 2026
@JarryShaw JarryShaw moved this to In review in PyPCAPKit Nov 1, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

The red "Python pypy3.11" leg is a lost runner, not a test failure. The log ends at 9 m 23 s with "The runner has received a shutdown signal", in the middle of the tests/protocols shard. That is #2600: since the checksum wave, the PyPy protocols shard has run close to the runner's memory, and this PR adds DCCP's tests to the same shard. The shard split in #2600 is the fix. Re-run this leg once #2600 has merged. The review verdict stands.

@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Coverage: 94.06% (unit tier, Python 3.15, 30e3b2904, Unit Tests run success)

Package Statements Missed Branches Partial Cover
pcapkit (top level) 104 4 20 2 95.16%
pcapkit/const 20284 154 2760 135 98.70%
pcapkit/corekit 2664 74 836 37 96.60%
pcapkit/dumpkit 281 3 100 3 98.43%
pcapkit/foundation 3382 27 1196 32 98.71%
pcapkit/interface 138 4 52 3 96.32%
pcapkit/protocols 20779 220 5468 204 98.37%
pcapkit/toolkit 961 28 342 10 96.32%
pcapkit/utilities 506 7 144 5 98.15%
pcapkit/vendor 5065 2228 1160 188 52.64%

Per-file detail: the coverage-html artifact of this run.

@JarryShaw

Copy link
Copy Markdown
Owner Author

With #2586 merged, this PR's checksum imports point at a path that no longer exists on main. A fix round is rebasing it onto main and retargeting them to pcapkit.corekit.checksum.internet and misc.checksum.ip_pseudo. That push will also re-run the PyPy leg that was lost to the #2600 stall.

…#2489)

- DCCP dissects the RFC 4340 generic header with short and long sequence
  numbers, the fields of every packet type, DCCP-Listen (RFC 5596) and the
  options, and rebuilds each packet byte for byte; an option length under 2
  is refused, and an over-long NDP Count keeps its width.
- The enclosing IP layer verifies its checksum under CHECKSUM_VERIFY and
  computes it under CHECKSUM_COMPUTE, over the part CsCov gives; a CsCov
  reaching the end is written as 0 when computed, as Linux did.
- IP protocol 33 dispatches to it; register_dccp and register_dccp_option
  write its port and option maps.
- The IANA DCCP registries get crawlers and generated const modules.
- Docs pages, the dispatch and option round-trip generators and the guard
  tables follow; the NotImplemented stub goes.
@JarryShaw

Copy link
Copy Markdown
Owner Author

Rebased onto main (a25eb0e39): 0bfbe212f → 30e3b2904, with no conflicts.

  • Imports: every DCCP import and reference to the checksum helpers now points at pcapkit.corekit.checksum.internet or misc.checksum.ip_pseudo. That covers make, _verify_pseudo_checksum, the data module, the test setUp and the pep.rst DCCP bullet. The only remaining old-path string is main's own negative example in the boundary test.
  • Patch-id (--stable): unchanged outside those lines, at 79ff5093639d on both heads.
  • Tests: 95 modules pass, test_dccp_unit passes 43 tests, and the protocols/transport leg runs 566 tests OK.
  • Review: GOOD TO GO stands, since only the import paths changed. This push also re-runs the PyPy leg that was lost to the ci: the PyPy protocols shard stalls past the 30s case timeout since the checksum wave #2600 stall.

@JarryShaw
JarryShaw merged commit a2a78a6 into main Nov 2, 2026
61 checks passed
@JarryShaw
JarryShaw deleted the feat/2489-dccp branch November 2, 2026 02:14
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Nov 2, 2026
@github-actions github-actions Bot added this to the PyPCAPKit v1.6 milestone Nov 2, 2026
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Nov 2, 2026
JarryShaw added a commit that referenced this pull request Nov 2, 2026
…1.6.0 (#2449)

- Added: DCCP, its checksum over the IP pseudo-header, register_dccp and
  register_dccp_option, and the pcapkit.const.dccp registries (#2593).
- Folded into unreleased entries: LinuxSLL's stop on its ARPHRD path
  (#2587) and ARPHRD's __proto_dest__ (#2598), SSLv2 records chained in a
  segment (#2585), the checksum's move to pcapkit.corekit.checksum.internet
  (#2586), and IGMPv2's and IGMPv3's versioned name (#2590).
- Breaking: InARP moves to pcapkit.protocols.link.inarp with no re-export,
  joining the DRARP entry (#2596).
- Changed: the conventions' new rulings (#2599), the milestone workflow's
  next-open-milestone lookup (#2591), the PyPy protocols shards (#2604).
  Fixed: a handled next-layer refusal is quiet under beholder (#2597); the
  IPX crawlers restore sys.path (#2601).
- CHANGELOG.md regenerated; util/changelog_md.py --check passes.
JarryShaw added a commit that referenced this pull request Nov 2, 2026
…graph (#2564)

- ARPHRD values on LinuxSLL each have a dissector (#2460, #2502, #2510);
  radiotap hands 802.11 to IEEE802_11 (#2575), its own fields stay #2576.
- Release Plan: drop the Mermaid chain that workflows.rst already draws.
- Wave 2 done, ruled on #2564; the "wave 2 or 3" items become wave 3.
- Deterministic Construction Arguments: scoped for 1.6.0, ruled in review of
  #2593 (#2489) and on #2594.
- The SSL family's listings gain SSLv2 (#2457, #2567).
- Reassembly covers DTLS handshakes; dpkt, scapy and pypcapfile disable it.
- Binding lists gain LINUX_SLL/SLL2, TLS 443 and DTLS 5684; the checksum list
  gains GRE and IGMP (#2618). Consistency sweep marked done; timed words dropped.

Docs tests under tests/project pass, one module per process.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat Pull requests that add a new capability (feat: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

DCCP implementation, with the DCCP checksum over the IP pseudo-header

1 participant