Branch: refs/heads/misc-bugfixes
Home: https://github.com/kronosnet/kronosnet
Commit: 76dd6e1cbe8dfd46ba6957750718bc0cf4a6b289
https://github.com/kronosnet/kronosnet/commit/76dd6e1cbe8dfd46ba6957750718b…
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
Date: 2026-05-22 (Fri, 22 May 2026)
Changed paths:
M libknet/host.c
Log Message:
-----------
libknet: fix defragmentation buffer reclamation logic
Fix two bugs in the defragmentation buffer reclamation logic that prevent
efficient memory management:
1. Window calculation was using the old received sequence number (dst_seq_num)
instead of the current packet's sequence number (seq_num) to calculate the
valid buffer window. This caused buffers to be reclaimed based on stale
sequence information, potentially freeing buffers that should still be valid
or keeping buffers that should be reclaimed.
2. Window size calculation incorrectly used defrag_bufs_max (configuration limit,
default 1024) instead of allocated_defrag_bufs (actual allocated count, typically 32)
when allocated_defrag_bufs < defrag_bufs_max. This created an excessively large
window (1025 sequence numbers for 32 buffer slots), causing integer wraparound
in the tail calculation and preventing proper buffer reclamation.
Example: With seq_num=150, allocated_defrag_bufs=32, defrag_bufs_max=1024:
- Buggy: tail = 150 - 1025 = -875 → wraps to 64661 (prevents reclamation)
- Fixed: tail = 150 - 33 = 117 (correct reclamation window)
The window size must always match the actual allocated buffer capacity to ensure
proper reclamation of stale defragmentation buffers.
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply(a)anthropic.com>
Commit: 81c8dfbba77e9abe16aaac0b3e5958a2a00dce88
https://github.com/kronosnet/kronosnet/commit/81c8dfbba77e9abe16aaac0b3e595…
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
Date: 2026-05-22 (Fri, 22 May 2026)
Changed paths:
M libknet/host.c
Log Message:
-----------
libknet: fix sequence number wraparound calculation in defragmentation
The distance calculation between sequence numbers was incorrect when
wraparound occurred. The formula was backwards: it subtracted in the wrong
direction and didn't account for the +1 needed for modular arithmetic.
This caused incorrect buffer reclamation decisions near the SEQ_MAX boundary.
Practical examples (SEQ_MAX = 65535):
Example 1 - Normal case (no wraparound):
Last packet: dst_seq_num = 1000
New packet: seq_num = 1005
Expected distance: 5
BEFORE (wrong):
seq_dist = dst_seq_num - seq_num = 1000 - 1005 = -5 (negative!)
AFTER (correct):
seq_dist = seq_num - dst_seq_num = 1005 - 1000 = 5
Example 2 - Wraparound case:
Last packet: dst_seq_num = 65534
New packet: seq_num = 3 (wrapped around)
Expected distance: 5 (65534→65535→0→1→2→3)
BEFORE (wrong):
seq_dist = (SEQ_MAX - seq_num) + dst_seq_num
seq_dist = (65535 - 3) + 65534 = 131066 (huge wrong number!)
AFTER (correct):
seq_dist = (SEQ_MAX - dst_seq_num) + seq_num + 1
seq_dist = (65535 - 65534) + 3 + 1 = 5
The +1 accounts for the transition from 65535→0 being one step, not zero.
Verification that circular buffer cleaning is not broken:
The seq_dist value is used to determine whether the new packet is:
a) Within the circular buffer window (seq_dist < KNET_CBUFFER_SIZE)
b) Far enough to require full buffer clear (seq_dist > threshold)
c) Should trigger incremental cleaning (fall through case)
Test case 1 - Normal sequential packet:
dst_seq_num = 1000, seq_num = 1005, expected distance = 5
BEFORE: seq_dist = -5 (unsigned overflow ~65530)
→ Incorrectly clears entire buffer for normal sequential packets!
AFTER: seq_dist = 5
→ Correctly identifies packet as within buffer window, no clearing needed
Test case 2 - Wraparound (close distance):
dst_seq_num = 65534, seq_num = 3, expected distance = 5
BEFORE: seq_dist = 131066
→ Falls through to circular buffer cleaning code incorrectly
AFTER: seq_dist = 5
→ Correctly identifies packet as within buffer window
Test case 3 - Large jump requiring buffer clear:
dst_seq_num = 1000, seq_num = 50000, expected distance = 49000
BEFORE: seq_dist = -49000 (unsigned ~16536)
→ Clears buffer (correct by accident)
AFTER: seq_dist = 49000
→ Clears buffer (correct by design)
The circular buffer cleaning code (lines 673-684) uses seq_num and dst_seq_num
directly via modulo operations to find buffer positions. It does not use
seq_dist for position calculations, only for the threshold check to determine
whether to run. The fix corrects the threshold logic without affecting the
position calculations.
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply(a)anthropic.com>
Commit: 81162ed5d2ff6ebb8a944584f0cd2bb986772e6f
https://github.com/kronosnet/kronosnet/commit/81162ed5d2ff6ebb8a944584f0cd2…
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
Date: 2026-05-22 (Fri, 22 May 2026)
Changed paths:
M libknet/tests/Makefile.am
A libknet/tests/int_seq_wraparound_stress.c
Log Message:
-----------
[tests] add comprehensive sequence number wraparound stress test
Add new int_seq_wraparound_stress test that exercises sequence number
wraparound and defragmentation buffer management with realistic packet
loss scenarios.
Test scenarios:
1. Normal sequential packets with occasional loss
2. Wraparound boundary (65535->0) with packet loss
3. Large sequence jumps (>KNET_CBUFFER_SIZE) triggering buffer clearing
4. Out-of-order fragment delivery within same sequence number
5. Out-of-order complete packet delivery (different sequence numbers)
6. Extreme packet loss beyond receive window
7. Wraparound with extreme loss (>KNET_CBUFFER_SIZE gap)
8. Wraparound stress with multiple cycles and duplicate detection
9. Fragment corruption across wraparound (historical bug regression test)
10. Defrag buffer reclamation window calculation validation
Signed-off-by: Fabio M. Di Nitto <fabbione(a)kronosnet.org>
Co-Authored-By: Claude Sonnet 4.5 <noreply(a)anthropic.com>
Commit: a541323887eb5d5c1a335ffb348b52b80441bf2f
https://github.com/kronosnet/kronosnet/commit/a541323887eb5d5c1a335ffb348b5…
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
Date: 2026-05-22 (Fri, 22 May 2026)
Changed paths:
M libknet/tests/Makefile.am
A libknet/tests/int_defrag_edge_cases.c
Log Message:
-----------
[tests] add defragmentation edge cases test suite
Add new int_defrag_edge_cases_test that validates critical defragmentation
buffer management scenarios not covered by existing tests.
Test scenarios:
1. Last fragment arriving first - validates special buffer positioning
at KNET_MAX_PACKET_SIZE - len offset, last_first flag handling, and
fragment relocation when packet completes. Tests asymmetric MTU with
fragments in order [3/3, 1/3, 2/3] and verifies data integrity across
all fragments (280 bytes total with distinct payloads 'A', 'B', 'C').
2. Buffer exhaustion and reclamation - validates window-based reclamation
when all 32 defrag buffers are filled with incomplete packets. Sends
new complete packet with distant sequence number (9000 vs 2000-2031)
triggering reclamation of all out-of-window buffers. Verifies data
integrity with no corruption from old buffer data in new packet.
3. Fragment data overwrite protection - validates correct assembly of
large fragmented packets without buffer overflow. Test case 1 sends
100 fragments × 500 bytes (50,000 bytes total), test case 2 sends
50 fragments × 1,300 bytes (65,000 bytes approaching KNET_MAX_PACKET_SIZE).
Each fragment filled with its index number and verified on assembly.
Signed-off-by: Fabio M. Di Nitto <fabbione(a)kronosnet.org>
Co-Authored-By: Claude Sonnet 4.5 <noreply(a)anthropic.com>
Compare: https://github.com/kronosnet/kronosnet/compare/a63f9768576d...a541323887eb
To unsubscribe from these emails, change your notification settings at https://github.com/kronosnet/kronosnet/settings/notifications