Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
connection.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
10#include "crypto.h"
11#include "flow_control.h"
12#include "frame.h"
13#include "loss_detector.h"
14#include "packet.h"
15#include "pmtud_controller.h"
16#include "rtt_estimator.h"
17#include "stream_manager.h"
18#include "transport_params.h"
20
21#include <chrono>
22#include <deque>
23#include <functional>
24#include <map>
25#include <memory>
26#include <mutex>
27#include <optional>
28#include <span>
29#include <string>
30#include <vector>
31
32#if defined(NETWORK_ENABLE_TEST_INJECTION)
33namespace kcenon::network::tests::support
34{
35 class quic_connection_test_access;
36} // namespace kcenon::network::tests::support
37#endif
38
40{
41
42// ============================================================================
43// Connection State Enums
44// ============================================================================
45
50{
51 idle,
53 connected,
54 closing,
55 draining,
56 closed,
57};
58
69
73[[nodiscard]] auto connection_state_to_string(connection_state state) -> const char*;
74
78[[nodiscard]] auto handshake_state_to_string(handshake_state state) -> const char*;
79
80// ============================================================================
81// Connection Error Codes
82// ============================================================================
83
84namespace connection_error
85{
86 constexpr int not_established = -730;
87 constexpr int handshake_failed = -731;
88 constexpr int invalid_state = -732;
89 constexpr int protocol_violation = -733;
90 constexpr int connection_refused = -734;
91 constexpr int idle_timeout = -735;
92 constexpr int connection_closed = -736;
93} // namespace connection_error
94
95// ============================================================================
96// Sent Packet Tracking
97// ============================================================================
98
104{
105 uint64_t packet_number{0};
106 std::chrono::steady_clock::time_point sent_time;
107 size_t sent_bytes{0};
108 bool ack_eliciting{false};
109 bool in_flight{false};
111
112 // Frames included in this packet (for retransmission)
113 std::vector<frame> frames;
114};
115
116// ============================================================================
117// Packet Number Space
118// ============================================================================
119
125{
127 uint64_t next_pn{0};
128
130 uint64_t largest_acked{0};
131
133 uint64_t largest_received{0};
134
136 std::chrono::steady_clock::time_point largest_received_time;
137
139 std::map<uint64_t, sent_packet_info> sent_packets;
140
142 bool ack_needed{false};
143
145 std::chrono::microseconds ack_delay{0};
146};
147
148// ============================================================================
149// Connection Class
150// ============================================================================
151
165{
166public:
173
175
176 // Non-copyable and non-movable (members are not movable)
177 connection(const connection&) = delete;
178 auto operator=(const connection&) -> connection& = delete;
180 auto operator=(connection&&) -> connection& = delete;
181
182 // ========================================================================
183 // Connection State
184 // ========================================================================
185
189 [[nodiscard]] auto state() const noexcept -> connection_state { return state_; }
190
194 [[nodiscard]] auto handshake_state() const noexcept -> enum handshake_state
195 {
196 return hs_state_;
197 }
198
202 [[nodiscard]] auto is_established() const noexcept -> bool
203 {
205 }
206
210 [[nodiscard]] auto is_draining() const noexcept -> bool
211 {
214 }
215
219 [[nodiscard]] auto is_closed() const noexcept -> bool
220 {
222 }
223
227 [[nodiscard]] auto is_server() const noexcept -> bool { return is_server_; }
228
229 // ========================================================================
230 // Connection IDs
231 // ========================================================================
232
236 [[nodiscard]] auto local_cid() const -> const connection_id& { return local_cid_; }
237
241 [[nodiscard]] auto remote_cid() const -> const connection_id& { return remote_cid_; }
242
246 [[nodiscard]] auto initial_dcid() const -> const connection_id& { return initial_dcid_; }
247
254 [[nodiscard]] auto add_local_cid(const connection_id& cid, uint64_t sequence)
255 -> VoidResult;
256
262 [[nodiscard]] auto retire_cid(uint64_t sequence) -> VoidResult;
263
268 {
269 return peer_cid_manager_;
270 }
271
275 [[nodiscard]] auto peer_cid_manager() const -> const connection_id_manager&
276 {
277 return peer_cid_manager_;
278 }
279
286 [[nodiscard]] auto active_peer_cid() const -> const connection_id&;
287
294 [[nodiscard]] auto rotate_peer_cid() -> VoidResult;
295
296 // ========================================================================
297 // Transport Parameters
298 // ========================================================================
299
304 void set_local_params(const transport_parameters& params);
305
310 void set_remote_params(const transport_parameters& params);
311
315 [[nodiscard]] auto local_params() const -> const transport_parameters&
316 {
317 return local_params_;
318 }
319
323 [[nodiscard]] auto remote_params() const -> const transport_parameters&
324 {
325 return remote_params_;
326 }
327
328 // ========================================================================
329 // Handshake
330 // ========================================================================
331
337 [[nodiscard]] auto start_handshake(const std::string& server_name)
339
346 [[nodiscard]] auto init_server_handshake(const std::string& cert_file,
347 const std::string& key_file) -> VoidResult;
348
349 // ========================================================================
350 // Packet Processing
351 // ========================================================================
352
358 [[nodiscard]] auto receive_packet(std::span<const uint8_t> data) -> VoidResult;
359
364 [[nodiscard]] auto generate_packets() -> std::vector<std::vector<uint8_t>>;
365
369 [[nodiscard]] auto has_pending_data() const -> bool;
370
371 // ========================================================================
372 // Stream Access
373 // ========================================================================
374
378 [[nodiscard]] auto streams() -> stream_manager& { return stream_mgr_; }
379
383 [[nodiscard]] auto streams() const -> const stream_manager& { return stream_mgr_; }
384
385 // ========================================================================
386 // Flow Control
387 // ========================================================================
388
392 [[nodiscard]] auto flow_control() -> flow_controller& { return flow_ctrl_; }
393
397 [[nodiscard]] auto flow_control() const -> const flow_controller& { return flow_ctrl_; }
398
399 // ========================================================================
400 // Connection Close
401 // ========================================================================
402
409 [[nodiscard]] auto close(uint64_t error_code, const std::string& reason = "")
410 -> VoidResult;
411
418 [[nodiscard]] auto close_application(uint64_t error_code,
419 const std::string& reason = "") -> VoidResult;
420
424 [[nodiscard]] auto close_error_code() const -> std::optional<uint64_t>
425 {
426 return close_error_code_;
427 }
428
432 [[nodiscard]] auto close_reason() const -> const std::string& { return close_reason_; }
433
434 // ========================================================================
435 // Timers
436 // ========================================================================
437
442 [[nodiscard]] auto next_timeout() const
443 -> std::optional<std::chrono::steady_clock::time_point>;
444
448 void on_timeout();
449
453 [[nodiscard]] auto idle_deadline() const -> std::chrono::steady_clock::time_point
454 {
455 return idle_deadline_;
456 }
457
458 // ========================================================================
459 // Crypto Access
460 // ========================================================================
461
465 [[nodiscard]] auto crypto() -> quic_crypto& { return crypto_; }
466
470 [[nodiscard]] auto crypto() const -> const quic_crypto& { return crypto_; }
471
472 // ========================================================================
473 // Path MTU Discovery (RFC 9000 Section 14, RFC 8899)
474 // ========================================================================
475
480 [[nodiscard]] auto path_mtu() const noexcept -> size_t;
481
488 void enable_pmtud();
489
495 void disable_pmtud();
496
501 [[nodiscard]] auto pmtud_enabled() const noexcept -> bool;
502
506 [[nodiscard]] auto pmtud() -> pmtud_controller& { return pmtud_controller_; }
507
511 [[nodiscard]] auto pmtud() const -> const pmtud_controller& { return pmtud_controller_; }
512
513 // ========================================================================
514 // Statistics
515 // ========================================================================
516
520 [[nodiscard]] auto bytes_sent() const noexcept -> uint64_t { return bytes_sent_; }
521
525 [[nodiscard]] auto bytes_received() const noexcept -> uint64_t { return bytes_received_; }
526
530 [[nodiscard]] auto packets_sent() const noexcept -> uint64_t { return packets_sent_; }
531
535 [[nodiscard]] auto packets_received() const noexcept -> uint64_t
536 {
537 return packets_received_;
538 }
539
540private:
541 // ========================================================================
542 // Private Members
543 // ========================================================================
544
547 enum handshake_state hs_state_ { handshake_state::initial };
548
549 // Connection IDs
552 connection_id initial_dcid_; // For initial key derivation
553 std::vector<std::pair<uint64_t, connection_id>> local_cids_;
555 connection_id_manager peer_cid_manager_; // Manages peer CIDs (RFC 9000 Section 5.1)
556
557 // Transport parameters
560
561 // Subsystems
565
566 // Loss detection and congestion control (RFC 9002)
570
571 // Path MTU Discovery (RFC 8899)
573
574 // Packet number spaces
578
579 // Pending crypto data per encryption level
580 std::deque<std::vector<uint8_t>> pending_crypto_initial_;
581 std::deque<std::vector<uint8_t>> pending_crypto_handshake_;
582 std::deque<std::vector<uint8_t>> pending_crypto_app_;
583
584 // Pending ACKs per encryption level
587 bool pending_ack_app_{false};
588
589 // Pending frames to send
590 std::deque<frame> pending_frames_;
591
592 // Close state
593 bool close_sent_{false};
594 bool close_received_{false};
595 std::optional<uint64_t> close_error_code_;
596 std::string close_reason_;
598
599 // Timers
600 std::chrono::steady_clock::time_point idle_deadline_;
601 std::chrono::steady_clock::time_point pto_deadline_;
602 std::chrono::steady_clock::time_point drain_deadline_;
603
604 // Statistics
605 uint64_t bytes_sent_{0};
606 uint64_t bytes_received_{0};
607 uint64_t packets_sent_{0};
608 uint64_t packets_received_{0};
609
610 // ========================================================================
611 // Private Methods
612 // ========================================================================
613
617 [[nodiscard]] auto process_long_header_packet(const long_header& hdr,
618 std::span<const uint8_t> payload)
619 -> VoidResult;
620
624 [[nodiscard]] auto process_short_header_packet(const short_header& hdr,
625 std::span<const uint8_t> payload)
626 -> VoidResult;
627
631 [[nodiscard]] auto process_frames(std::span<const uint8_t> payload,
633
637 [[nodiscard]] auto handle_frame(const frame& frame, encryption_level level)
638 -> VoidResult;
639
643 [[nodiscard]] auto build_packet(encryption_level level) -> std::vector<uint8_t>;
644
648 [[nodiscard]] auto get_pn_space(encryption_level level) -> packet_number_space&;
649 [[nodiscard]] auto get_pn_space(encryption_level level) const
650 -> const packet_number_space&;
651
655 void update_state();
656
660 void reset_idle_timer();
661
665 void enter_draining();
666
670 void enter_closing();
671
675 void apply_remote_params();
676
680 [[nodiscard]] auto generate_ack_frame(const packet_number_space& space)
681 -> std::optional<ack_frame>;
682
688
694
699 void queue_frames_for_retransmission(const sent_packet& lost_packet);
700
704 [[nodiscard]] auto to_sent_packet(const sent_packet_info& info) const -> sent_packet;
705
706#if defined(NETWORK_ENABLE_TEST_INJECTION)
707 // Test-only: grants tests/support/quic_connection_test_access access to
708 // private dispatch helpers (handle_frame, process_frames, build_packet,
709 // generate_ack_frame, handle_loss_detection_result, generate_probe_packets,
710 // queue_frames_for_retransmission, update_state) and member fields so
711 // tests can drive branches that are otherwise reachable only after a
712 // full TLS handshake. The handshake exceeds the wait_for budget under
713 // -fprofile-arcs -ftest-coverage instrumentation (Issue #1111 / #1145).
714 friend class kcenon::network::tests::support::quic_connection_test_access;
715#endif
716};
717
718} // namespace kcenon::network::protocols::quic
QUIC congestion control (RFC 9002 Section 7)
Manages peer connection IDs for QUIC connections (RFC 9000 Section 5.1)
QUIC Connection ID (RFC 9000 Section 5.1)
QUIC connection state machine (RFC 9000 Section 5)
Definition connection.h:165
std::chrono::steady_clock::time_point idle_deadline_
Definition connection.h:600
void generate_probe_packets()
Generate probe packets for PTO (RFC 9002 Section 6.2.4) Sends one or two ack-eliciting packets to pro...
void enable_pmtud()
Enable Path MTU Discovery.
std::deque< std::vector< uint8_t > > pending_crypto_app_
Definition connection.h:582
auto handle_frame(const frame &frame, encryption_level level) -> VoidResult
Handle a specific frame.
void disable_pmtud()
Disable Path MTU Discovery.
auto packets_sent() const noexcept -> uint64_t
Get packets sent count.
Definition connection.h:530
std::deque< std::vector< uint8_t > > pending_crypto_initial_
Definition connection.h:580
auto operator=(connection &&) -> connection &=delete
auto remote_params() const -> const transport_parameters &
Get remote transport parameters.
Definition connection.h:323
auto is_established() const noexcept -> bool
Check if connection is established (handshake complete)
Definition connection.h:202
void update_state()
Update connection state based on handshake progress.
auto next_timeout() const -> std::optional< std::chrono::steady_clock::time_point >
Get the next timeout deadline.
auto is_draining() const noexcept -> bool
Check if connection is draining or closing.
Definition connection.h:210
auto init_server_handshake(const std::string &cert_file, const std::string &key_file) -> VoidResult
Initialize server handshake.
auto rotate_peer_cid() -> VoidResult
Rotate to a new peer connection ID.
auto packets_received() const noexcept -> uint64_t
Get packets received count.
Definition connection.h:535
auto receive_packet(std::span< const uint8_t > data) -> VoidResult
Receive and process a packet.
void enter_draining()
Transition to draining state.
auto initial_dcid() const -> const connection_id &
Get initial Destination Connection ID (for key derivation)
Definition connection.h:246
void apply_remote_params()
Apply remote transport parameters.
std::chrono::steady_clock::time_point drain_deadline_
Definition connection.h:602
auto flow_control() const -> const flow_controller &
Get the connection-level flow controller (const)
Definition connection.h:397
auto get_pn_space(encryption_level level) -> packet_number_space &
Get packet number space for an encryption level.
auto remote_cid() const -> const connection_id &
Get remote Connection ID.
Definition connection.h:241
auto is_server() const noexcept -> bool
Check if this is a server-side connection.
Definition connection.h:227
auto pmtud() -> pmtud_controller &
Get the PMTUD controller.
Definition connection.h:506
auto idle_deadline() const -> std::chrono::steady_clock::time_point
Get idle timeout deadline.
Definition connection.h:453
void set_local_params(const transport_parameters &params)
Set local transport parameters.
auto generate_ack_frame(const packet_number_space &space) -> std::optional< ack_frame >
Generate ACK frame for a packet number space.
auto flow_control() -> flow_controller &
Get the connection-level flow controller.
Definition connection.h:392
auto generate_packets() -> std::vector< std::vector< uint8_t > >
Generate packets to send.
void enter_closing()
Transition to closing state.
auto bytes_received() const noexcept -> uint64_t
Get total bytes received.
Definition connection.h:525
auto path_mtu() const noexcept -> size_t
Get current path MTU.
std::optional< uint64_t > close_error_code_
Definition connection.h:595
std::deque< std::vector< uint8_t > > pending_crypto_handshake_
Definition connection.h:581
auto has_pending_data() const -> bool
Check if there are packets to send.
auto close_reason() const -> const std::string &
Get the close reason (if connection was closed)
Definition connection.h:432
auto crypto() -> quic_crypto &
Get crypto handler.
Definition connection.h:465
auto close_error_code() const -> std::optional< uint64_t >
Get the close error code (if connection was closed)
Definition connection.h:424
auto local_params() const -> const transport_parameters &
Get local transport parameters.
Definition connection.h:315
auto operator=(const connection &) -> connection &=delete
auto retire_cid(uint64_t sequence) -> VoidResult
Retire a Connection ID.
auto is_closed() const noexcept -> bool
Check if connection is closed.
Definition connection.h:219
void queue_frames_for_retransmission(const sent_packet &lost_packet)
Queue frames from lost packet for retransmission.
auto close(uint64_t error_code, const std::string &reason="") -> VoidResult
Close the connection.
auto process_frames(std::span< const uint8_t > payload, encryption_level level) -> VoidResult
Process frames from a decrypted packet.
auto build_packet(encryption_level level) -> std::vector< uint8_t >
Build a packet at the given encryption level.
void handle_loss_detection_result(const loss_detection_result &result)
Handle loss detection result (RFC 9002)
auto start_handshake(const std::string &server_name) -> Result< std::vector< uint8_t > >
Start the handshake (client only)
auto streams() const -> const stream_manager &
Get the stream manager (const)
Definition connection.h:383
auto local_cid() const -> const connection_id &
Get local Connection ID.
Definition connection.h:236
auto streams() -> stream_manager &
Get the stream manager.
Definition connection.h:378
auto add_local_cid(const connection_id &cid, uint64_t sequence) -> VoidResult
Add a new local Connection ID.
std::vector< std::pair< uint64_t, connection_id > > local_cids_
Definition connection.h:553
auto state() const noexcept -> connection_state
Get current connection state.
Definition connection.h:189
auto process_short_header_packet(const short_header &hdr, std::span< const uint8_t > payload) -> VoidResult
Process a short header packet.
auto close_application(uint64_t error_code, const std::string &reason="") -> VoidResult
Close connection due to application error.
auto handshake_state() const noexcept -> enum handshake_state
Get current handshake state.
Definition connection.h:194
void set_remote_params(const transport_parameters &params)
Set remote transport parameters.
auto process_long_header_packet(const long_header &hdr, std::span< const uint8_t > payload) -> VoidResult
Process a long header packet.
std::chrono::steady_clock::time_point pto_deadline_
Definition connection.h:601
auto peer_cid_manager() const -> const connection_id_manager &
Get the peer connection ID manager (const)
Definition connection.h:275
auto active_peer_cid() const -> const connection_id &
Get the currently active peer connection ID.
auto to_sent_packet(const sent_packet_info &info) const -> sent_packet
Convert sent_packet_info to sent_packet for loss detector.
auto crypto() const -> const quic_crypto &
Get crypto handler (const)
Definition connection.h:470
auto bytes_sent() const noexcept -> uint64_t
Get total bytes sent.
Definition connection.h:520
auto pmtud_enabled() const noexcept -> bool
Check if PMTUD is enabled.
auto pmtud() const -> const pmtud_controller &
Get the PMTUD controller (const)
Definition connection.h:511
auto peer_cid_manager() -> connection_id_manager &
Get the peer connection ID manager.
Definition connection.h:267
Connection-level flow control for QUIC (RFC 9000 Section 4)
QUIC loss detection (RFC 9002 Section 6)
QUIC packet number utilities (RFC 9000 Section 17.1)
Definition packet.h:174
Path MTU Discovery controller for QUIC (RFC 8899 DPLPMTUD)
QUIC-TLS integration handler (RFC 9001)
Definition crypto.h:245
RTT estimation for QUIC (RFC 9002 Section 5)
Manages QUIC streams within a connection.
QUIC connection identifier type.
connection_state
QUIC connection state (RFC 9000 Section 5)
Definition connection.h:50
@ connected
Handshake complete, can send/receive data.
@ closing
CONNECTION_CLOSE sent, waiting for timeout.
@ draining
CONNECTION_CLOSE received, draining period.
encryption_level
QUIC encryption levels (RFC 9001 Section 4)
Definition keys.h:54
@ initial
Initial encryption (derived from DCID)
std::variant< padding_frame, ping_frame, ack_frame, reset_stream_frame, stop_sending_frame, crypto_frame, new_token_frame, stream_frame, max_data_frame, max_stream_data_frame, max_streams_frame, data_blocked_frame, stream_data_blocked_frame, streams_blocked_frame, new_connection_id_frame, retire_connection_id_frame, path_challenge_frame, path_response_frame, connection_close_frame, handshake_done_frame > frame
Variant type holding any QUIC frame.
auto handshake_state_to_string(handshake_state state) -> const char *
Convert handshake state to string.
handshake_state
TLS handshake state.
Definition connection.h:63
@ waiting_server_hello
Client waiting for ServerHello.
@ waiting_finished
Waiting for peer's Finished.
auto connection_state_to_string(connection_state state) -> const char *
Convert connection state to string.
Result< std::monostate > VoidResult
Network-specific error and result type definitions.
QUIC Long Header format (RFC 9000 Section 17.2)
Definition packet.h:95
State for each packet number space (Initial, Handshake, Application)
Definition connection.h:125
std::chrono::microseconds ack_delay
ACK delay for this space.
Definition connection.h:145
uint64_t largest_received
Largest received packet number.
Definition connection.h:133
std::chrono::steady_clock::time_point largest_received_time
Time of receiving largest packet.
Definition connection.h:136
std::map< uint64_t, sent_packet_info > sent_packets
Packets awaiting acknowledgment.
Definition connection.h:139
uint64_t largest_acked
Largest acknowledged packet number.
Definition connection.h:130
uint64_t next_pn
Next packet number to use.
Definition connection.h:127
Information about a sent packet for loss detection.
Definition connection.h:104
std::chrono::steady_clock::time_point sent_time
Definition connection.h:106
Information about a sent packet for loss detection (RFC 9002 Section A.1.1)
QUIC Short Header format (RFC 9000 Section 17.3)
Definition packet.h:138
QUIC transport parameters (RFC 9000 Section 18)