Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
pmtud_controller.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#pragma once
6
7#include <chrono>
8#include <cstddef>
9#include <optional>
10
12{
13
18enum class pmtud_state
19{
20 disabled,
21 base,
22 searching,
24 error,
25};
26
30[[nodiscard]] auto pmtud_state_to_string(pmtud_state state) noexcept -> const char*;
31
37{
39 size_t min_mtu = 1200;
40
42 size_t max_probe_mtu = 1500;
43
45 size_t probe_step = 32;
46
48 std::chrono::seconds probe_timeout{3};
49
51 size_t max_probes = 3;
52
54 std::chrono::milliseconds probe_interval{1000};
55
57 std::chrono::seconds confirmation_interval{600}; // 10 minutes
58};
59
75{
76public:
81
87
88 // ========================================================================
89 // MTU Access
90 // ========================================================================
91
96 [[nodiscard]] auto current_mtu() const noexcept -> size_t
97 {
98 return current_mtu_;
99 }
100
105 [[nodiscard]] auto min_mtu() const noexcept -> size_t
106 {
107 return config_.min_mtu;
108 }
109
114 [[nodiscard]] auto max_mtu() const noexcept -> size_t
115 {
116 return config_.max_probe_mtu;
117 }
118
119 // ========================================================================
120 // State Access
121 // ========================================================================
122
127 [[nodiscard]] auto state() const noexcept -> pmtud_state
128 {
129 return state_;
130 }
131
136 [[nodiscard]] auto is_enabled() const noexcept -> bool
137 {
139 }
140
145 [[nodiscard]] auto is_search_complete() const noexcept -> bool
146 {
148 }
149
150 // ========================================================================
151 // Control
152 // ========================================================================
153
160 void enable();
161
167 void disable();
168
174 void reset();
175
176 // ========================================================================
177 // Probing
178 // ========================================================================
179
185 [[nodiscard]] auto should_probe(
186 std::chrono::steady_clock::time_point now) const noexcept -> bool;
187
192 [[nodiscard]] auto probe_size() const noexcept -> std::optional<size_t>;
193
199 void on_probe_sent(size_t size, std::chrono::steady_clock::time_point sent_time);
200
209 void on_probe_acked(size_t size);
210
218 void on_probe_lost(size_t size);
219
220 // ========================================================================
221 // ICMP Handling
222 // ========================================================================
223
231 void on_packet_too_big(size_t reported_mtu);
232
233 // ========================================================================
234 // Timers
235 // ========================================================================
236
241 [[nodiscard]] auto next_timeout() const noexcept
242 -> std::optional<std::chrono::steady_clock::time_point>;
243
251 void on_timeout(std::chrono::steady_clock::time_point now);
252
253private:
254 // ========================================================================
255 // Private Methods
256 // ========================================================================
257
261 void start_search();
262
267 [[nodiscard]] auto calculate_next_probe_size() const noexcept -> size_t;
268
272 void complete_search();
273
277 void handle_black_hole();
278
279 // ========================================================================
280 // Private Members
281 // ========================================================================
282
285
288
291
294
297
299 size_t probing_mtu_{0};
300
302 size_t probe_count_{0};
303
306
308 std::chrono::steady_clock::time_point last_probe_time_;
309
311 std::chrono::steady_clock::time_point search_complete_time_;
312
314 bool probe_in_flight_{false};
315
317 static constexpr size_t kBlackHoleThreshold = 6;
318};
319
320} // namespace kcenon::network::protocols::quic
Path MTU Discovery controller for QUIC (RFC 8899 DPLPMTUD)
void complete_search()
Transition to search_complete state.
std::chrono::steady_clock::time_point last_probe_time_
Time of last probe sent.
void on_packet_too_big(size_t reported_mtu)
Handle ICMP Packet Too Big message.
pmtud_controller()
Default constructor with default configuration.
size_t search_high_
Upper bound for binary search (target MTU)
auto is_enabled() const noexcept -> bool
Check if PMTUD is enabled.
void on_probe_sent(size_t size, std::chrono::steady_clock::time_point sent_time)
Record that a probe was sent.
void enable()
Enable PMTUD and start probing.
size_t search_low_
Lower bound for binary search (known good MTU)
auto is_search_complete() const noexcept -> bool
Check if MTU search is complete.
size_t probe_count_
Number of probes sent at current size.
static constexpr size_t kBlackHoleThreshold
Threshold for black hole detection.
auto next_timeout() const noexcept -> std::optional< std::chrono::steady_clock::time_point >
Get next timeout deadline for PMTUD.
bool probe_in_flight_
Whether a probe is currently in flight.
void on_probe_acked(size_t size)
Handle probe acknowledgment.
void on_probe_lost(size_t size)
Handle probe loss.
auto min_mtu() const noexcept -> size_t
Get minimum MTU.
auto max_mtu() const noexcept -> size_t
Get maximum MTU being probed.
auto current_mtu() const noexcept -> size_t
Get current validated MTU.
size_t consecutive_failures_
Number of consecutive probe failures (for black hole detection)
std::chrono::steady_clock::time_point search_complete_time_
Time when search was completed (for re-validation)
auto should_probe(std::chrono::steady_clock::time_point now) const noexcept -> bool
Check if a probe should be sent.
auto state() const noexcept -> pmtud_state
Get current PMTUD state.
size_t probing_mtu_
Current probe size being tested.
auto calculate_next_probe_size() const noexcept -> size_t
Calculate next probe size using binary search.
auto probe_size() const noexcept -> std::optional< size_t >
Get the size for next probe packet.
void on_timeout(std::chrono::steady_clock::time_point now)
Handle timeout event.
void handle_black_hole()
Handle black hole detection.
tracing_config config
Definition exporters.cpp:29
pmtud_state
States for DPLPMTUD state machine (RFC 8899 Section 5.2)
@ search_complete
Maximum MTU found and validated.
@ base
Using BASE_PLPMTU (minimum MTU)
@ searching
Binary search for larger MTU.
@ error
Black hole detected, reset to base.
auto pmtud_state_to_string(pmtud_state state) noexcept -> const char *
Convert PMTUD state to string.
Configuration for PMTUD controller.
std::chrono::seconds probe_timeout
Timeout for probe packets before considering them lost.
std::chrono::milliseconds probe_interval
Interval between probe attempts during search.
size_t max_probes
Maximum number of probes before giving up at current size.
size_t probe_step
Step size for probing (binary search uses mid-point)
size_t max_probe_mtu
Maximum MTU to probe (typical Ethernet is 1500)
std::chrono::seconds confirmation_interval
Interval for re-validation after search is complete.
size_t min_mtu
Minimum MTU (RFC 9000 requires 1200 bytes for QUIC)