Sans-I/O, sans-clock controllers: the caller feeds byte counts and the
monotonic millisecond clock; the controller answers "may I send another
bytes right now?" via :meth:can_send and grows / shrinks the
congestion window on ACK / loss. No socket, no timer -- the
:mod:flare.quic._loss_recovery bookkeeping and the client / server
send paths own those and consult a controller through the
:trait:CongestionController contract.
Two algorithms ship:
- :struct:
RenoController -- the RFC 9002 section 7.3 NewReno reference
(slow start + AIMD congestion avoidance). Simple, robust, the safe
default.
- :struct:
CubicController -- RFC 9438 CUBIC with the RFC 9406
HyStart++ slow-start exit. Better throughput on high
bandwidth-delay-product paths (the case HTTP/3 over WAN hits).
:struct:CcChoice selects between them. Both share the RFC 9002
constants below and the in-recovery guard (one window reduction per
round-trip, keyed on the lost packet's send time).
These controllers model the window only -- they do not pace
egress (no inter-packet send timer). The QUIC send path uses the window
as a gate (burst up to cwnd - bytes_in_flight); add a pacer
(RFC 9002 section 7.7) only if a profile shows bursty loss. The upgrade
path is a next_send_time accessor here plus a timer in the reactor.