microsoft/msquic

QUIC_MAX_RANGE_ALLOC_SIZE Limit Causes Performance Degradation Under Extreme Packet Loss

Open

#5,450 opened on 2025年9月15日

GitHub で見る
 (2 comments) (0 reactions) (1 assignee)C (671 forks)github user discovery
Triagedhelp wanted

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

  1. Set up a QUIC connection with high packet loss simulation
  2. Send packets with large sequence number gaps (e.g., packets 1, 1000, 2, 999, 3, 998...)
  3. Monitor range set usage in QUIC_MAX_RANGE_ALLOC_SIZE constrained structures
  4. Observe connection performance degradation when range limit is reached
  5. 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:

  1. Quick workaround: Increase QUIC_MAX_RANGE_ALLOC_SIZE to 4GB or remove the limit entirely
  2. 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.

コントリビューターガイド