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

Path MTU Discovery controller for QUIC (RFC 8899 DPLPMTUD) More...

#include <pmtud_controller.h>

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

Public Member Functions

 pmtud_controller ()
 Default constructor with default configuration.
 
 pmtud_controller (pmtud_config config)
 Constructor with custom configuration.
 
auto current_mtu () const noexcept -> size_t
 Get current validated MTU.
 
auto min_mtu () const noexcept -> size_t
 Get minimum MTU.
 
auto max_mtu () const noexcept -> size_t
 Get maximum MTU being probed.
 
auto state () const noexcept -> pmtud_state
 Get current PMTUD state.
 
auto is_enabled () const noexcept -> bool
 Check if PMTUD is enabled.
 
auto is_search_complete () const noexcept -> bool
 Check if MTU search is complete.
 
void enable ()
 Enable PMTUD and start probing.
 
void disable ()
 Disable PMTUD.
 
void reset ()
 Reset to initial state.
 
auto should_probe (std::chrono::steady_clock::time_point now) const noexcept -> bool
 Check if a probe should be sent.
 
auto probe_size () const noexcept -> std::optional< size_t >
 Get the size for next probe packet.
 
void on_probe_sent (size_t size, std::chrono::steady_clock::time_point sent_time)
 Record that a probe was sent.
 
void on_probe_acked (size_t size)
 Handle probe acknowledgment.
 
void on_probe_lost (size_t size)
 Handle probe loss.
 
void on_packet_too_big (size_t reported_mtu)
 Handle ICMP Packet Too Big message.
 
auto next_timeout () const noexcept -> std::optional< std::chrono::steady_clock::time_point >
 Get next timeout deadline for PMTUD.
 
void on_timeout (std::chrono::steady_clock::time_point now)
 Handle timeout event.
 

Private Member Functions

void start_search ()
 Start probing from base MTU.
 
auto calculate_next_probe_size () const noexcept -> size_t
 Calculate next probe size using binary search.
 
void complete_search ()
 Transition to search_complete state.
 
void handle_black_hole ()
 Handle black hole detection.
 

Private Attributes

pmtud_config config_
 Configuration.
 
pmtud_state state_ {pmtud_state::disabled}
 Current state.
 
size_t current_mtu_
 Current validated MTU.
 
size_t search_low_
 Lower bound for binary search (known good MTU)
 
size_t search_high_
 Upper bound for binary search (target MTU)
 
size_t probing_mtu_ {0}
 Current probe size being tested.
 
size_t probe_count_ {0}
 Number of probes sent at current size.
 
size_t consecutive_failures_ {0}
 Number of consecutive probe failures (for black hole detection)
 
std::chrono::steady_clock::time_point last_probe_time_
 Time of last probe sent.
 
std::chrono::steady_clock::time_point search_complete_time_
 Time when search was completed (for re-validation)
 
bool probe_in_flight_ {false}
 Whether a probe is currently in flight.
 

Static Private Attributes

static constexpr size_t kBlackHoleThreshold = 6
 Threshold for black hole detection.
 

Detailed Description

Path MTU Discovery controller for QUIC (RFC 8899 DPLPMTUD)

Implements Datagram Packetization Layer PMTU Discovery (DPLPMTUD) as specified in RFC 8899 for use with QUIC (RFC 9000 Section 14).

The controller maintains a state machine that:

  • Starts at the minimum QUIC MTU (1200 bytes)
  • Probes for larger MTU using binary search
  • Handles probe acknowledgments and losses
  • Responds to ICMP Packet Too Big messages
  • Periodically re-validates discovered MTU

Definition at line 74 of file pmtud_controller.h.

Constructor & Destructor Documentation

◆ pmtud_controller() [1/2]

kcenon::network::protocols::quic::pmtud_controller::pmtud_controller ( )

Default constructor with default configuration.

Definition at line 30 of file pmtud_controller.cpp.

31 : pmtud_controller(pmtud_config{})
32{
33}
pmtud_controller()
Default constructor with default configuration.

◆ pmtud_controller() [2/2]

kcenon::network::protocols::quic::pmtud_controller::pmtud_controller ( pmtud_config config)
explicit

Constructor with custom configuration.

Parameters
configConfiguration parameters

Definition at line 35 of file pmtud_controller.cpp.

36 : config_(config)
40{
41}
size_t search_high_
Upper bound for binary search (target MTU)
size_t search_low_
Lower bound for binary search (known good MTU)
size_t max_probe_mtu
Maximum MTU to probe (typical Ethernet is 1500)
size_t min_mtu
Minimum MTU (RFC 9000 requires 1200 bytes for QUIC)

References config.

Member Function Documentation

◆ calculate_next_probe_size()

auto kcenon::network::protocols::quic::pmtud_controller::calculate_next_probe_size ( ) const -> size_t
nodiscardprivatenoexcept

Calculate next probe size using binary search.

Returns
Next MTU to probe

Definition at line 315 of file pmtud_controller.cpp.

316{
317 // Binary search - probe the midpoint
318 size_t mid = search_low_ + (search_high_ - search_low_) / 2;
319
320 // Round up to ensure we make progress
321 if (mid == search_low_ && search_high_ > search_low_)
322 {
324 }
325
326 return std::min(mid, search_high_);
327}
size_t probe_step
Step size for probing (binary search uses mid-point)

References config_, kcenon::network::protocols::quic::pmtud_config::probe_step, search_high_, and search_low_.

Referenced by on_packet_too_big(), on_probe_acked(), on_probe_lost(), and start_search().

Here is the caller graph for this function:

◆ complete_search()

void kcenon::network::protocols::quic::pmtud_controller::complete_search ( )
private

Transition to search_complete state.

Definition at line 329 of file pmtud_controller.cpp.

330{
332 search_complete_time_ = std::chrono::steady_clock::now();
333 probing_mtu_ = 0;
334 probe_count_ = 0;
335}
size_t probe_count_
Number of probes sent at current size.
std::chrono::steady_clock::time_point search_complete_time_
Time when search was completed (for re-validation)
size_t probing_mtu_
Current probe size being tested.
@ search_complete
Maximum MTU found and validated.

References probe_count_, probing_mtu_, kcenon::network::protocols::quic::search_complete, search_complete_time_, and state_.

Referenced by on_probe_acked(), and on_probe_lost().

Here is the caller graph for this function:

◆ current_mtu()

auto kcenon::network::protocols::quic::pmtud_controller::current_mtu ( ) const -> size_t
inlinenodiscardnoexcept

Get current validated MTU.

Returns
Current MTU to use for sending packets

Definition at line 96 of file pmtud_controller.h.

97 {
98 return current_mtu_;
99 }

References current_mtu_.

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

Here is the caller graph for this function:

◆ disable()

void kcenon::network::protocols::quic::pmtud_controller::disable ( )

Disable PMTUD.

Stops probing and reverts to minimum MTU.

Definition at line 58 of file pmtud_controller.cpp.

References config_, current_mtu_, kcenon::network::protocols::quic::disabled, kcenon::network::protocols::quic::pmtud_config::min_mtu, probe_in_flight_, probing_mtu_, and state_.

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

Here is the caller graph for this function:

◆ enable()

void kcenon::network::protocols::quic::pmtud_controller::enable ( )

Enable PMTUD and start probing.

Transitions from disabled state to base state and begins the MTU discovery process.

Definition at line 43 of file pmtud_controller.cpp.

44{
46 {
51 probe_count_ = 0;
53 probe_in_flight_ = false;
55 }
56}
size_t consecutive_failures_
Number of consecutive probe failures (for black hole detection)
@ base
Using BASE_PLPMTU (minimum MTU)

References kcenon::network::protocols::quic::base, config_, consecutive_failures_, current_mtu_, kcenon::network::protocols::quic::disabled, kcenon::network::protocols::quic::pmtud_config::max_probe_mtu, kcenon::network::protocols::quic::pmtud_config::min_mtu, probe_count_, probe_in_flight_, search_high_, search_low_, start_search(), and state_.

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

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_black_hole()

void kcenon::network::protocols::quic::pmtud_controller::handle_black_hole ( )
private

◆ is_enabled()

auto kcenon::network::protocols::quic::pmtud_controller::is_enabled ( ) const -> bool
inlinenodiscardnoexcept

Check if PMTUD is enabled.

Returns
True if PMTUD is enabled and running

Definition at line 136 of file pmtud_controller.h.

137 {
139 }

References kcenon::network::protocols::quic::disabled, and state_.

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

Here is the caller graph for this function:

◆ is_search_complete()

auto kcenon::network::protocols::quic::pmtud_controller::is_search_complete ( ) const -> bool
inlinenodiscardnoexcept

Check if MTU search is complete.

Returns
True if maximum MTU has been found

Definition at line 145 of file pmtud_controller.h.

146 {
148 }

References kcenon::network::protocols::quic::search_complete, and state_.

◆ max_mtu()

auto kcenon::network::protocols::quic::pmtud_controller::max_mtu ( ) const -> size_t
inlinenodiscardnoexcept

Get maximum MTU being probed.

Returns
Maximum MTU target

Definition at line 114 of file pmtud_controller.h.

115 {
116 return config_.max_probe_mtu;
117 }

References config_, and kcenon::network::protocols::quic::pmtud_config::max_probe_mtu.

◆ min_mtu()

auto kcenon::network::protocols::quic::pmtud_controller::min_mtu ( ) const -> size_t
inlinenodiscardnoexcept

Get minimum MTU.

Returns
Minimum guaranteed MTU (BASE_PLPMTU)

Definition at line 105 of file pmtud_controller.h.

106 {
107 return config_.min_mtu;
108 }

References config_, and kcenon::network::protocols::quic::pmtud_config::min_mtu.

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

Here is the caller graph for this function:

◆ next_timeout()

auto kcenon::network::protocols::quic::pmtud_controller::next_timeout ( ) const -> std::optional<std::chrono::steady_clock::time_point>
nodiscardnoexcept

Get next timeout deadline for PMTUD.

Returns
Time point for next probe or confirmation, or nullopt if none

Definition at line 256 of file pmtud_controller.cpp.

258{
260 {
261 return std::nullopt;
262 }
263
265 {
266 // Timeout for probe in flight
268 }
269
271 {
273 }
274
276 {
278 }
279
281 {
283 }
284
285 return std::nullopt;
286}
std::chrono::steady_clock::time_point last_probe_time_
Time of last probe sent.
@ searching
Binary search for larger MTU.
std::chrono::seconds probe_timeout
Timeout for probe packets before considering them lost.
std::chrono::milliseconds probe_interval
Interval between probe attempts during search.
std::chrono::seconds confirmation_interval
Interval for re-validation after search is complete.

References kcenon::network::protocols::quic::base, config_, kcenon::network::protocols::quic::pmtud_config::confirmation_interval, kcenon::network::protocols::quic::disabled, kcenon::network::protocols::quic::error, last_probe_time_, probe_in_flight_, kcenon::network::protocols::quic::pmtud_config::probe_interval, kcenon::network::protocols::quic::pmtud_config::probe_timeout, kcenon::network::protocols::quic::search_complete, search_complete_time_, kcenon::network::protocols::quic::searching, and state_.

◆ on_packet_too_big()

void kcenon::network::protocols::quic::pmtud_controller::on_packet_too_big ( size_t reported_mtu)

Handle ICMP Packet Too Big message.

Parameters
reported_mtuMTU reported in the ICMP message

Called when an ICMP PTB message is received. Updates the MTU immediately if the reported value is smaller.

Definition at line 233 of file pmtud_controller.cpp.

234{
235 // RFC 8899: ICMP PTB should trigger immediate MTU reduction
236 if (reported_mtu >= config_.min_mtu && reported_mtu < current_mtu_)
237 {
238 current_mtu_ = reported_mtu;
239 search_high_ = reported_mtu;
240
242 {
243 // Need to restart search with new upper bound
245 probe_count_ = 0;
247 }
248 }
249 else if (reported_mtu < config_.min_mtu)
250 {
251 // PTB reports MTU below QUIC minimum - possible black hole
253 }
254}
auto calculate_next_probe_size() const noexcept -> size_t
Calculate next probe size using binary search.
void handle_black_hole()
Handle black hole detection.

References calculate_next_probe_size(), config_, current_mtu_, handle_black_hole(), kcenon::network::protocols::quic::pmtud_config::min_mtu, probe_count_, probing_mtu_, kcenon::network::protocols::quic::search_complete, search_high_, kcenon::network::protocols::quic::searching, and state_.

Here is the call graph for this function:

◆ on_probe_acked()

void kcenon::network::protocols::quic::pmtud_controller::on_probe_acked ( size_t size)

Handle probe acknowledgment.

Parameters
sizeSize of the probed packet that was acknowledged

Called when a probe packet is acknowledged by the peer. If the probed size is larger than current MTU, updates the validated MTU and continues searching.

Definition at line 147 of file pmtud_controller.cpp.

148{
149 probe_in_flight_ = false;
151
152 // Handle based on current state
154 {
155 // Successful probe - update validated MTU
156 if (size > current_mtu_)
157 {
158 current_mtu_ = size;
159 search_low_ = size;
160 }
161
162 // Check if we've found the maximum
164 {
166 }
167 else
168 {
169 // Continue searching
171 probe_count_ = 0;
173 }
174 }
176 {
177 // Re-validation successful
178 search_complete_time_ = std::chrono::steady_clock::now();
179 }
180 else if (state_ == pmtud_state::error)
181 {
182 // Recovery successful
184 probe_count_ = 0;
186 }
187}
void complete_search()
Transition to search_complete state.

References kcenon::network::protocols::quic::base, calculate_next_probe_size(), complete_search(), config_, consecutive_failures_, current_mtu_, kcenon::network::protocols::quic::error, probe_count_, probe_in_flight_, kcenon::network::protocols::quic::pmtud_config::probe_step, probing_mtu_, kcenon::network::protocols::quic::search_complete, search_complete_time_, search_high_, search_low_, kcenon::network::protocols::quic::searching, and state_.

Here is the call graph for this function:

◆ on_probe_lost()

void kcenon::network::protocols::quic::pmtud_controller::on_probe_lost ( size_t size)

Handle probe loss.

Parameters
sizeSize of the probe packet that was lost

Called when a probe packet is declared lost. Adjusts the search range and may retry probing.

Definition at line 189 of file pmtud_controller.cpp.

190{
191 probe_in_flight_ = false;
193
194 // Check for black hole
196 {
198 return;
199 }
200
202 {
204 {
205 // Too many failures at this size - reduce search range
206 search_high_ = size;
207 probe_count_ = 0;
208
209 // Check if we've converged
211 {
213 }
214 else
215 {
217 }
218 }
219 // Otherwise, will retry the same size on next should_probe()
220 }
222 {
223 // Re-validation failed - MTU may have decreased
224 // Fall back to error state and restart search
229 probe_count_ = 0;
230 }
231}
static constexpr size_t kBlackHoleThreshold
Threshold for black hole detection.
size_t max_probes
Maximum number of probes before giving up at current size.

References kcenon::network::protocols::quic::base, calculate_next_probe_size(), complete_search(), config_, consecutive_failures_, current_mtu_, kcenon::network::protocols::quic::error, handle_black_hole(), kBlackHoleThreshold, kcenon::network::protocols::quic::pmtud_config::max_probes, kcenon::network::protocols::quic::pmtud_config::min_mtu, probe_count_, probe_in_flight_, kcenon::network::protocols::quic::pmtud_config::probe_step, probing_mtu_, kcenon::network::protocols::quic::search_complete, search_high_, search_low_, kcenon::network::protocols::quic::searching, and state_.

Referenced by on_timeout().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_probe_sent()

void kcenon::network::protocols::quic::pmtud_controller::on_probe_sent ( size_t size,
std::chrono::steady_clock::time_point sent_time )

Record that a probe was sent.

Parameters
sizeSize of the probe packet sent
sent_timeTime the probe was sent

Definition at line 138 of file pmtud_controller.cpp.

140{
141 probing_mtu_ = size;
142 last_probe_time_ = sent_time;
143 probe_in_flight_ = true;
144 ++probe_count_;
145}

References last_probe_time_, probe_count_, probe_in_flight_, and probing_mtu_.

◆ on_timeout()

void kcenon::network::protocols::quic::pmtud_controller::on_timeout ( std::chrono::steady_clock::time_point now)

Handle timeout event.

Parameters
nowCurrent time

Called when the PMTUD timer expires. May trigger probe retransmission or state transitions.

Definition at line 288 of file pmtud_controller.cpp.

289{
291 {
292 return;
293 }
294
296 {
297 // Probe timeout - treat as loss
298 auto elapsed = now - last_probe_time_;
299 if (elapsed >= config_.probe_timeout)
300 {
302 }
303 }
304}
void on_probe_lost(size_t size)
Handle probe loss.

References config_, kcenon::network::protocols::quic::disabled, last_probe_time_, on_probe_lost(), probe_in_flight_, kcenon::network::protocols::quic::pmtud_config::probe_timeout, probing_mtu_, and state_.

Here is the call graph for this function:

◆ probe_size()

auto kcenon::network::protocols::quic::pmtud_controller::probe_size ( ) const -> std::optional<size_t>
nodiscardnoexcept

Get the size for next probe packet.

Returns
Size in bytes for the probe packet, or nullopt if no probe needed

Definition at line 117 of file pmtud_controller.cpp.

118{
120 {
121 return std::nullopt;
122 }
123
125 {
126 return probing_mtu_ > 0 ? std::optional<size_t>(probing_mtu_) : std::nullopt;
127 }
128
129 // For re-validation in search_complete state
131 {
132 return current_mtu_;
133 }
134
135 return std::nullopt;
136}

References kcenon::network::protocols::quic::base, current_mtu_, kcenon::network::protocols::quic::disabled, probing_mtu_, kcenon::network::protocols::quic::search_complete, kcenon::network::protocols::quic::searching, and state_.

◆ reset()

◆ should_probe()

auto kcenon::network::protocols::quic::pmtud_controller::should_probe ( std::chrono::steady_clock::time_point now) const -> bool
nodiscardnoexcept

Check if a probe should be sent.

Parameters
nowCurrent time
Returns
True if a probe packet should be generated

Definition at line 78 of file pmtud_controller.cpp.

80{
81 // Don't probe if disabled or probe already in flight
83 {
84 return false;
85 }
86
87 // In base state, always ready to start probing
89 {
90 return true;
91 }
92
93 // In searching state, check if enough time has passed
95 {
96 auto elapsed = now - last_probe_time_;
97 return elapsed >= config_.probe_interval;
98 }
99
100 // In search_complete state, check if re-validation is needed
102 {
103 auto elapsed = now - search_complete_time_;
104 return elapsed >= config_.confirmation_interval;
105 }
106
107 // In error state, check if enough time for recovery
109 {
110 auto elapsed = now - last_probe_time_;
111 return elapsed >= config_.probe_timeout;
112 }
113
114 return false;
115}

References kcenon::network::protocols::quic::base, kcenon::network::protocols::quic::disabled, kcenon::network::protocols::quic::error, kcenon::network::protocols::quic::search_complete, and kcenon::network::protocols::quic::searching.

◆ start_search()

void kcenon::network::protocols::quic::pmtud_controller::start_search ( )
private

Start probing from base MTU.

Definition at line 306 of file pmtud_controller.cpp.

References calculate_next_probe_size(), config_, current_mtu_, kcenon::network::protocols::quic::pmtud_config::max_probe_mtu, probe_count_, probing_mtu_, search_high_, search_low_, kcenon::network::protocols::quic::searching, and state_.

Referenced by enable().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ state()

auto kcenon::network::protocols::quic::pmtud_controller::state ( ) const -> pmtud_state
inlinenodiscardnoexcept

Get current PMTUD state.

Returns
Current state

Definition at line 127 of file pmtud_controller.h.

128 {
129 return state_;
130 }

References state_.

Member Data Documentation

◆ config_

pmtud_config kcenon::network::protocols::quic::pmtud_controller::config_
private

◆ consecutive_failures_

size_t kcenon::network::protocols::quic::pmtud_controller::consecutive_failures_ {0}
private

Number of consecutive probe failures (for black hole detection)

Definition at line 305 of file pmtud_controller.h.

305{0};

Referenced by enable(), handle_black_hole(), on_probe_acked(), on_probe_lost(), and reset().

◆ current_mtu_

size_t kcenon::network::protocols::quic::pmtud_controller::current_mtu_
private

◆ kBlackHoleThreshold

size_t kcenon::network::protocols::quic::pmtud_controller::kBlackHoleThreshold = 6
staticconstexprprivate

Threshold for black hole detection.

Definition at line 317 of file pmtud_controller.h.

Referenced by on_probe_lost().

◆ last_probe_time_

std::chrono::steady_clock::time_point kcenon::network::protocols::quic::pmtud_controller::last_probe_time_
private

Time of last probe sent.

Definition at line 308 of file pmtud_controller.h.

Referenced by next_timeout(), on_probe_sent(), and on_timeout().

◆ probe_count_

size_t kcenon::network::protocols::quic::pmtud_controller::probe_count_ {0}
private

Number of probes sent at current size.

Definition at line 302 of file pmtud_controller.h.

302{0};

Referenced by complete_search(), enable(), handle_black_hole(), on_packet_too_big(), on_probe_acked(), on_probe_lost(), on_probe_sent(), reset(), and start_search().

◆ probe_in_flight_

bool kcenon::network::protocols::quic::pmtud_controller::probe_in_flight_ {false}
private

Whether a probe is currently in flight.

Definition at line 314 of file pmtud_controller.h.

314{false};

Referenced by disable(), enable(), handle_black_hole(), next_timeout(), on_probe_acked(), on_probe_lost(), on_probe_sent(), on_timeout(), and reset().

◆ probing_mtu_

size_t kcenon::network::protocols::quic::pmtud_controller::probing_mtu_ {0}
private

◆ search_complete_time_

std::chrono::steady_clock::time_point kcenon::network::protocols::quic::pmtud_controller::search_complete_time_
private

Time when search was completed (for re-validation)

Definition at line 311 of file pmtud_controller.h.

Referenced by complete_search(), next_timeout(), and on_probe_acked().

◆ search_high_

size_t kcenon::network::protocols::quic::pmtud_controller::search_high_
private

Upper bound for binary search (target MTU)

Definition at line 296 of file pmtud_controller.h.

Referenced by calculate_next_probe_size(), enable(), handle_black_hole(), on_packet_too_big(), on_probe_acked(), on_probe_lost(), reset(), and start_search().

◆ search_low_

size_t kcenon::network::protocols::quic::pmtud_controller::search_low_
private

Lower bound for binary search (known good MTU)

Definition at line 293 of file pmtud_controller.h.

Referenced by calculate_next_probe_size(), enable(), handle_black_hole(), on_probe_acked(), on_probe_lost(), reset(), and start_search().

◆ state_


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