QUIC_MAX_RANGE_ALLOC_SIZE Limit Causes Performance Degradation Under Extreme Packet Loss
#5,450 opened on 2025年9月15日
Repository metrics
- Stars
- (4,712 stars)
- PR merge metrics
- (PR metrics pending)
説明
Describe the bug
Performance degradation and potential DoS vulnerability in QUIC range tracking under extreme packet loss scenarios. The QUIC_MAX_RANGE_ALLOC_SIZE limit of 1MB (~67,786 subranges) is exhausted rapidly when handling pathological packet loss patterns, causing range operations to fail and connections to become unresponsive.
Affected OS
- Windows
- Linux
- macOS
- Other (specify below)
Additional OS information
Linux userspace applications (tested on various Linux distributions)
MsQuic version
main
Steps taken to reproduce bug
- Set up a QUIC connection with high packet loss simulation
- Send packets with large sequence number gaps (e.g., packets 1, 1000, 2, 999, 3, 998...)
- Monitor range set usage in
QUIC_MAX_RANGE_ALLOC_SIZEconstrained structures - Observe connection performance degradation when range limit is reached
- Connection becomes unresponsive or fails range operations
Expected behavior
QUIC connections should handle extreme packet loss gracefully without hitting artificial memory limits. Range tracking should either:
- Dynamically expand memory allocation, or
- Implement range compaction to coalesce adjacent ranges and free up space
Actual outcome
Under consistent packet loss with large gaps:
- Range set hits 67,786 subrange limit quickly
- Further range operations fail
- Connection performance degrades significantly
- Potential for DoS attacks via crafted packet sequences
Additional details
The 1MB limit appears designed for Windows kernel memory constraints but is too restrictive for userspace Linux applications.
Root cause analysis: The issue occurs because each packet gap requires a separate subrange entry. Pathological sequences like alternating high/low packet numbers cause O(n) insertion costs due to array shifting.
Proposed solutions:
- Quick workaround: Increase
QUIC_MAX_RANGE_ALLOC_SIZEto 4GB or remove the limit entirely - Proper fix: Implement
QuicRangeCompact()function to coalesce adjacent ranges before expanding allocation
Code reference: https://github.com/microsoft/msquic/blob/1a1ef818035222c3bbc274e55ec71a89ff084ce1/src/core/quicdef.h#L244
Pathological input example:
// This sequence creates worst-case O(n) behavior:
QuicRangeAddValue(range, 1); // Insert at start
QuicRangeAddValue(range, 1000); // Insert at end
QuicRangeAddValue(range, 5); // Insert near start (causes full array shift)
QuicRangeAddValue(range, 2000); // Insert at end
The pattern continues with Tₙ₊₁ consistently greater than all previous values Tₖ (k = 0 to n-1), creating pathological insertion patterns that maximize memmove operations.