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
33{
34
35// ============================================================================
36// Connection State Enums
37// ============================================================================
38
43{
44 idle,
46 connected,
47 closing,
48 draining,
49 closed,
50};
51
62
66[[nodiscard]] auto connection_state_to_string(connection_state state) -> const char*;
67
71[[nodiscard]] auto handshake_state_to_string(handshake_state state) -> const char*;
72
73// ============================================================================
74// Connection Error Codes
75// ============================================================================
76
77namespace connection_error
78{
79 constexpr int not_established = -730;
80 constexpr int handshake_failed = -731;
81 constexpr int invalid_state = -732;
82 constexpr int protocol_violation = -733;
83 constexpr int connection_refused = -734;
84 constexpr int idle_timeout = -735;
85 constexpr int connection_closed = -736;
86} // namespace connection_error
87
88// ============================================================================
89// Sent Packet Tracking
90// ============================================================================
91
97{
98 uint64_t packet_number{0};
99 std::chrono::steady_clock::time_point sent_time;
100 size_t sent_bytes{0};
101 bool ack_eliciting{false};
102 bool in_flight{false};
104
105 // Frames included in this packet (for retransmission)
106 std::vector<frame> frames;
107};
108
109// ============================================================================
110// Packet Number Space
111// ============================================================================
112
118{
120 uint64_t next_pn{0};
121
123 uint64_t largest_acked{0};
124
126 uint64_t largest_received{0};
127
129 std::chrono::steady_clock::time_point largest_received_time;
130
132 std::map<uint64_t, sent_packet_info> sent_packets;
133
135 bool ack_needed{false};
136
138 std::chrono::microseconds ack_delay{0};
139};
140
141// ============================================================================
142// Connection Class
143// ============================================================================
144
158{
159public:
166
168
169 // Non-copyable and non-movable (members are not movable)
170 connection(const connection&) = delete;
171 auto operator=(const connection&) -> connection& = delete;
173 auto operator=(connection&&) -> connection& = delete;
174
175 // ========================================================================
176 // Connection State
177 // ========================================================================
178
182 [[nodiscard]] auto state() const noexcept -> connection_state { return state_; }
183
187 [[nodiscard]] auto handshake_state() const noexcept -> enum handshake_state
188 {
189 return hs_state_;
190 }
191
195 [[nodiscard]] auto is_established() const noexcept -> bool
196 {
198 }
199
203 [[nodiscard]] auto is_draining() const noexcept -> bool
204 {
207 }
208
212 [[nodiscard]] auto is_closed() const noexcept -> bool
213 {
215 }
216
220 [[nodiscard]] auto is_server() const noexcept -> bool { return is_server_; }
221
222 // ========================================================================
223 // Connection IDs
224 // ========================================================================
225
229 [[nodiscard]] auto local_cid() const -> const connection_id& { return local_cid_; }
230
234 [[nodiscard]] auto remote_cid() const -> const connection_id& { return remote_cid_; }
235
239 [[nodiscard]] auto initial_dcid() const -> const connection_id& { return initial_dcid_; }
240
247 [[nodiscard]] auto add_local_cid(const connection_id& cid, uint64_t sequence)
248 -> VoidResult;
249
255 [[nodiscard]] auto retire_cid(uint64_t sequence) -> VoidResult;
256
261 {
262 return peer_cid_manager_;
263 }
264
268 [[nodiscard]] auto peer_cid_manager() const -> const connection_id_manager&
269 {
270 return peer_cid_manager_;
271 }
272
279 [[nodiscard]] auto active_peer_cid() const -> const connection_id&;
280
287 [[nodiscard]] auto rotate_peer_cid() -> VoidResult;
288
289 // ========================================================================
290 // Transport Parameters
291 // ========================================================================
292
297 void set_local_params(const transport_parameters& params);
298
303 void set_remote_params(const transport_parameters& params);
304
308 [[nodiscard]] auto local_params() const -> const transport_parameters&
309 {
310 return local_params_;
311 }
312
316 [[nodiscard]] auto remote_params() const -> const transport_parameters&
317 {
318 return remote_params_;
319 }
320
321 // ========================================================================
322 // Handshake
323 // ========================================================================
324
330 [[nodiscard]] auto start_handshake(const std::string& server_name)
332
339 [[nodiscard]] auto init_server_handshake(const std::string& cert_file,
340 const std::string& key_file) -> VoidResult;
341
342 // ========================================================================
343 // Packet Processing
344 // ========================================================================
345
351 [[nodiscard]] auto receive_packet(std::span<const uint8_t> data) -> VoidResult;
352
357 [[nodiscard]] auto generate_packets() -> std::vector<std::vector<uint8_t>>;
358
362 [[nodiscard]] auto has_pending_data() const -> bool;
363
364 // ========================================================================
365 // Stream Access
366 // ========================================================================
367
371 [[nodiscard]] auto streams() -> stream_manager& { return stream_mgr_; }
372
376 [[nodiscard]] auto streams() const -> const stream_manager& { return stream_mgr_; }
377
378 // ========================================================================
379 // Flow Control
380 // ========================================================================
381
385 [[nodiscard]] auto flow_control() -> flow_controller& { return flow_ctrl_; }
386
390 [[nodiscard]] auto flow_control() const -> const flow_controller& { return flow_ctrl_; }
391
392 // ========================================================================
393 // Connection Close
394 // ========================================================================
395
402 [[nodiscard]] auto close(uint64_t error_code, const std::string& reason = "")
403 -> VoidResult;
404
411 [[nodiscard]] auto close_application(uint64_t error_code,
412 const std::string& reason = "") -> VoidResult;
413
417 [[nodiscard]] auto close_error_code() const -> std::optional<uint64_t>
418 {
419 return close_error_code_;
420 }
421
425 [[nodiscard]] auto close_reason() const -> const std::string& { return close_reason_; }
426
427 // ========================================================================
428 // Timers
429 // ========================================================================
430
435 [[nodiscard]] auto next_timeout() const
436 -> std::optional<std::chrono::steady_clock::time_point>;
437
441 void on_timeout();
442
446 [[nodiscard]] auto idle_deadline() const -> std::chrono::steady_clock::time_point
447 {
448 return idle_deadline_;
449 }
450
451 // ========================================================================
452 // Crypto Access
453 // ========================================================================
454
458 [[nodiscard]] auto crypto() -> quic_crypto& { return crypto_; }
459
463 [[nodiscard]] auto crypto() const -> const quic_crypto& { return crypto_; }
464
465 // ========================================================================
466 // Path MTU Discovery (RFC 9000 Section 14, RFC 8899)
467 // ========================================================================
468
473 [[nodiscard]] auto path_mtu() const noexcept -> size_t;
474
481 void enable_pmtud();
482
488 void disable_pmtud();
489
494 [[nodiscard]] auto pmtud_enabled() const noexcept -> bool;
495
499 [[nodiscard]] auto pmtud() -> pmtud_controller& { return pmtud_controller_; }
500
504 [[nodiscard]] auto pmtud() const -> const pmtud_controller& { return pmtud_controller_; }
505
506 // ========================================================================
507 // Statistics
508 // ========================================================================
509
513 [[nodiscard]] auto bytes_sent() const noexcept -> uint64_t { return bytes_sent_; }
514
518 [[nodiscard]] auto bytes_received() const noexcept -> uint64_t { return bytes_received_; }
519
523 [[nodiscard]] auto packets_sent() const noexcept -> uint64_t { return packets_sent_; }
524
528 [[nodiscard]] auto packets_received() const noexcept -> uint64_t
529 {
530 return packets_received_;
531 }
532
533private:
534 // ========================================================================
535 // Private Members
536 // ========================================================================
537
540 enum handshake_state hs_state_ { handshake_state::initial };
541
542 // Connection IDs
545 connection_id initial_dcid_; // For initial key derivation
546 std::vector<std::pair<uint64_t, connection_id>> local_cids_;
548 connection_id_manager peer_cid_manager_; // Manages peer CIDs (RFC 9000 Section 5.1)
549
550 // Transport parameters
553
554 // Subsystems
558
559 // Loss detection and congestion control (RFC 9002)
563
564 // Path MTU Discovery (RFC 8899)
566
567 // Packet number spaces
571
572 // Pending crypto data per encryption level
573 std::deque<std::vector<uint8_t>> pending_crypto_initial_;
574 std::deque<std::vector<uint8_t>> pending_crypto_handshake_;
575 std::deque<std::vector<uint8_t>> pending_crypto_app_;
576
577 // Pending ACKs per encryption level
580 bool pending_ack_app_{false};
581
582 // Pending frames to send
583 std::deque<frame> pending_frames_;
584
585 // Close state
586 bool close_sent_{false};
587 bool close_received_{false};
588 std::optional<uint64_t> close_error_code_;
589 std::string close_reason_;
591
592 // Timers
593 std::chrono::steady_clock::time_point idle_deadline_;
594 std::chrono::steady_clock::time_point pto_deadline_;
595 std::chrono::steady_clock::time_point drain_deadline_;
596
597 // Statistics
598 uint64_t bytes_sent_{0};
599 uint64_t bytes_received_{0};
600 uint64_t packets_sent_{0};
601 uint64_t packets_received_{0};
602
603 // ========================================================================
604 // Private Methods
605 // ========================================================================
606
610 [[nodiscard]] auto process_long_header_packet(const long_header& hdr,
611 std::span<const uint8_t> payload)
612 -> VoidResult;
613
617 [[nodiscard]] auto process_short_header_packet(const short_header& hdr,
618 std::span<const uint8_t> payload)
619 -> VoidResult;
620
624 [[nodiscard]] auto process_frames(std::span<const uint8_t> payload,
626
630 [[nodiscard]] auto handle_frame(const frame& frame, encryption_level level)
631 -> VoidResult;
632
636 [[nodiscard]] auto build_packet(encryption_level level) -> std::vector<uint8_t>;
637
641 [[nodiscard]] auto get_pn_space(encryption_level level) -> packet_number_space&;
642 [[nodiscard]] auto get_pn_space(encryption_level level) const
643 -> const packet_number_space&;
644
648 void update_state();
649
653 void reset_idle_timer();
654
658 void enter_draining();
659
663 void enter_closing();
664
668 void apply_remote_params();
669
673 [[nodiscard]] auto generate_ack_frame(const packet_number_space& space)
674 -> std::optional<ack_frame>;
675
681
687
692 void queue_frames_for_retransmission(const sent_packet& lost_packet);
693
697 [[nodiscard]] auto to_sent_packet(const sent_packet_info& info) const -> sent_packet;
698};
699
700} // 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:158
std::chrono::steady_clock::time_point idle_deadline_
Definition connection.h:593
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:575
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:523
std::deque< std::vector< uint8_t > > pending_crypto_initial_
Definition connection.h:573
auto operator=(connection &&) -> connection &=delete
auto remote_params() const -> const transport_parameters &
Get remote transport parameters.
Definition connection.h:316
auto is_established() const noexcept -> bool
Check if connection is established (handshake complete)
Definition connection.h:195
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:203
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:528
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:239
void apply_remote_params()
Apply remote transport parameters.
std::chrono::steady_clock::time_point drain_deadline_
Definition connection.h:595
auto flow_control() const -> const flow_controller &
Get the connection-level flow controller (const)
Definition connection.h:390
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:234
auto is_server() const noexcept -> bool
Check if this is a server-side connection.
Definition connection.h:220
auto pmtud() -> pmtud_controller &
Get the PMTUD controller.
Definition connection.h:499
auto idle_deadline() const -> std::chrono::steady_clock::time_point
Get idle timeout deadline.
Definition connection.h:446
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:385
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:518
auto path_mtu() const noexcept -> size_t
Get current path MTU.
std::optional< uint64_t > close_error_code_
Definition connection.h:588
std::deque< std::vector< uint8_t > > pending_crypto_handshake_
Definition connection.h:574
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:425
auto crypto() -> quic_crypto &
Get crypto handler.
Definition connection.h:458
auto close_error_code() const -> std::optional< uint64_t >
Get the close error code (if connection was closed)
Definition connection.h:417
auto local_params() const -> const transport_parameters &
Get local transport parameters.
Definition connection.h:308
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:212
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:376
auto local_cid() const -> const connection_id &
Get local Connection ID.
Definition connection.h:229
auto streams() -> stream_manager &
Get the stream manager.
Definition connection.h:371
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:546
auto state() const noexcept -> connection_state
Get current connection state.
Definition connection.h:182
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:187
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:594
auto peer_cid_manager() const -> const connection_id_manager &
Get the peer connection ID manager (const)
Definition connection.h:268
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:463
auto bytes_sent() const noexcept -> uint64_t
Get total bytes sent.
Definition connection.h:513
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:504
auto peer_cid_manager() -> connection_id_manager &
Get the peer connection ID manager.
Definition connection.h:260
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:43
@ 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:56
@ 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:118
std::chrono::microseconds ack_delay
ACK delay for this space.
Definition connection.h:138
uint64_t largest_received
Largest received packet number.
Definition connection.h:126
std::chrono::steady_clock::time_point largest_received_time
Time of receiving largest packet.
Definition connection.h:129
std::map< uint64_t, sent_packet_info > sent_packets
Packets awaiting acknowledgment.
Definition connection.h:132
uint64_t largest_acked
Largest acknowledged packet number.
Definition connection.h:123
uint64_t next_pn
Next packet number to use.
Definition connection.h:120
Information about a sent packet for loss detection.
Definition connection.h:97
std::chrono::steady_clock::time_point sent_time
Definition connection.h:99
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)