fix: correct NetFlow v9 Count and frame boundaries - #302
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes NetFlow v9 semantics by treating header Count as exporter-declared record metadata (not a FlowSet count) and by parsing FlowSets to the end of the caller-delimited v9 export-packet frame. Adds a configurable v9 maximum frame size (default 65,535 bytes), updates serialization to recompute record count, and refreshes tests/fixtures/docs to reflect framing rules and stricter boundary validation.
Changes:
- Parse v9 FlowSets to the end of the caller-provided frame and preserve exporter-declared
header.countduring parsing/pending replay. - Serialize v9 by recomputing
header.countas the total emitted record count; reject empty packets and u16 overflow for record count / FlowSet length. - Add/propagate a configurable v9 max-frame-size limit and update tests, snapshots, README, and SECURITY guidance accordingly.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/v9_count_framing.rs | New regression tests covering v9 Count semantics, framing, pending replay, serialization overflow, and frame-size limits. |
| src/variable_versions/v9/types.rs | Stops using header.count to delimit FlowSet parsing; clarifies Header::count meaning in docs. |
| src/variable_versions/v9/serializer.rs | Recomputes header.count as record count; adds overflow checks and rejects packets with no emittable FlowSet. |
| src/variable_versions/v9/parser.rs | Adds v9 frame-size enforcement and header-only rejection; parses FlowSets to end-of-frame; preserves exporter-declared count. |
| src/variable_versions/mod.rs | Re-exports the new default v9 frame-size constant. |
| src/variable_versions/config.rs | Introduces DEFAULT_MAX_V9_FRAME_SIZE_BYTES and ConfigError::InvalidV9FrameSize. |
| src/tests.rs | Updates legacy/base tests to avoid concatenated v9 frames and to remove bytes beyond declared FlowSet lengths. |
| src/snapshots/netflow_parser__tests__restored_legacy_tests__it_parses_v9_ipv6flowlabel.snap | Snapshot update reflecting test refactor/expectations. |
| src/snapshots/netflow_parser__tests__restored_legacy_tests__it_parses_multiple_packets.snap | Snapshot update reflecting test refactor/expectations. |
| src/snapshots/netflow_parser__tests__base_tests__v9_example_from_integration_test.snap | Snapshot update reflecting corrected v9 Count semantics and fixture trimming. |
| src/snapshots/netflow_parser__tests__base_tests__v9_example_from_integration_test_2.snap | Snapshot update reflecting corrected v9 Count semantics and fixture trimming. |
| src/lib.rs | Adds builder option for v9 max frame size; updates parse/iter docs to emphasize v9 framing constraints. |
| SECURITY.md | Documents the new default v9 frame-size DoS mitigation. |
| README.md | Documents v9 frame-boundary requirements and configuration example for max frame size. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ktsaou
force-pushed
the
fix/v9-count-framing
branch
from
July 21, 2026 08:13
103aec5 to
44959d7
Compare
Owner
|
Can you rebase? |
ktsaou
force-pushed
the
fix/v9-count-framing
branch
from
July 22, 2026 07:26
44959d7 to
48eaaa4
Compare
Contributor
Author
|
rebased |
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
NetFlow v9
Countis the total number of Template, Options Template, and Data records in an Export Packet. The parser instead used it as the number of FlowSets to parse.That caused valid FlowSets to be left unread when the declared record count was smaller than the FlowSet count. The outer parser then treated those remaining FlowSet bytes as another packet. Pending-flow replay also rewrote the received Count as a FlowSet count, and serialization emitted a FlowSet count rather than a record count.
NetFlow v9 has no packet-length field, so Count cannot delimit the packet. The complete caller-provided transport frame is the only available byte boundary.
Change
Protocol basis
RFC 3954 section 5.1 defines Count as the sum of Template, Options Template, and Data records. nfdump and GoFlow2 likewise traverse FlowSets to the caller-provided packet boundary.
Compatibility
The configuration API is additive. Parsing behavior intentionally changes where the previous behavior depended on treating Count as a FlowSet count:
parse_bytesoriter_packetscall.Self-delimiting IPFIX, NetFlow v5, and NetFlow v7 batching is unchanged.
Tests
Four core regression tests fail against unmodified
mainand pass with this change. The final focused suite contains nine tests covering Count semantics, caller framing, pending replay, serialization, overflow, empty packets, default/configured frame limits, invalid configuration, and pre-template-state rejection.The complete project validation passes: