Skip to content

v0.4.0: QUIC support, IPv6, TCP reassembly, bug fixes#8

Merged
Crank-Git merged 18 commits into
masterfrom
v0.4.0
Apr 7, 2026
Merged

v0.4.0: QUIC support, IPv6, TCP reassembly, bug fixes#8
Crank-Git merged 18 commits into
masterfrom
v0.4.0

Conversation

@Crank-Git
Copy link
Copy Markdown
Owner

Summary

  • QUIC Initial packet parsing (RFC 9001/9369) — auto-detected on UDP, decrypts Initial packets to extract TLS ClientHello, produces q protocol prefix in JA4 fingerprints
  • IPv6 support — all fingerprinters (JA4L, JA4SSH, JA4X) now handle both IPv4 and IPv6 via new packet_utils helpers
  • TCP stream reassembly — new sequence-aware TCPStreamReassembler used by JA4H (multi-segment HTTP) and JA4X (out-of-order certificate delivery)
  • Bug fix: JA4SSH direction detection — lower port now correctly identified as server on non-standard SSH ports
  • Documentationdocs/implementation_notes.md documenting all undocumented spec deviations for Go port reference

New files

File Purpose
ja4plus/utils/quic_utils.py QUIC v1/v2 Initial decryption pipeline
ja4plus/utils/tcp_stream.py Sequence-aware TCP stream reassembly
ja4plus/utils/packet_utils.py IPv4/IPv6 abstraction helpers
docs/implementation_notes.md Spec deviation documentation
6 new test files 48 new tests

Test plan

  • All 473 tests pass (425 original + 48 new)
  • Cross-validate QUIC fingerprints against Go implementation
  • Test with real QUIC pcap captures (e.g. Chrome → google.com)
  • Verify IPv6 fingerprints match IPv4 for same TLS ClientHello

🤖 Generated with Claude Code

Crank-Git and others added 18 commits April 6, 2026 21:54
Lower port is now correctly identified as server, not client.
Previously the logic was inverted: src_port < dst_port made src
the client, but conventionally the lower (listening) port is the
server side.
Handles out-of-order segments, duplicates, overlaps, and gap detection.
Used by JA4H and JA4X for multi-segment payload reassembly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
JA4L, JA4SSH, and JA4X now use get_ip_layer() to handle both IPv4
and IPv6 packets. JA4T/JA4TS already worked (TCP-only checks).
JA4/JA4S/JA4H work via extract_tls_info/extract_http_info which
operate on Raw layer regardless of IP version.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
HTTP requests spanning multiple TCP segments are now reassembled
before parsing. Uses TCPStreamReassembler for sequence-aware
reassembly. Single-packet requests continue to work as before.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces naive arrival-order stream concatenation with
TCPStreamReassembler for correct handling of out-of-order TCP
segments during certificate extraction.
# Conflicts:
#	ja4plus/utils/packet_utils.py
# Conflicts:
#	ja4plus/utils/packet_utils.py
#	ja4plus/utils/tcp_stream.py
UDP packets are now checked for QUIC Initial data before falling
through to standard TLS parsing. QUIC ClientHellos produce tls_info
dicts with is_quic=True, triggering the 'q' protocol prefix in JA4.
Adds QUIC section to usage guide, new utilities to API reference,
and bumps version to 0.4.0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Crank-Git Crank-Git merged commit a98f99d into master Apr 7, 2026
7 checks passed
@Crank-Git Crank-Git deleted the v0.4.0 branch April 7, 2026 02:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant