Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
quic_client.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#ifndef KCENON_NETWORK_INTERNAL_EXPERIMENTAL_QUIC_CLIENT_H_
7#define KCENON_NETWORK_INTERNAL_EXPERIMENTAL_QUIC_CLIENT_H_
8
9// Experimental API marker - users must opt-in to use this header
12
13#include <atomic>
14#include <chrono>
15#include <functional>
16#include <future>
17#include <memory>
18#include <mutex>
19#include <optional>
20#include <span>
21#include <string>
22#include <string_view>
23#include <system_error>
24#include <vector>
25
26#include <asio.hpp>
27
35
36// Forward declaration
38{
39 class quic_socket;
40 enum class quic_role : uint8_t;
41} // namespace kcenon::network::internal
42
44{
45
51 {
53 std::optional<std::string> ca_cert_file;
54
56 std::optional<std::string> client_cert_file;
57
59 std::optional<std::string> client_key_file;
60
62 bool verify_server{true};
63
65 std::vector<std::string> alpn_protocols;
66
68 uint64_t max_idle_timeout_ms{30000};
69
71 uint64_t initial_max_data{1048576};
72
74 uint64_t initial_max_stream_data{65536};
75
78
81
83 bool enable_early_data{false};
84
86 std::optional<std::vector<uint8_t>> session_ticket;
87
89 uint32_t max_early_data_size{16384};
90 };
91
97 {
98 uint64_t bytes_sent{0};
99 uint64_t bytes_received{0};
100 uint64_t packets_sent{0};
101 uint64_t packets_received{0};
102 uint64_t packets_lost{0};
103 std::chrono::microseconds smoothed_rtt{0};
104 std::chrono::microseconds min_rtt{0};
105 size_t cwnd{0};
106 };
107
149 : public std::enable_shared_from_this<messaging_quic_client>
151 {
152 public:
154 using receive_callback_t = std::function<void(const std::vector<uint8_t>&)>;
156 using stream_receive_callback_t = std::function<void(uint64_t, const std::vector<uint8_t>&, bool)>;
158 using connected_callback_t = std::function<void()>;
160 using disconnected_callback_t = std::function<void()>;
162 using error_callback_t = std::function<void(std::error_code)>;
163
168 explicit messaging_quic_client(std::string_view client_id);
169
173 ~messaging_quic_client() noexcept override;
174
175 // Non-copyable, non-movable
177 messaging_quic_client& operator=(const messaging_quic_client&) = delete;
180
181 // =====================================================================
182 // Lifecycle Management
183 // =====================================================================
184
191 [[nodiscard]] auto start_client(std::string_view host,
192 unsigned short port) -> VoidResult;
193
201 [[nodiscard]] auto start_client(std::string_view host,
202 unsigned short port,
203 const quic_client_config& config) -> VoidResult;
204
209 [[nodiscard]] auto stop_client() -> VoidResult;
210
215 [[nodiscard]] auto client_id() const -> const std::string&;
216
217 // =====================================================================
218 // Data Transfer (Default Stream)
219 // =====================================================================
220
236 [[nodiscard]] auto send_packet(std::vector<uint8_t>&& data) -> VoidResult;
237
247 [[nodiscard]] auto send_packet(std::string_view data) -> VoidResult;
248
253 [[nodiscard]] auto stats() const -> quic_connection_stats;
254
255 // =====================================================================
256 // i_network_component interface implementation
257 // =====================================================================
258
265 [[nodiscard]] auto is_running() const -> bool override;
266
272 auto wait_for_stop() -> void override;
273
274 // =====================================================================
275 // i_quic_client interface implementation
276 // =====================================================================
277
286 [[nodiscard]] auto start(std::string_view host, uint16_t port) -> VoidResult override;
287
294 [[nodiscard]] auto stop() -> VoidResult override;
295
302 [[nodiscard]] auto is_connected() const -> bool override;
303
310 [[nodiscard]] auto is_handshake_complete() const -> bool override;
311
319 [[nodiscard]] auto send(std::vector<uint8_t>&& data) -> VoidResult override;
320
327 [[nodiscard]] auto create_stream() -> Result<uint64_t> override;
328
335 [[nodiscard]] auto create_unidirectional_stream() -> Result<uint64_t> override;
336
346 [[nodiscard]] auto send_on_stream(
347 uint64_t stream_id,
348 std::vector<uint8_t>&& data,
349 bool fin = false) -> VoidResult override;
350
358 [[nodiscard]] auto close_stream(uint64_t stream_id) -> VoidResult override;
359
366 auto set_alpn_protocols(const std::vector<std::string>& protocols) -> void override;
367
374 [[nodiscard]] auto alpn_protocol() const -> std::optional<std::string> override;
375
382 [[nodiscard]] auto is_early_data_accepted() const -> bool override;
383
390 auto set_receive_callback(interfaces::i_quic_client::receive_callback_t callback) -> void override;
391
398 auto set_stream_callback(interfaces::i_quic_client::stream_callback_t callback) -> void override;
399
406 auto set_connected_callback(interfaces::i_quic_client::connected_callback_t callback) -> void override;
407
414 auto set_disconnected_callback(interfaces::i_quic_client::disconnected_callback_t callback) -> void override;
415
422 auto set_error_callback(interfaces::i_quic_client::error_callback_t callback) -> void override;
423
430 auto set_session_ticket_callback(interfaces::i_quic_client::session_ticket_callback_t callback) -> void override;
431
438 auto set_early_data_callback(interfaces::i_quic_client::early_data_callback_t callback) -> void override;
439
446 auto set_early_data_accepted_callback(interfaces::i_quic_client::early_data_accepted_callback_t callback) -> void override;
447
448 // =====================================================================
449 // Legacy API (maintained for backward compatibility)
450 // =====================================================================
451
460
461 private:
462 // =====================================================================
463 // Internal Implementation Methods
464 // =====================================================================
465
472 auto do_start_impl(std::string_view host, unsigned short port) -> VoidResult;
473
478 auto do_stop_impl() -> VoidResult;
479
483 auto do_connect(std::string_view host, unsigned short port) -> void;
484
488 auto on_connect() -> void;
489
493 auto on_stream_data(uint64_t stream_id,
494 std::span<const uint8_t> data,
495 bool fin) -> void;
496
500 auto on_error(std::error_code ec) -> void;
501
505 auto on_close(uint64_t error_code, const std::string& reason) -> void;
506
510 auto get_socket() const -> std::shared_ptr<internal::quic_socket>;
511
512 // =====================================================================
513 // Internal Callback Helpers
514 // =====================================================================
515
520 auto invoke_receive_callback(const std::vector<uint8_t>& data) -> void;
521
528 auto invoke_stream_receive_callback(uint64_t stream_id,
529 const std::vector<uint8_t>& data,
530 bool fin) -> void;
531
535 auto invoke_connected_callback() -> void;
536
540 auto invoke_disconnected_callback() -> void;
541
546 auto invoke_error_callback(std::error_code ec) -> void;
547
550
552 using callbacks_t = utils::callback_manager<
558 >;
559
560 // =====================================================================
561 // Member Variables
562 // =====================================================================
563
564 std::string client_id_;
565 utils::lifecycle_manager lifecycle_;
567 std::atomic<bool> is_connected_{false};
569 std::unique_ptr<asio::io_context> io_context_;
570 std::unique_ptr<asio::executor_work_guard<asio::io_context::executor_type>>
572 std::shared_ptr<integration::thread_pool_interface>
574 std::future<void> io_context_future_;
575
576 mutable std::mutex socket_mutex_;
577 std::shared_ptr<internal::quic_socket> socket_;
578
580 uint64_t default_stream_id_{0};
581
582 std::atomic<bool> handshake_complete_{false};
583
584 // 0-RTT callbacks
588 std::atomic<bool> early_data_accepted_{false};
589 };
590
591// =====================================================================
592// Unified Pattern Type Aliases
593// =====================================================================
594// These aliases provide a consistent API pattern across all protocols,
595// making QUIC clients accessible via the unified template naming.
596// See: unified_messaging_client.h for TCP, unified_udp_messaging_client.h for UDP.
597
610
625
626} // namespace kcenon::network::core
627
628#endif // KCENON_NETWORK_INTERNAL_EXPERIMENTAL_QUIC_CLIENT_H_
Thread-safe callback registration and invocation manager.
A QUIC client that provides reliable, multiplexed communication.
std::shared_ptr< internal::quic_socket > socket_
The QUIC socket.
auto set_disconnected_callback(interfaces::i_quic_client::disconnected_callback_t callback) -> void override
Sets the callback for disconnection (interface version).
interfaces::i_quic_client::session_ticket_callback_t session_ticket_cb_
Session ticket callback.
std::function< void()> disconnected_callback_t
Callback type for disconnection.
auto stop() -> VoidResult override
Stops the QUIC client.
auto wait_for_stop() -> void override
Blocks until stop() is called.
auto send(std::vector< uint8_t > &&data) -> VoidResult override
Sends data on the default stream (interface version).
std::mutex socket_mutex_
Protects socket_ from data races.
auto do_stop_impl() -> VoidResult
QUIC-specific implementation of client stop.
auto on_connect() -> void
Callback invoked when connection is established.
std::unique_ptr< asio::executor_work_guard< asio::io_context::executor_type > > work_guard_
Keeps io_context running.
uint64_t default_stream_id_
Default stream for send_packet()
interfaces::i_quic_client::early_data_callback_t early_data_cb_
Early data production callback.
messaging_quic_client(std::string_view client_id)
Constructs a QUIC client with a given identifier.
auto is_running() const -> bool override
Checks if the client is currently running.
auto create_unidirectional_stream() -> Result< uint64_t > override
Creates a new unidirectional stream (interface version).
auto on_close(uint64_t error_code, const std::string &reason) -> void
Callback for connection close.
~messaging_quic_client() noexcept override
Destructor; automatically calls stop_client() if running.
auto alpn_protocol() const -> std::optional< std::string > override
Gets the negotiated ALPN protocol (interface version).
auto is_handshake_complete() const -> bool override
Checks if TLS handshake is complete (interface version).
auto invoke_stream_receive_callback(uint64_t stream_id, const std::vector< uint8_t > &data, bool fin) -> void
Invokes the stream receive callback.
auto set_early_data_accepted_callback(interfaces::i_quic_client::early_data_accepted_callback_t callback) -> void override
Sets the callback for early data acceptance notification (interface version).
auto start_client(std::string_view host, unsigned short port) -> VoidResult
Starts the client with default configuration.
auto close_stream(uint64_t stream_id) -> VoidResult override
Closes a stream (interface version).
std::unique_ptr< asio::io_context > io_context_
I/O context.
std::function< void(uint64_t, const std::vector< uint8_t > &, bool)> stream_receive_callback_t
Callback type for stream data (stream_id, data, fin)
std::shared_ptr< integration::thread_pool_interface > thread_pool_
Thread pool for async ops.
auto invoke_connected_callback() -> void
Invokes the connected callback.
auto send_on_stream(uint64_t stream_id, std::vector< uint8_t > &&data, bool fin=false) -> VoidResult override
Sends data on a specific stream (interface version).
auto do_start_impl(std::string_view host, unsigned short port) -> VoidResult
QUIC-specific implementation of client start.
std::atomic< bool > handshake_complete_
TLS handshake status.
auto invoke_receive_callback(const std::vector< uint8_t > &data) -> void
Invokes the receive callback.
auto set_session_ticket_callback(interfaces::i_quic_client::session_ticket_callback_t callback) -> void override
Sets the callback for session tickets (interface version).
auto set_receive_callback(interfaces::i_quic_client::receive_callback_t callback) -> void override
Sets the callback for received data on default stream (interface version).
auto set_stream_callback(interfaces::i_quic_client::stream_callback_t callback) -> void override
Sets the callback for stream data (interface version).
auto send_packet(std::vector< uint8_t > &&data) -> VoidResult
Send data on the default stream (stream 0).
std::function< void()> connected_callback_t
Callback type for connection established.
quic_client_config config_
Client configuration.
auto on_stream_data(uint64_t stream_id, std::span< const uint8_t > data, bool fin) -> void
Callback for receiving stream data.
auto stop_client() -> VoidResult
Stops the client and releases all resources.
interfaces::i_quic_client::early_data_accepted_callback_t early_data_accepted_cb_
Early data acceptance callback.
std::function< void(std::error_code)> error_callback_t
Callback type for errors.
std::function< void(const std::vector< uint8_t > &)> receive_callback_t
Callback type for received data.
auto invoke_disconnected_callback() -> void
Invokes the disconnected callback.
auto on_error(std::error_code ec) -> void
Callback for handling errors.
std::future< void > io_context_future_
Future for io_context run.
auto do_connect(std::string_view host, unsigned short port) -> void
Internal connection implementation.
auto create_stream() -> Result< uint64_t > override
Creates a new bidirectional stream (interface version).
auto invoke_error_callback(std::error_code ec) -> void
Invokes the error callback.
auto is_connected() const -> bool override
Checks if the client is connected (interface version).
auto set_connected_callback(interfaces::i_quic_client::connected_callback_t callback) -> void override
Sets the callback for connection established (interface version).
auto start(std::string_view host, uint16_t port) -> VoidResult override
Starts the QUIC client connecting to the specified server.
auto set_stream_receive_callback(stream_receive_callback_t callback) -> void
Sets the callback for stream data reception (all streams, legacy version).
auto is_early_data_accepted() const -> bool override
Checks if early data was accepted (interface version).
auto stats() const -> quic_connection_stats
Get connection statistics.
auto client_id() const -> const std::string &
Returns the client identifier.
auto get_socket() const -> std::shared_ptr< internal::quic_socket >
Get the internal socket with mutex protection.
auto set_alpn_protocols(const std::vector< std::string > &protocols) -> void override
Sets the ALPN protocols for negotiation (interface version).
std::atomic< bool > early_data_accepted_
Early data acceptance status.
auto set_error_callback(interfaces::i_quic_client::error_callback_t callback) -> void override
Sets the callback for errors (interface version).
auto set_early_data_callback(interfaces::i_quic_client::early_data_callback_t callback) -> void override
Sets the callback for early data production (interface version).
Interface for QUIC client components.
std::function< void(bool accepted)> early_data_accepted_callback_t
Callback type for early data acceptance notification.
std::function< std::vector< uint8_t >()> early_data_callback_t
Callback type for early data production.
std::function< void( std::vector< uint8_t > ticket_data, uint32_t lifetime_hint, uint32_t max_early_data)> session_ticket_callback_t
Callback type for session ticket received (for 0-RTT resumption)
std::function< void(uint64_t, const std::vector< uint8_t > &, bool)> stream_callback_t
Callback type for stream data (stream_id, data, is_fin)
Macros and utilities for marking experimental APIs.
#define NETWORK_REQUIRE_EXPERIMENTAL
Enforces opt-in for experimental APIs at compile time.
Component lifecycle management (start, stop, restart).
quic_role
Role of the QUIC endpoint (client or server)
Definition quic_socket.h:31
quic_client_callback
Callback indices for messaging_quic_client.
Global context for shared network system resources.
Network-specific error and result type definitions.
Configuration options for QUIC client.
Definition quic_client.h:51
std::optional< std::string > ca_cert_file
Path to CA certificate file for server verification (PEM format)
Definition quic_client.h:53
uint64_t initial_max_streams_uni
Initial maximum unidirectional streams (default: 100)
Definition quic_client.h:80
bool verify_server
Whether to verify server certificate (default: true)
Definition quic_client.h:62
std::optional< std::vector< uint8_t > > session_ticket
Session ticket for 0-RTT resumption.
Definition quic_client.h:86
uint64_t initial_max_data
Initial maximum data that can be sent (default: 1 MB)
Definition quic_client.h:71
uint64_t max_idle_timeout_ms
Maximum idle timeout in milliseconds (default: 30 seconds)
Definition quic_client.h:68
uint32_t max_early_data_size
Maximum early data size in bytes (default: 16KB, 0 to disable)
Definition quic_client.h:89
uint64_t initial_max_stream_data
Initial maximum data per stream (default: 64 KB)
Definition quic_client.h:74
uint64_t initial_max_streams_bidi
Initial maximum bidirectional streams (default: 100)
Definition quic_client.h:77
std::optional< std::string > client_key_file
Path to client private key file for mutual TLS (PEM format)
Definition quic_client.h:59
bool enable_early_data
Enable 0-RTT early data (default: false)
Definition quic_client.h:83
std::optional< std::string > client_cert_file
Path to client certificate file for mutual TLS (PEM format)
Definition quic_client.h:56
std::vector< std::string > alpn_protocols
ALPN protocols to negotiate (e.g., {"h3", "hq-29"})
Definition quic_client.h:65
Statistics for a QUIC connection.
Definition quic_client.h:97
uint64_t packets_received
Total packets received.
uint64_t bytes_received
Total bytes received.
Definition quic_client.h:99
std::chrono::microseconds smoothed_rtt
Smoothed RTT.
std::chrono::microseconds min_rtt
Minimum RTT observed.
size_t cwnd
Congestion window size.
uint64_t packets_sent
Total packets sent.
uint64_t packets_lost
Total packets lost.
Thread system integration interface for network_system.