Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::protocols::quic::congestion_controller Class Reference

QUIC congestion control (RFC 9002 Section 7) More...

#include <congestion_controller.h>

Collaboration diagram for kcenon::network::protocols::quic::congestion_controller:
Collaboration graph

Public Member Functions

 congestion_controller ()
 Default constructor.
 
 congestion_controller (size_t max_datagram_size)
 Constructor with custom max datagram size.
 
auto can_send (size_t bytes=0) const noexcept -> bool
 Check if we can send more data.
 
auto available_window () const noexcept -> size_t
 Get available congestion window.
 
auto on_packet_sent (size_t bytes) -> void
 Record bytes sent.
 
auto on_packet_acked (const sent_packet &packet, std::chrono::steady_clock::time_point ack_time) -> void
 Handle packet acknowledgment (RFC 9002 Section 7.3)
 
auto on_packet_lost (const sent_packet &packet) -> void
 Handle packet loss (RFC 9002 Section 7.3.2)
 
auto on_congestion_event (std::chrono::steady_clock::time_point sent_time) -> void
 Handle congestion event (RFC 9002 Section 7.3.2)
 
auto on_ecn_congestion (std::chrono::steady_clock::time_point sent_time) -> void
 Handle ECN congestion signal (RFC 9002 Section 7.1)
 
auto on_persistent_congestion (const rtt_estimator &rtt) -> void
 Handle persistent congestion detection (RFC 9002 Section 7.6)
 
auto cwnd () const noexcept -> size_t
 Get current congestion window.
 
auto ssthresh () const noexcept -> size_t
 Get slow start threshold.
 
auto bytes_in_flight () const noexcept -> size_t
 Get bytes in flight.
 
auto state () const noexcept -> congestion_state
 Get current congestion state.
 
auto max_datagram_size () const noexcept -> size_t
 Get max datagram size.
 
auto set_max_datagram_size (size_t size) -> void
 Set max datagram size.
 
auto reset () -> void
 Reset congestion controller to initial state.
 

Private Member Functions

auto is_in_recovery (std::chrono::steady_clock::time_point sent_time) const noexcept -> bool
 Check if currently in recovery period.
 

Private Attributes

congestion_state state_ {congestion_state::slow_start}
 Current congestion state.
 
size_t cwnd_
 Congestion window in bytes.
 
size_t ssthresh_ {std::numeric_limits<size_t>::max()}
 Slow start threshold.
 
size_t bytes_in_flight_ {0}
 Bytes currently in flight.
 
size_t max_datagram_size_
 Maximum datagram size.
 
std::chrono::steady_clock::time_point congestion_recovery_start_
 Start of the current congestion recovery period.
 
size_t initial_window_
 Initial window size (for reset)
 
size_t minimum_window_
 Minimum window size.
 

Static Private Attributes

static constexpr double kLossReductionFactor = 0.5
 Loss reduction factor (RFC 9002 Section 7.3.2)
 
static constexpr size_t kDefaultMaxDatagramSize = 1200
 Default max datagram size (QUIC minimum guaranteed MTU)
 
static constexpr size_t kInitialWindowPackets = 10
 Number of datagrams for initial window.
 
static constexpr size_t kMinimumWindowPackets = 2
 Minimum window in packets.
 

Detailed Description

QUIC congestion control (RFC 9002 Section 7)

Implements the NewReno congestion control algorithm as specified in RFC 9002. Manages the congestion window, slow start threshold, and bytes in flight.

Definition at line 42 of file congestion_controller.h.

Constructor & Destructor Documentation

◆ congestion_controller() [1/2]

kcenon::network::protocols::quic::congestion_controller::congestion_controller ( )

Default constructor.

Initializes with default parameters:

  • Initial window: 10 * max_datagram_size (14720 bytes for 1472 byte datagrams)
  • Minimum window: 2 * max_datagram_size
  • Max datagram size: 1200 bytes (QUIC minimum)

Definition at line 28 of file congestion_controller.cpp.

30{
31}
static constexpr size_t kDefaultMaxDatagramSize
Default max datagram size (QUIC minimum guaranteed MTU)

◆ congestion_controller() [2/2]

kcenon::network::protocols::quic::congestion_controller::congestion_controller ( size_t max_datagram_size)
explicit

Constructor with custom max datagram size.

Parameters
max_datagram_sizeMaximum datagram size in bytes

Definition at line 33 of file congestion_controller.cpp.

37{
41}
auto max_datagram_size() const noexcept -> size_t
Get max datagram size.
static constexpr size_t kMinimumWindowPackets
Minimum window in packets.
static constexpr size_t kInitialWindowPackets
Number of datagrams for initial window.
std::chrono::steady_clock::time_point congestion_recovery_start_
Start of the current congestion recovery period.

References cwnd_, initial_window_, kInitialWindowPackets, kMinimumWindowPackets, max_datagram_size_, and minimum_window_.

Member Function Documentation

◆ available_window()

auto kcenon::network::protocols::quic::congestion_controller::available_window ( ) const -> size_t
nodiscardnoexcept

Get available congestion window.

Returns
Number of bytes that can be sent

Definition at line 52 of file congestion_controller.cpp.

53{
55 {
56 return 0;
57 }
58 return cwnd_ - bytes_in_flight_;
59}

References bytes_in_flight_, and cwnd_.

◆ bytes_in_flight()

auto kcenon::network::protocols::quic::congestion_controller::bytes_in_flight ( ) const -> size_t
inlinenodiscardnoexcept

Get bytes in flight.

Returns
Current bytes in flight

Definition at line 143 of file congestion_controller.h.

144 {
145 return bytes_in_flight_;
146 }

References bytes_in_flight_.

◆ can_send()

auto kcenon::network::protocols::quic::congestion_controller::can_send ( size_t bytes = 0) const -> bool
nodiscardnoexcept

Check if we can send more data.

Parameters
bytesNumber of bytes to send (default 0 means any)
Returns
True if there is available congestion window

Definition at line 43 of file congestion_controller.cpp.

44{
45 if (bytes == 0)
46 {
47 return bytes_in_flight_ < cwnd_;
48 }
49 return bytes_in_flight_ + bytes <= cwnd_;
50}

◆ cwnd()

auto kcenon::network::protocols::quic::congestion_controller::cwnd ( ) const -> size_t
inlinenodiscardnoexcept

Get current congestion window.

Returns
Current congestion window in bytes

Definition at line 125 of file congestion_controller.h.

126 {
127 return cwnd_;
128 }

References cwnd_.

◆ is_in_recovery()

auto kcenon::network::protocols::quic::congestion_controller::is_in_recovery ( std::chrono::steady_clock::time_point sent_time) const -> bool
nodiscardprivatenoexcept

Check if currently in recovery period.

Returns
True if in recovery

Definition at line 181 of file congestion_controller.cpp.

183{
185 {
186 return false;
187 }
188
189 // We're in recovery if the packet was sent before recovery started
190 return sent_time <= congestion_recovery_start_;
191}
@ recovery
Congestion recovery after loss.

References kcenon::network::protocols::quic::recovery.

◆ max_datagram_size()

auto kcenon::network::protocols::quic::congestion_controller::max_datagram_size ( ) const -> size_t
inlinenodiscardnoexcept

Get max datagram size.

Returns
Maximum datagram size

Definition at line 161 of file congestion_controller.h.

162 {
163 return max_datagram_size_;
164 }

References max_datagram_size_.

◆ on_congestion_event()

auto kcenon::network::protocols::quic::congestion_controller::on_congestion_event ( std::chrono::steady_clock::time_point sent_time) -> void

Handle congestion event (RFC 9002 Section 7.3.2)

Parameters
sent_timeTime the packet was sent

Called when ECN or persistent congestion is detected.

Definition at line 125 of file congestion_controller.cpp.

127{
128 // Only respond to congestion once per RTT (RFC 9002 Section 7.3.2)
129 if (is_in_recovery(sent_time))
130 {
131 return;
132 }
133
134 // Enter recovery
135 congestion_recovery_start_ = std::chrono::steady_clock::now();
137
138 // Reduce cwnd and set ssthresh
139 // ssthresh = cwnd * kLossReductionFactor
140 // cwnd = max(ssthresh, minimum_window)
141 ssthresh_ = static_cast<size_t>(
142 static_cast<double>(cwnd_) * kLossReductionFactor);
143 cwnd_ = std::max(ssthresh_, minimum_window_);
144}
static constexpr double kLossReductionFactor
Loss reduction factor (RFC 9002 Section 7.3.2)
auto is_in_recovery(std::chrono::steady_clock::time_point sent_time) const noexcept -> bool
Check if currently in recovery period.

References kcenon::network::protocols::quic::recovery.

◆ on_ecn_congestion()

auto kcenon::network::protocols::quic::congestion_controller::on_ecn_congestion ( std::chrono::steady_clock::time_point sent_time) -> void

Handle ECN congestion signal (RFC 9002 Section 7.1)

Parameters
sent_timeTime the packet was sent that triggered the ECN-CE signal

Called when ECN-CE marks are detected in ACK_ECN frame. ECN congestion is treated similarly to packet loss but provides more responsive congestion detection without waiting for packet loss.

Only one congestion response is triggered per RTT to avoid over-reaction to multiple ECN-CE marks within the same round trip.

Definition at line 146 of file congestion_controller.cpp.

148{
149 // RFC 9002 Section 7.1: Processing ECN Information
150 // ECN-CE marks indicate congestion without packet loss
151 // Respond same as packet loss, but only once per RTT
152
153 // Only respond to congestion once per RTT
154 if (is_in_recovery(sent_time))
155 {
156 return;
157 }
158
159 // Enter recovery
160 congestion_recovery_start_ = std::chrono::steady_clock::now();
162
163 // Reduce cwnd and set ssthresh
164 // RFC 9002 Section 7.1: "a sender that receives an ACK frame with
165 // ECN feedback indicating the CE codepoint MUST enter congestion
166 // avoidance"
167 ssthresh_ = static_cast<size_t>(
168 static_cast<double>(cwnd_) * kLossReductionFactor);
169 cwnd_ = std::max(ssthresh_, minimum_window_);
170}

References kcenon::network::protocols::quic::recovery.

Referenced by kcenon::network::protocols::quic::connection::handle_loss_detection_result().

Here is the caller graph for this function:

◆ on_packet_acked()

auto kcenon::network::protocols::quic::congestion_controller::on_packet_acked ( const sent_packet & packet,
std::chrono::steady_clock::time_point ack_time ) -> void

Handle packet acknowledgment (RFC 9002 Section 7.3)

Parameters
packetAcknowledged packet information
ack_timeTime the ACK was received

Definition at line 66 of file congestion_controller.cpp.

69{
70 // Update bytes in flight
71 if (packet.in_flight && bytes_in_flight_ >= packet.sent_bytes)
72 {
73 bytes_in_flight_ -= packet.sent_bytes;
74 }
75
76 // Don't increase cwnd in recovery
77 if (is_in_recovery(packet.sent_time))
78 {
79 return;
80 }
81
82 // Exit recovery if we're receiving ACKs for packets sent after recovery started
84 {
86 }
87
88 // Congestion window increase (RFC 9002 Section 7.3.1)
90 {
91 // Slow start: increase cwnd by the number of bytes acknowledged
92 cwnd_ += packet.sent_bytes;
93
94 // Check if we've exceeded slow start threshold
95 if (cwnd_ >= ssthresh_)
96 {
98 }
99 }
100 else
101 {
102 // Congestion avoidance: AIMD
103 // cwnd += max_datagram_size * acked_bytes / cwnd
104 auto increment = (max_datagram_size_ * packet.sent_bytes) / cwnd_;
105 if (increment == 0)
106 {
107 increment = 1; // Always increase by at least 1 byte
108 }
109 cwnd_ += increment;
110 }
111}

References kcenon::network::protocols::quic::congestion_avoidance, kcenon::network::protocols::quic::recovery, and kcenon::network::protocols::quic::slow_start.

Referenced by kcenon::network::protocols::quic::connection::handle_loss_detection_result().

Here is the caller graph for this function:

◆ on_packet_lost()

auto kcenon::network::protocols::quic::congestion_controller::on_packet_lost ( const sent_packet & packet) -> void

Handle packet loss (RFC 9002 Section 7.3.2)

Parameters
packetLost packet information

Definition at line 113 of file congestion_controller.cpp.

114{
115 // Update bytes in flight
116 if (packet.in_flight && bytes_in_flight_ >= packet.sent_bytes)
117 {
118 bytes_in_flight_ -= packet.sent_bytes;
119 }
120
121 // Trigger congestion event
122 on_congestion_event(packet.sent_time);
123}
auto on_congestion_event(std::chrono::steady_clock::time_point sent_time) -> void
Handle congestion event (RFC 9002 Section 7.3.2)

Referenced by kcenon::network::protocols::quic::connection::handle_loss_detection_result().

Here is the caller graph for this function:

◆ on_packet_sent()

auto kcenon::network::protocols::quic::congestion_controller::on_packet_sent ( size_t bytes) -> void

Record bytes sent.

Parameters
bytesNumber of bytes sent

Definition at line 61 of file congestion_controller.cpp.

62{
63 bytes_in_flight_ += bytes;
64}

◆ on_persistent_congestion()

auto kcenon::network::protocols::quic::congestion_controller::on_persistent_congestion ( const rtt_estimator & rtt) -> void

Handle persistent congestion detection (RFC 9002 Section 7.6)

Parameters
rttRTT estimator for PTO calculation

Definition at line 172 of file congestion_controller.cpp.

173{
174 // RFC 9002 Section 7.6: Reset cwnd to minimum
178 congestion_recovery_start_ = std::chrono::steady_clock::time_point{};
179}

References kcenon::network::protocols::quic::slow_start.

◆ reset()

auto kcenon::network::protocols::quic::congestion_controller::reset ( ) -> void

Reset congestion controller to initial state.

Definition at line 203 of file congestion_controller.cpp.

204{
207 ssthresh_ = std::numeric_limits<size_t>::max();
209 congestion_recovery_start_ = std::chrono::steady_clock::time_point{};
210}

References kcenon::network::protocols::quic::slow_start.

◆ set_max_datagram_size()

auto kcenon::network::protocols::quic::congestion_controller::set_max_datagram_size ( size_t size) -> void

Set max datagram size.

Parameters
sizeNew maximum datagram size

Definition at line 193 of file congestion_controller.cpp.

194{
195 max_datagram_size_ = size;
198
199 // Ensure cwnd is at least minimum window
200 cwnd_ = std::max(cwnd_, minimum_window_);
201}

Referenced by kcenon::network::protocols::quic::connection::disable_pmtud(), and kcenon::network::protocols::quic::connection::enable_pmtud().

Here is the caller graph for this function:

◆ ssthresh()

auto kcenon::network::protocols::quic::congestion_controller::ssthresh ( ) const -> size_t
inlinenodiscardnoexcept

Get slow start threshold.

Returns
Current slow start threshold

Definition at line 134 of file congestion_controller.h.

135 {
136 return ssthresh_;
137 }

References ssthresh_.

◆ state()

auto kcenon::network::protocols::quic::congestion_controller::state ( ) const -> congestion_state
inlinenodiscardnoexcept

Get current congestion state.

Returns
Current state

Definition at line 152 of file congestion_controller.h.

153 {
154 return state_;
155 }

References state_.

Member Data Documentation

◆ bytes_in_flight_

size_t kcenon::network::protocols::quic::congestion_controller::bytes_in_flight_ {0}
private

Bytes currently in flight.

Definition at line 195 of file congestion_controller.h.

195{0};

Referenced by available_window(), and bytes_in_flight().

◆ congestion_recovery_start_

std::chrono::steady_clock::time_point kcenon::network::protocols::quic::congestion_controller::congestion_recovery_start_
private

Start of the current congestion recovery period.

Definition at line 201 of file congestion_controller.h.

◆ cwnd_

size_t kcenon::network::protocols::quic::congestion_controller::cwnd_
private

Congestion window in bytes.

Definition at line 189 of file congestion_controller.h.

Referenced by available_window(), congestion_controller(), and cwnd().

◆ initial_window_

size_t kcenon::network::protocols::quic::congestion_controller::initial_window_
private

Initial window size (for reset)

Definition at line 204 of file congestion_controller.h.

Referenced by congestion_controller().

◆ kDefaultMaxDatagramSize

size_t kcenon::network::protocols::quic::congestion_controller::kDefaultMaxDatagramSize = 1200
staticconstexprprivate

Default max datagram size (QUIC minimum guaranteed MTU)

Definition at line 213 of file congestion_controller.h.

◆ kInitialWindowPackets

size_t kcenon::network::protocols::quic::congestion_controller::kInitialWindowPackets = 10
staticconstexprprivate

Number of datagrams for initial window.

Definition at line 216 of file congestion_controller.h.

Referenced by congestion_controller().

◆ kLossReductionFactor

double kcenon::network::protocols::quic::congestion_controller::kLossReductionFactor = 0.5
staticconstexprprivate

Loss reduction factor (RFC 9002 Section 7.3.2)

Definition at line 210 of file congestion_controller.h.

◆ kMinimumWindowPackets

size_t kcenon::network::protocols::quic::congestion_controller::kMinimumWindowPackets = 2
staticconstexprprivate

Minimum window in packets.

Definition at line 219 of file congestion_controller.h.

Referenced by congestion_controller().

◆ max_datagram_size_

size_t kcenon::network::protocols::quic::congestion_controller::max_datagram_size_
private

Maximum datagram size.

Definition at line 198 of file congestion_controller.h.

Referenced by congestion_controller(), and max_datagram_size().

◆ minimum_window_

size_t kcenon::network::protocols::quic::congestion_controller::minimum_window_
private

Minimum window size.

Definition at line 207 of file congestion_controller.h.

Referenced by congestion_controller().

◆ ssthresh_

size_t kcenon::network::protocols::quic::congestion_controller::ssthresh_ {std::numeric_limits<size_t>::max()}
private

Slow start threshold.

Definition at line 192 of file congestion_controller.h.

192{std::numeric_limits<size_t>::max()};

Referenced by ssthresh().

◆ state_

congestion_state kcenon::network::protocols::quic::congestion_controller::state_ {congestion_state::slow_start}
private

Current congestion state.

Definition at line 186 of file congestion_controller.h.

Referenced by state().


The documentation for this class was generated from the following files: