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
258 [[nodiscard]] auto stats() const -> quic_connection_stats;
259
260 // =====================================================================
261 // i_network_component interface implementation
262 // =====================================================================
263
270 [[nodiscard]] auto is_running() const -> bool override;
271
277 auto wait_for_stop() -> void override;
278
279 // =====================================================================
280 // i_quic_client interface implementation
281 // =====================================================================
282
291 [[nodiscard]] auto start(std::string_view host, uint16_t port) -> VoidResult override;
292
299 [[nodiscard]] auto stop() -> VoidResult override;
300
307 [[nodiscard]] auto is_connected() const -> bool override;
308
315 [[nodiscard]] auto is_handshake_complete() const -> bool override;
316
324 [[nodiscard]] auto send(std::vector<uint8_t>&& data) -> VoidResult override;
325
332 [[nodiscard]] auto create_stream() -> Result<uint64_t> override;
333
340 [[nodiscard]] auto create_unidirectional_stream() -> Result<uint64_t> override;
341
351 [[nodiscard]] auto send_on_stream(
352 uint64_t stream_id,
353 std::vector<uint8_t>&& data,
354 bool fin = false) -> VoidResult override;
355
363 [[nodiscard]] auto close_stream(uint64_t stream_id) -> VoidResult override;
364
371 auto set_alpn_protocols(const std::vector<std::string>& protocols) -> void override;
372
384 [[nodiscard]] auto alpn_protocol() const -> std::optional<std::string> override;
385
392 [[nodiscard]] auto is_early_data_accepted() const -> bool override;
393
400 auto set_receive_callback(interfaces::i_quic_client::receive_callback_t callback) -> void override;
401
408 auto set_stream_callback(interfaces::i_quic_client::stream_callback_t callback) -> void override;
409
416 auto set_connected_callback(interfaces::i_quic_client::connected_callback_t callback) -> void override;
417
424 auto set_disconnected_callback(interfaces::i_quic_client::disconnected_callback_t callback) -> void override;
425
432 auto set_error_callback(interfaces::i_quic_client::error_callback_t callback) -> void override;
433
440 auto set_session_ticket_callback(interfaces::i_quic_client::session_ticket_callback_t callback) -> void override;
441
448 auto set_early_data_callback(interfaces::i_quic_client::early_data_callback_t callback) -> void override;
449
456 auto set_early_data_accepted_callback(interfaces::i_quic_client::early_data_accepted_callback_t callback) -> void override;
457
458 // =====================================================================
459 // Legacy API (maintained for backward compatibility)
460 // =====================================================================
461
470
471 private:
472 // =====================================================================
473 // Internal Implementation Methods
474 // =====================================================================
475
482 auto do_start_impl(std::string_view host, unsigned short port) -> VoidResult;
483
488 auto do_stop_impl() -> VoidResult;
489
493 auto do_connect(std::string_view host, unsigned short port) -> void;
494
498 auto on_connect() -> void;
499
503 auto on_stream_data(uint64_t stream_id,
504 std::span<const uint8_t> data,
505 bool fin) -> void;
506
510 auto on_error(std::error_code ec) -> void;
511
515 auto on_close(uint64_t error_code, const std::string& reason) -> void;
516
520 auto get_socket() const -> std::shared_ptr<internal::quic_socket>;
521
522 // =====================================================================
523 // Internal Callback Helpers
524 // =====================================================================
525
530 auto invoke_receive_callback(const std::vector<uint8_t>& data) -> void;
531
538 auto invoke_stream_receive_callback(uint64_t stream_id,
539 const std::vector<uint8_t>& data,
540 bool fin) -> void;
541
545 auto invoke_connected_callback() -> void;
546
550 auto invoke_disconnected_callback() -> void;
551
556 auto invoke_error_callback(std::error_code ec) -> void;
557
560
562 using callbacks_t = utils::callback_manager<
568 >;
569
570 // =====================================================================
571 // Member Variables
572 // =====================================================================
573
574 std::string client_id_;
575 utils::lifecycle_manager lifecycle_;
577 std::atomic<bool> is_connected_{false};
579 std::unique_ptr<asio::io_context> io_context_;
580 std::unique_ptr<asio::executor_work_guard<asio::io_context::executor_type>>
582 std::shared_ptr<integration::thread_pool_interface>
584 std::future<void> io_context_future_;
585
586 mutable std::mutex socket_mutex_;
587 std::shared_ptr<internal::quic_socket> socket_;
588
590 uint64_t default_stream_id_{0};
591
592 std::atomic<bool> handshake_complete_{false};
593
594 // 0-RTT callbacks
598 std::atomic<bool> early_data_accepted_{false};
599 };
600
601// =====================================================================
602// Unified Pattern Type Aliases
603// =====================================================================
604// These aliases provide a consistent API pattern across all protocols,
605// making QUIC clients accessible via the unified template naming.
606// See: unified_messaging_client.h for TCP, unified_udp_messaging_client.h for UDP.
607
620
635
636} // namespace kcenon::network::core
637
638#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:38
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.