Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
kcenon::network::internal::quic_socket Class Reference

A QUIC socket that wraps UDP and integrates QUIC packet protection. More...

#include <quic_socket.h>

Inheritance diagram for kcenon::network::internal::quic_socket:
Inheritance graph
Collaboration diagram for kcenon::network::internal::quic_socket:
Collaboration graph

Public Types

using stream_data_callback
 Callback for receiving stream data.
 
using connected_callback = std::function<void()>
 Callback when connection is established.
 
using error_callback = std::function<void(std::error_code)>
 Callback for error handling.
 
using close_callback = std::function<void(uint64_t error_code, const std::string& reason)>
 Callback when connection is closed.
 

Public Member Functions

 quic_socket (asio::ip::udp::socket socket, quic_role role)
 Constructs a QUIC socket.
 
 ~quic_socket ()
 Destructor.
 
 quic_socket (const quic_socket &)=delete
 
quic_socketoperator= (const quic_socket &)=delete
 
 quic_socket (quic_socket &&other) noexcept
 
quic_socketoperator= (quic_socket &&other) noexcept
 
auto set_stream_data_callback (stream_data_callback cb) -> void
 Set callback for stream data reception.
 
auto set_connected_callback (connected_callback cb) -> void
 Set callback for connection establishment.
 
auto set_error_callback (error_callback cb) -> void
 Set callback for errors.
 
auto set_close_callback (close_callback cb) -> void
 Set callback for connection close.
 
auto connect (const asio::ip::udp::endpoint &endpoint, const std::string &server_name="") -> VoidResult
 Connect to a remote server (client only)
 
auto accept (const std::string &cert_file, const std::string &key_file) -> VoidResult
 Accept an incoming connection (server only)
 
auto close (uint64_t error_code=0, const std::string &reason="") -> VoidResult
 Close the connection gracefully.
 
auto start_receive () -> void
 Start the receive loop.
 
auto stop_receive () -> void
 Stop the receive loop.
 
auto send_stream_data (uint64_t stream_id, std::vector< uint8_t > &&data, bool fin=false) -> VoidResult
 Send data on a stream.
 
auto create_stream (bool unidirectional=false) -> Result< uint64_t >
 Create a new stream.
 
auto close_stream (uint64_t stream_id) -> VoidResult
 Close a stream.
 
auto is_connected () const noexcept -> bool
 Check if the connection is established.
 
auto is_handshake_complete () const noexcept -> bool
 Check if the TLS handshake is complete.
 
auto state () const noexcept -> quic_connection_state
 Get the current connection state.
 
auto role () const noexcept -> quic_role
 Get the role (client or server)
 
auto remote_endpoint () const -> asio::ip::udp::endpoint
 Get the remote endpoint.
 
auto local_connection_id () const -> const protocols::quic::connection_id &
 Get the local connection ID.
 
auto remote_connection_id () const -> const protocols::quic::connection_id &
 Get the remote connection ID.
 
auto socket () -> asio::ip::udp::socket &
 Access the underlying UDP socket.
 
auto socket () const -> const asio::ip::udp::socket &
 Access the underlying UDP socket (const)
 

Private Member Functions

auto do_receive () -> void
 Internal receive loop implementation.
 
auto handle_packet (std::span< const uint8_t > data) -> void
 Handle received packet data.
 
auto process_frame (const protocols::quic::frame &f) -> void
 Process a parsed frame.
 
auto process_crypto_frame (const protocols::quic::crypto_frame &f) -> void
 Process CRYPTO frame data.
 
auto process_stream_frame (const protocols::quic::stream_frame &f) -> void
 Process STREAM frame data.
 
auto process_ack_frame (const protocols::quic::ack_frame &f) -> void
 Process ACK frame.
 
auto process_connection_close_frame (const protocols::quic::connection_close_frame &f) -> void
 Process CONNECTION_CLOSE frame.
 
auto process_handshake_done_frame () -> void
 Process HANDSHAKE_DONE frame.
 
auto send_pending_packets () -> void
 Send pending outgoing packets.
 
auto send_packet (protocols::quic::encryption_level level, std::vector< protocols::quic::frame > &&frames) -> VoidResult
 Build and send a packet with frames.
 
auto queue_crypto_data (std::vector< uint8_t > &&data) -> void
 Queue crypto data for sending.
 
auto determine_encryption_level (const protocols::quic::packet_header &header) const noexcept -> protocols::quic::encryption_level
 Determine encryption level from packet header.
 
auto generate_connection_id () -> protocols::quic::connection_id
 Generate a new connection ID.
 
auto on_retransmit_timeout () -> void
 Retransmission timeout handler.
 
auto transition_state (quic_connection_state new_state) -> void
 Transition to a new connection state.
 

Private Attributes

asio::ip::udp::socket udp_socket_
 Underlying UDP socket.
 
asio::ip::udp::endpoint remote_endpoint_
 Remote endpoint.
 
std::array< uint8_t, 65536 > recv_buffer_
 Receive buffer (max UDP datagram size)
 
quic_role role_
 Socket role (client/server)
 
std::atomic< quic_connection_statestate_ {quic_connection_state::idle}
 Connection state.
 
protocols::quic::quic_crypto crypto_
 QUIC crypto handler.
 
protocols::quic::connection_id local_conn_id_
 Local connection ID.
 
protocols::quic::connection_id remote_conn_id_
 Remote connection ID.
 
std::array< uint64_t, 4 > next_packet_number_ {0, 0, 0, 0}
 Packet number for each encryption level.
 
std::array< uint64_t, 4 > largest_received_pn_ {0, 0, 0, 0}
 Largest received packet number for each level.
 
uint64_t next_stream_id_ {0}
 Next stream ID to allocate.
 
std::array< std::deque< std::vector< uint8_t > >, 4 > pending_crypto_data_
 Pending crypto data to send per encryption level.
 
std::map< uint64_t, std::deque< std::pair< std::vector< uint8_t >, bool > > > pending_stream_data_
 Pending stream data to send (stream_id -> data queue)
 
std::mutex callback_mutex_
 Mutex for callback protection.
 
stream_data_callback stream_data_cb_
 Stream data callback.
 
connected_callback connected_cb_
 Connected callback.
 
error_callback error_cb_
 Error callback.
 
close_callback close_cb_
 Close callback.
 
std::atomic< bool > is_receiving_ {false}
 Is receive loop running.
 
std::atomic< bool > handshake_complete_ {false}
 Is handshake complete.
 
asio::steady_timer retransmit_timer_
 Retransmission timer.
 
asio::steady_timer idle_timer_
 Idle timeout timer.
 
std::mutex state_mutex_
 Mutex for state protection.
 

Detailed Description

A QUIC socket that wraps UDP and integrates QUIC packet protection.

Key Features

  • Wraps an existing asio::ip::udp::socket for UDP I/O
  • Integrates QUIC packet protection (encryption/decryption)
  • Handles packet parsing and building
  • Manages connection state at socket level
  • Supports stream-based data transfer

Thread Safety

  • All public methods are thread-safe through internal locking
  • Callbacks are invoked on ASIO worker threads
  • Ensure callback implementations are thread-safe

QUIC Protocol

  • Implements RFC 9000 connection semantics
  • Uses RFC 9001 TLS 1.3 for key negotiation
  • Supports multiple concurrent streams

Definition at line 72 of file quic_socket.h.

Member Typedef Documentation

◆ close_callback

using kcenon::network::internal::quic_socket::close_callback = std::function<void(uint64_t error_code, const std::string& reason)>

Callback when connection is closed.

Parameters
error_codeThe QUIC error code
reasonHuman-readable reason string

Definition at line 102 of file quic_socket.h.

◆ connected_callback

Callback when connection is established.

Definition at line 89 of file quic_socket.h.

◆ error_callback

using kcenon::network::internal::quic_socket::error_callback = std::function<void(std::error_code)>

Callback for error handling.

Parameters
ecThe error code describing the error

Definition at line 95 of file quic_socket.h.

◆ stream_data_callback

Initial value:
std::function<void(
uint64_t stream_id,
std::span<const uint8_t> data,
bool fin)>

Callback for receiving stream data.

Parameters
stream_idThe stream identifier
dataThe received data
finTrue if this is the final data on the stream

Definition at line 81 of file quic_socket.h.

Constructor & Destructor Documentation

◆ quic_socket() [1/3]

kcenon::network::internal::quic_socket::quic_socket ( asio::ip::udp::socket socket,
quic_role role )

Constructs a QUIC socket.

Parameters
socketAn open UDP socket
roleClient or server role

Definition at line 20 of file quic_socket.cpp.

21 : udp_socket_(std::move(socket))
22 , role_(role)
23 , retransmit_timer_(udp_socket_.get_executor())
24 , idle_timer_(udp_socket_.get_executor())
25{
26 // Generate local connection ID
28
29 // Initialize next stream ID based on role
30 // Client-initiated bidi streams: 0, 4, 8, ...
31 // Server-initiated bidi streams: 1, 5, 9, ...
33}
asio::ip::udp::socket udp_socket_
Underlying UDP socket.
auto socket() -> asio::ip::udp::socket &
Access the underlying UDP socket.
auto role() const noexcept -> quic_role
Get the role (client or server)
quic_role role_
Socket role (client/server)
uint64_t next_stream_id_
Next stream ID to allocate.
auto generate_connection_id() -> protocols::quic::connection_id
Generate a new connection ID.
protocols::quic::connection_id local_conn_id_
Local connection ID.
asio::steady_timer retransmit_timer_
Retransmission timer.
asio::steady_timer idle_timer_
Idle timeout timer.

References kcenon::network::internal::client, generate_connection_id(), local_conn_id_, next_stream_id_, and role_.

Here is the call graph for this function:

◆ ~quic_socket()

kcenon::network::internal::quic_socket::~quic_socket ( )

Destructor.

Definition at line 35 of file quic_socket.cpp.

36{
38
39 // Cancel timers
40 retransmit_timer_.cancel();
41 idle_timer_.cancel();
42}
auto stop_receive() -> void
Stop the receive loop.

References idle_timer_, retransmit_timer_, and stop_receive().

Here is the call graph for this function:

◆ quic_socket() [2/3]

kcenon::network::internal::quic_socket::quic_socket ( const quic_socket & )
delete

◆ quic_socket() [3/3]

kcenon::network::internal::quic_socket::quic_socket ( quic_socket && other)
noexcept

Definition at line 44 of file quic_socket.cpp.

45 : udp_socket_(std::move(other.udp_socket_))
46 , remote_endpoint_(std::move(other.remote_endpoint_))
47 , recv_buffer_(std::move(other.recv_buffer_))
48 , role_(other.role_)
49 , state_(other.state_.load())
50 , crypto_(std::move(other.crypto_))
51 , local_conn_id_(std::move(other.local_conn_id_))
52 , remote_conn_id_(std::move(other.remote_conn_id_))
53 , next_packet_number_(other.next_packet_number_)
54 , largest_received_pn_(other.largest_received_pn_)
55 , next_stream_id_(other.next_stream_id_)
56 , pending_crypto_data_(std::move(other.pending_crypto_data_))
57 , pending_stream_data_(std::move(other.pending_stream_data_))
58 , stream_data_cb_(std::move(other.stream_data_cb_))
59 , connected_cb_(std::move(other.connected_cb_))
60 , error_cb_(std::move(other.error_cb_))
61 , close_cb_(std::move(other.close_cb_))
62 , is_receiving_(other.is_receiving_.load())
63 , handshake_complete_(other.handshake_complete_.load())
64 , retransmit_timer_(std::move(other.retransmit_timer_))
65 , idle_timer_(std::move(other.idle_timer_))
66{
67}
stream_data_callback stream_data_cb_
Stream data callback.
std::atomic< quic_connection_state > state_
Connection state.
std::array< uint64_t, 4 > next_packet_number_
Packet number for each encryption level.
std::atomic< bool > is_receiving_
Is receive loop running.
protocols::quic::connection_id remote_conn_id_
Remote connection ID.
std::map< uint64_t, std::deque< std::pair< std::vector< uint8_t >, bool > > > pending_stream_data_
Pending stream data to send (stream_id -> data queue)
connected_callback connected_cb_
Connected callback.
std::atomic< bool > handshake_complete_
Is handshake complete.
std::array< uint8_t, 65536 > recv_buffer_
Receive buffer (max UDP datagram size)
error_callback error_cb_
Error callback.
std::array< std::deque< std::vector< uint8_t > >, 4 > pending_crypto_data_
Pending crypto data to send per encryption level.
protocols::quic::quic_crypto crypto_
QUIC crypto handler.
asio::ip::udp::endpoint remote_endpoint_
Remote endpoint.
std::array< uint64_t, 4 > largest_received_pn_
Largest received packet number for each level.
close_callback close_cb_
Close callback.

Member Function Documentation

◆ accept()

auto kcenon::network::internal::quic_socket::accept ( const std::string & cert_file,
const std::string & key_file ) -> VoidResult
nodiscard

Accept an incoming connection (server only)

Parameters
cert_filePath to certificate file (PEM format)
key_filePath to private key file (PEM format)
Returns
Success or error

Definition at line 213 of file quic_socket.cpp.

215{
217 {
218 return error_void(
220 "accept() can only be called on server sockets",
221 "quic_socket");
222 }
223
225 {
226 return error_void(
228 "Connection already in progress",
229 "quic_socket");
230 }
231
232 // Initialize server-side crypto
233 auto init_result = crypto_.init_server(cert_file, key_file);
234 if (init_result.is_err())
235 {
236 return error_void(
238 "Failed to initialize TLS server",
239 "quic_socket",
240 init_result.error().message);
241 }
242
244
245 // Start receiving - server waits for Initial packet from client
247
248 return ok();
249}
auto transition_state(quic_connection_state new_state) -> void
Transition to a new connection state.
auto start_receive() -> void
Start the receive loop.
auto init_server(const std::string &cert_file, const std::string &key_file) -> VoidResult
Initialize as server.
Definition crypto.cpp:827
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")
VoidResult ok()

References kcenon::network::error_codes::network_system::connection_failed, kcenon::network::error_void(), kcenon::network::internal::handshake_start, kcenon::network::internal::idle, kcenon::network::error_codes::common_errors::invalid_argument, kcenon::network::ok(), and kcenon::network::internal::server.

Here is the call graph for this function:

◆ close()

auto kcenon::network::internal::quic_socket::close ( uint64_t error_code = 0,
const std::string & reason = "" ) -> VoidResult
nodiscard

Close the connection gracefully.

Parameters
error_codeApplication error code (0 for no error)
reasonHuman-readable reason string
Returns
Success or error

Definition at line 251 of file quic_socket.cpp.

252{
253 auto current_state = state_.load();
254 if (current_state == quic_connection_state::closed ||
255 current_state == quic_connection_state::closing ||
256 current_state == quic_connection_state::draining)
257 {
258 return ok(); // Already closing/closed
259 }
260
262
263 // Build CONNECTION_CLOSE frame
264 connection_close_frame close_frame;
265 close_frame.error_code = error_code;
266 close_frame.reason_phrase = reason;
267 close_frame.is_application_error = (error_code != 0);
268
269 // Send CONNECTION_CLOSE
270 std::vector<frame> frames;
271 frames.push_back(close_frame);
272
273 auto level = handshake_complete_.load()
274 ? encryption_level::application
275 : encryption_level::initial;
276
277 auto send_result = send_packet(level, std::move(frames));
278 if (send_result.is_err())
279 {
280 // Log error but continue with close
281 }
282
284
285 // Set a timer for draining period (3 * PTO), then fully close
286 idle_timer_.expires_after(std::chrono::milliseconds(300));
287 idle_timer_.async_wait(
288 [self = shared_from_this()](const std::error_code& ec)
289 {
290 if (!ec)
291 {
292 self->transition_state(quic_connection_state::closed);
293 self->stop_receive();
294 }
295 });
296
297 return ok();
298}
auto send_packet(protocols::quic::encryption_level level, std::vector< protocols::quic::frame > &&frames) -> VoidResult
Build and send a packet with frames.
@ draining
Draining period before close.
error_code
HTTP/2 error codes (RFC 7540 Section 7)
Definition frame.h:471

References kcenon::network::internal::closed, kcenon::network::internal::closing, kcenon::network::internal::draining, kcenon::network::protocols::quic::connection_close_frame::error_code, kcenon::network::protocols::quic::connection_close_frame::is_application_error, kcenon::network::ok(), and kcenon::network::protocols::quic::connection_close_frame::reason_phrase.

Here is the call graph for this function:

◆ close_stream()

auto kcenon::network::internal::quic_socket::close_stream ( uint64_t stream_id) -> VoidResult
nodiscard

Close a stream.

Parameters
stream_idStream to close
Returns
Success or error

Definition at line 377 of file quic_socket.cpp.

378{
379 std::lock_guard<std::mutex> lock(state_mutex_);
380
381 auto it = pending_stream_data_.find(stream_id);
382 if (it == pending_stream_data_.end())
383 {
384 return error_void(
386 "Stream not found",
387 "quic_socket");
388 }
389
390 // Send FIN on the stream
391 it->second.push_back({{}, true});
392
394
395 return ok();
396}
auto send_pending_packets() -> void
Send pending outgoing packets.
std::mutex state_mutex_
Mutex for state protection.

References kcenon::network::error_void(), kcenon::network::error_codes::common_errors::not_found, and kcenon::network::ok().

Here is the call graph for this function:

◆ connect()

auto kcenon::network::internal::quic_socket::connect ( const asio::ip::udp::endpoint & endpoint,
const std::string & server_name = "" ) -> VoidResult
nodiscard

Connect to a remote server (client only)

Parameters
endpointRemote endpoint to connect to
server_nameServer name for SNI (TLS)
Returns
Success or error

Definition at line 135 of file quic_socket.cpp.

137{
139 {
140 return error_void(
142 "connect() can only be called on client sockets",
143 "quic_socket");
144 }
145
147 {
148 return error_void(
150 "Connection already in progress or established",
151 "quic_socket");
152 }
153
154 remote_endpoint_ = endpoint;
155
156 // Initialize client-side crypto
157 auto init_result = crypto_.init_client(
158 server_name.empty() ? endpoint.address().to_string() : server_name);
159 if (init_result.is_err())
160 {
161 return error_void(
163 "Failed to initialize TLS client",
164 "quic_socket",
165 init_result.error().message);
166 }
167
168 // Generate initial secrets from destination connection ID
169 // For client, we use a random connection ID as the destination
171
172 auto derive_result = crypto_.derive_initial_secrets(remote_conn_id_);
173 if (derive_result.is_err())
174 {
175 return error_void(
177 "Failed to derive initial secrets",
178 "quic_socket",
179 derive_result.error().message);
180 }
181
183
184 // Start handshake - generate ClientHello
185 auto handshake_result = crypto_.start_handshake();
186 if (handshake_result.is_err())
187 {
189 return error_void(
191 "Failed to start TLS handshake",
192 "quic_socket",
193 handshake_result.error().message);
194 }
195
196 // Queue the CRYPTO data for sending
197 if (!handshake_result.value().empty())
198 {
199 queue_crypto_data(std::move(handshake_result.value()));
200 }
201
203
204 // Start receiving
206
207 // Send initial packet
209
210 return ok();
211}
auto queue_crypto_data(std::vector< uint8_t > &&data) -> void
Queue crypto data for sending.
auto start_handshake() -> Result< std::vector< uint8_t > >
Start the handshake (generate initial CRYPTO data)
Definition crypto.cpp:965
auto init_client(const std::string &server_name) -> VoidResult
Initialize as client.
Definition crypto.cpp:782
auto derive_initial_secrets(const connection_id &dest_cid) -> VoidResult
Derive initial secrets from destination connection ID.
Definition crypto.cpp:883

References kcenon::network::internal::client, kcenon::network::internal::closed, kcenon::network::error_codes::network_system::connection_failed, kcenon::network::error_void(), kcenon::network::internal::handshake, kcenon::network::internal::handshake_start, kcenon::network::internal::idle, kcenon::network::error_codes::common_errors::invalid_argument, and kcenon::network::ok().

Here is the call graph for this function:

◆ create_stream()

auto kcenon::network::internal::quic_socket::create_stream ( bool unidirectional = false) -> Result<uint64_t>
nodiscard

Create a new stream.

Parameters
unidirectionalTrue for unidirectional stream
Returns
Stream ID or error

Definition at line 341 of file quic_socket.cpp.

342{
343 if (!is_connected())
344 {
345 return error<uint64_t>(
347 "Connection not established",
348 "quic_socket");
349 }
350
351 std::lock_guard<std::mutex> lock(state_mutex_);
352
353 // Stream ID encoding (RFC 9000 Section 2.1):
354 // - Bits 0-1: Type (0=client-initiated bidi, 1=server-initiated bidi,
355 // 2=client-initiated uni, 3=server-initiated uni)
356 // - Bits 2+: Sequence number
357
358 uint64_t type_bits = 0;
360 {
361 type_bits |= 0x01; // Server-initiated
362 }
363 if (unidirectional)
364 {
365 type_bits |= 0x02; // Unidirectional
366 }
367
368 uint64_t stream_id = (next_stream_id_ << 2) | type_bits;
370
371 // Initialize the stream's pending data queue
372 pending_stream_data_[stream_id] = {};
373
374 return ok(std::move(stream_id));
375}
auto is_connected() const noexcept -> bool
Check if the connection is established.
@ error
Black hole detected, reset to base.

References kcenon::network::error_codes::network_system::connection_failed, kcenon::network::protocols::quic::error, kcenon::network::ok(), and kcenon::network::internal::server.

Here is the call graph for this function:

◆ determine_encryption_level()

auto kcenon::network::internal::quic_socket::determine_encryption_level ( const protocols::quic::packet_header & header) const -> protocols::quic::encryption_level
nodiscardprivatenoexcept

Determine encryption level from packet header.

Parameters
headerPacket header
Returns
Encryption level

Definition at line 905 of file quic_socket.cpp.

907{
908 if (std::holds_alternative<long_header>(header))
909 {
910 const auto& lh = std::get<long_header>(header);
911 switch (lh.type())
912 {
913 case packet_type::initial:
914 return encryption_level::initial;
915 case packet_type::zero_rtt:
916 return encryption_level::zero_rtt;
917 case packet_type::handshake:
918 return encryption_level::handshake;
919 default:
920 return encryption_level::initial;
921 }
922 }
923 else
924 {
925 // Short header = 1-RTT = application level
926 return encryption_level::application;
927 }
928}

◆ do_receive()

auto kcenon::network::internal::quic_socket::do_receive ( ) -> void
private

Internal receive loop implementation.

Definition at line 441 of file quic_socket.cpp.

442{
443 if (!is_receiving_.load())
444 {
445 return;
446 }
447
448 auto self = shared_from_this();
449 udp_socket_.async_receive_from(
450 asio::buffer(recv_buffer_),
452 [this, self](std::error_code ec, std::size_t bytes_transferred)
453 {
454 if (!is_receiving_.load())
455 {
456 return;
457 }
458
459 if (ec)
460 {
461 if (ec != asio::error::operation_aborted)
462 {
463 std::lock_guard<std::mutex> lock(callback_mutex_);
464 if (error_cb_)
465 {
466 error_cb_(ec);
467 }
468 }
469 return;
470 }
471
472 if (bytes_transferred > 0)
473 {
474 handle_packet(std::span(recv_buffer_.data(), bytes_transferred));
475 }
476
477 // Continue receiving
478 if (is_receiving_.load())
479 {
480 do_receive();
481 }
482 });
483}
std::mutex callback_mutex_
Mutex for callback protection.
auto handle_packet(std::span< const uint8_t > data) -> void
Handle received packet data.
auto do_receive() -> void
Internal receive loop implementation.

◆ generate_connection_id()

auto kcenon::network::internal::quic_socket::generate_connection_id ( ) -> protocols::quic::connection_id
nodiscardprivate

Generate a new connection ID.

Returns
Generated connection ID

Definition at line 930 of file quic_socket.cpp.

931{
932 std::random_device rd;
933 std::mt19937 gen(rd());
934 std::uniform_int_distribution<unsigned int> dis(0, 255);
935
936 std::array<uint8_t, 8> id_bytes;
937 for (auto& byte : id_bytes)
938 {
939 byte = static_cast<uint8_t>(dis(gen));
940 }
941
942 return connection_id(std::span<const uint8_t>(id_bytes));
943}

Referenced by quic_socket().

Here is the caller graph for this function:

◆ handle_packet()

auto kcenon::network::internal::quic_socket::handle_packet ( std::span< const uint8_t > data) -> void
private

Handle received packet data.

Parameters
dataRaw packet bytes

Definition at line 485 of file quic_socket.cpp.

486{
487 // Parse packet header
488 auto header_result = packet_parser::parse_header(data);
489 if (header_result.is_err())
490 {
491 // Invalid packet - silently ignore
492 return;
493 }
494
495 auto& [header, header_length] = header_result.value();
496
497 // Determine encryption level
498 auto level = determine_encryption_level(header);
499
500 // For server, derive initial secrets on first Initial packet
501 if (role_ == quic_role::server &&
503 {
504 if (std::holds_alternative<long_header>(header))
505 {
506 const auto& lh = std::get<long_header>(header);
507 if (lh.type() == packet_type::initial)
508 {
509 // Use client's DCID as our remote connection ID
510 remote_conn_id_ = lh.src_conn_id;
511
512 // Derive initial secrets from client's DCID
513 auto derive_result = crypto_.derive_initial_secrets(lh.dest_conn_id);
514 if (derive_result.is_err())
515 {
516 return;
517 }
518
520 }
521 }
522 }
523
524 // Get read keys for this level
525 auto keys_result = crypto_.get_read_keys(level);
526 if (keys_result.is_err())
527 {
528 // Keys not available yet - queue packet for later processing
529 return;
530 }
531
532 // Unprotect (decrypt) the packet
533 // First we need to get the packet number offset
534 size_t pn_offset = header_length;
535 if (std::holds_alternative<long_header>(header))
536 {
537 // For long headers, packet number is after the header
538 // (already accounted for in header_length for Initial/Handshake)
539 }
540
541 // Determine packet number length from header (after removing header protection)
542 size_t sample_offset = pn_offset + 4; // Sample is 4 bytes after PN start
543 if (sample_offset + hp_sample_size > data.size())
544 {
545 return; // Not enough data for sample
546 }
547
548 std::span<const uint8_t> sample(data.data() + sample_offset, hp_sample_size);
549
550 // Create mutable copy for header unprotection
551 std::vector<uint8_t> packet_copy(data.begin(), data.end());
552
553 auto unprotect_header_result = packet_protection::unprotect_header(
554 keys_result.value(),
555 std::span(packet_copy.data(), header_length + 4), // Include space for max PN
556 pn_offset,
557 sample);
558
559 if (unprotect_header_result.is_err())
560 {
561 return;
562 }
563
564 auto& [first_byte, pn_length] = unprotect_header_result.value();
565
566 // Extract packet number
567 uint64_t truncated_pn = 0;
568 for (size_t i = 0; i < pn_length; ++i)
569 {
570 truncated_pn = (truncated_pn << 8) | packet_copy[pn_offset + i];
571 }
572
573 // Decode full packet number
574 auto level_idx = static_cast<size_t>(level);
575 uint64_t full_pn = packet_number::decode(
576 truncated_pn, pn_length, largest_received_pn_[level_idx]);
577
578 // Update largest received
579 if (full_pn > largest_received_pn_[level_idx])
580 {
581 largest_received_pn_[level_idx] = full_pn;
582 }
583
584 // Decrypt packet payload
585 size_t payload_offset = pn_offset + pn_length;
586 auto unprotect_result = packet_protection::unprotect(
587 keys_result.value(),
588 std::span(packet_copy),
589 payload_offset,
590 full_pn);
591
592 if (unprotect_result.is_err())
593 {
594 return;
595 }
596
597 auto& [unprotected_header, payload] = unprotect_result.value();
598
599 // Parse frames from payload
600 auto frames_result = frame_parser::parse_all(payload);
601 if (frames_result.is_err())
602 {
603 return;
604 }
605
606 // Process each frame
607 for (const auto& f : frames_result.value())
608 {
609 process_frame(f);
610 }
611
612 // Send any pending responses
614}
auto determine_encryption_level(const protocols::quic::packet_header &header) const noexcept -> protocols::quic::encryption_level
Determine encryption level from packet header.
auto process_frame(const protocols::quic::frame &f) -> void
Process a parsed frame.
static auto parse_all(std::span< const uint8_t > data) -> Result< std::vector< frame > >
Parse all frames from buffer.
Definition frame.cpp:343
static auto decode(uint64_t truncated_pn, size_t pn_length, uint64_t largest_pn) noexcept -> uint64_t
Decode a packet number from received data.
Definition packet.cpp:103
static auto parse_header(std::span< const uint8_t > data) -> Result< std::pair< packet_header, size_t > >
Parse a packet header (without header protection removal)
Definition packet.cpp:168
static auto unprotect_header(const quic_keys &keys, std::span< uint8_t > header, size_t pn_offset, std::span< const uint8_t > sample) -> Result< std::pair< uint8_t, size_t > >
Remove header protection.
Definition crypto.cpp:687
static auto unprotect(const quic_keys &keys, std::span< const uint8_t > packet, size_t header_length, uint64_t packet_number) -> Result< std::pair< std::vector< uint8_t >, std::vector< uint8_t > > >
Unprotect (decrypt) a QUIC packet.
Definition crypto.cpp:508
auto get_read_keys(encryption_level level) const -> Result< quic_keys >
Get read keys for an encryption level.
Definition crypto.cpp:1026
constexpr size_t hp_sample_size
Header protection sample size.
Definition keys.h:37

References kcenon::network::protocols::quic::packet_number::decode(), kcenon::network::internal::handshake, kcenon::network::internal::handshake_start, kcenon::network::protocols::quic::hp_sample_size, kcenon::network::protocols::quic::frame_parser::parse_all(), kcenon::network::protocols::quic::packet_parser::parse_header(), kcenon::network::internal::server, kcenon::network::protocols::quic::packet_protection::unprotect(), and kcenon::network::protocols::quic::packet_protection::unprotect_header().

Here is the call graph for this function:

◆ is_connected()

auto kcenon::network::internal::quic_socket::is_connected ( ) const -> bool
nodiscardnoexcept

Check if the connection is established.

Returns
True if connected

Definition at line 402 of file quic_socket.cpp.

403{
405}

References kcenon::network::internal::connected, and state_.

◆ is_handshake_complete()

auto kcenon::network::internal::quic_socket::is_handshake_complete ( ) const -> bool
nodiscardnoexcept

Check if the TLS handshake is complete.

Returns
True if handshake is done

Definition at line 407 of file quic_socket.cpp.

408{
409 return handshake_complete_.load();
410}

References handshake_complete_.

◆ local_connection_id()

auto kcenon::network::internal::quic_socket::local_connection_id ( ) const -> const protocols::quic::connection_id&
nodiscard

Get the local connection ID.

Returns
Local connection ID

Definition at line 427 of file quic_socket.cpp.

428{
429 return local_conn_id_;
430}

References local_conn_id_.

◆ on_retransmit_timeout()

auto kcenon::network::internal::quic_socket::on_retransmit_timeout ( ) -> void
private

Retransmission timeout handler.

Definition at line 945 of file quic_socket.cpp.

946{
947 // Retransmission logic would go here
948 // For now, just resend pending packets
950}

◆ operator=() [1/2]

quic_socket & kcenon::network::internal::quic_socket::operator= ( const quic_socket & )
delete

◆ operator=() [2/2]

quic_socket & kcenon::network::internal::quic_socket::operator= ( quic_socket && other)
noexcept

Definition at line 69 of file quic_socket.cpp.

70{
71 if (this != &other)
72 {
74
75 udp_socket_ = std::move(other.udp_socket_);
76 remote_endpoint_ = std::move(other.remote_endpoint_);
77 recv_buffer_ = std::move(other.recv_buffer_);
78 role_ = other.role_;
79 state_.store(other.state_.load());
80 crypto_ = std::move(other.crypto_);
81 local_conn_id_ = std::move(other.local_conn_id_);
82 remote_conn_id_ = std::move(other.remote_conn_id_);
83 next_packet_number_ = other.next_packet_number_;
84 largest_received_pn_ = other.largest_received_pn_;
85 next_stream_id_ = other.next_stream_id_;
86 pending_crypto_data_ = std::move(other.pending_crypto_data_);
87 pending_stream_data_ = std::move(other.pending_stream_data_);
88
89 std::lock_guard<std::mutex> lock(callback_mutex_);
90 stream_data_cb_ = std::move(other.stream_data_cb_);
91 connected_cb_ = std::move(other.connected_cb_);
92 error_cb_ = std::move(other.error_cb_);
93 close_cb_ = std::move(other.close_cb_);
94
95 is_receiving_.store(other.is_receiving_.load());
96 handshake_complete_.store(other.handshake_complete_.load());
97 retransmit_timer_ = std::move(other.retransmit_timer_);
98 idle_timer_ = std::move(other.idle_timer_);
99 }
100 return *this;
101}

◆ process_ack_frame()

auto kcenon::network::internal::quic_socket::process_ack_frame ( const protocols::quic::ack_frame & f) -> void
private

Process ACK frame.

Parameters
fACK frame

Definition at line 715 of file quic_socket.cpp.

716{
717 // Process ACK - remove acknowledged packets from retransmission queue
718 // For now, just track the largest acknowledged
719 (void)f; // Placeholder for full implementation
720}

◆ process_connection_close_frame()

auto kcenon::network::internal::quic_socket::process_connection_close_frame ( const protocols::quic::connection_close_frame & f) -> void
private

Process CONNECTION_CLOSE frame.

Parameters
fConnection close frame

Definition at line 722 of file quic_socket.cpp.

723{
725
726 std::lock_guard<std::mutex> lock(callback_mutex_);
727 if (close_cb_)
728 {
729 close_cb_(f.error_code, f.reason_phrase);
730 }
731
732 // Enter draining period
733 idle_timer_.expires_after(std::chrono::milliseconds(300));
734 idle_timer_.async_wait(
735 [self = shared_from_this()](const std::error_code& ec)
736 {
737 if (!ec)
738 {
739 self->transition_state(quic_connection_state::closed);
740 self->stop_receive();
741 }
742 });
743}

References kcenon::network::internal::closed, and kcenon::network::internal::draining.

◆ process_crypto_frame()

auto kcenon::network::internal::quic_socket::process_crypto_frame ( const protocols::quic::crypto_frame & f) -> void
private

Process CRYPTO frame data.

Parameters
fCrypto frame

Definition at line 653 of file quic_socket.cpp.

654{
655 auto level = crypto_.current_level();
656
657 // Process the crypto data through TLS
658 auto response_result = crypto_.process_crypto_data(level, f.data);
659 if (response_result.is_err())
660 {
661 return;
662 }
663
664 // Queue any response crypto data
665 if (!response_result.value().empty())
666 {
667 queue_crypto_data(std::move(response_result.value()));
668 }
669
670 // Check if handshake is now complete
672 {
673 handshake_complete_.store(true);
674
675 // For client, transition to connected
676 // For server, we send HANDSHAKE_DONE
678 {
680
681 std::lock_guard<std::mutex> lock(callback_mutex_);
682 if (connected_cb_)
683 {
685 }
686 }
687 else
688 {
689 // Server sends HANDSHAKE_DONE
690 std::vector<frame> frames;
691 frames.push_back(handshake_done_frame{});
692
693 (void)send_packet(encryption_level::application, std::move(frames));
694
696
697 std::lock_guard<std::mutex> lock(callback_mutex_);
698 if (connected_cb_)
699 {
701 }
702 }
703 }
704}
auto process_crypto_data(encryption_level level, std::span< const uint8_t > data) -> Result< std::vector< uint8_t > >
Process incoming CRYPTO frame data.
Definition crypto.cpp:912
auto current_level() const noexcept -> encryption_level
Get current encryption level.
Definition crypto.cpp:1008
auto is_handshake_complete() const noexcept -> bool
Check if the handshake is complete.
Definition crypto.cpp:1003

References kcenon::network::internal::client, and kcenon::network::internal::connected.

◆ process_frame()

auto kcenon::network::internal::quic_socket::process_frame ( const protocols::quic::frame & f) -> void
private

Process a parsed frame.

Parameters
fFrame to process

Definition at line 616 of file quic_socket.cpp.

617{
618 std::visit([this](auto&& arg) {
619 using T = std::decay_t<decltype(arg)>;
620
621 if constexpr (std::is_same_v<T, crypto_frame>)
622 {
624 }
625 else if constexpr (std::is_same_v<T, stream_frame>)
626 {
628 }
629 else if constexpr (std::is_same_v<T, ack_frame>)
630 {
632 }
633 else if constexpr (std::is_same_v<T, connection_close_frame>)
634 {
636 }
637 else if constexpr (std::is_same_v<T, handshake_done_frame>)
638 {
640 }
641 else if constexpr (std::is_same_v<T, ping_frame>)
642 {
643 // PING requires ACK - will be sent with next packet
644 }
645 else if constexpr (std::is_same_v<T, padding_frame>)
646 {
647 // PADDING is ignored
648 }
649 // Other frame types can be added as needed
650 }, f);
651}
auto process_connection_close_frame(const protocols::quic::connection_close_frame &f) -> void
Process CONNECTION_CLOSE frame.
auto process_handshake_done_frame() -> void
Process HANDSHAKE_DONE frame.
auto process_ack_frame(const protocols::quic::ack_frame &f) -> void
Process ACK frame.
auto process_stream_frame(const protocols::quic::stream_frame &f) -> void
Process STREAM frame data.
auto process_crypto_frame(const protocols::quic::crypto_frame &f) -> void
Process CRYPTO frame data.

◆ process_handshake_done_frame()

auto kcenon::network::internal::quic_socket::process_handshake_done_frame ( ) -> void
private

Process HANDSHAKE_DONE frame.

Definition at line 745 of file quic_socket.cpp.

746{
747 // Client receives HANDSHAKE_DONE
749 {
750 handshake_complete_.store(true);
752
753 std::lock_guard<std::mutex> lock(callback_mutex_);
754 if (connected_cb_)
755 {
757 }
758 }
759}

References kcenon::network::internal::client, and kcenon::network::internal::connected.

◆ process_stream_frame()

auto kcenon::network::internal::quic_socket::process_stream_frame ( const protocols::quic::stream_frame & f) -> void
private

Process STREAM frame data.

Parameters
fStream frame

Definition at line 706 of file quic_socket.cpp.

707{
708 std::lock_guard<std::mutex> lock(callback_mutex_);
709 if (stream_data_cb_)
710 {
711 stream_data_cb_(f.stream_id, f.data, f.fin);
712 }
713}

◆ queue_crypto_data()

auto kcenon::network::internal::quic_socket::queue_crypto_data ( std::vector< uint8_t > && data) -> void
private

Queue crypto data for sending.

Parameters
dataCrypto data to send

Definition at line 896 of file quic_socket.cpp.

897{
898 auto level = crypto_.current_level();
899 auto level_idx = static_cast<size_t>(level);
900
901 std::lock_guard<std::mutex> lock(state_mutex_);
902 pending_crypto_data_[level_idx].push_back(std::move(data));
903}

◆ remote_connection_id()

auto kcenon::network::internal::quic_socket::remote_connection_id ( ) const -> const protocols::quic::connection_id&
nodiscard

Get the remote connection ID.

Returns
Remote connection ID

Definition at line 432 of file quic_socket.cpp.

433{
434 return remote_conn_id_;
435}

References remote_conn_id_.

◆ remote_endpoint()

auto kcenon::network::internal::quic_socket::remote_endpoint ( ) const -> asio::ip::udp::endpoint
nodiscard

Get the remote endpoint.

Returns
Remote endpoint

Definition at line 422 of file quic_socket.cpp.

423{
424 return remote_endpoint_;
425}

References remote_endpoint_.

◆ role()

auto kcenon::network::internal::quic_socket::role ( ) const -> quic_role
nodiscardnoexcept

Get the role (client or server)

Returns
Role

Definition at line 417 of file quic_socket.cpp.

418{
419 return role_;
420}

References role_.

◆ send_packet()

auto kcenon::network::internal::quic_socket::send_packet ( protocols::quic::encryption_level level,
std::vector< protocols::quic::frame > && frames ) -> VoidResult
nodiscardprivate

Build and send a packet with frames.

Parameters
levelEncryption level
framesFrames to include
Returns
Success or error

Definition at line 816 of file quic_socket.cpp.

818{
819 // Get write keys
820 auto keys_result = crypto_.get_write_keys(level);
821 if (keys_result.is_err())
822 {
823 return error_void(
825 "Write keys not available",
826 "quic_socket");
827 }
828
829 // Build frames payload
830 std::vector<uint8_t> payload;
831 for (const auto& f : frames)
832 {
833 auto frame_bytes = frame_builder::build(f);
834 payload.insert(payload.end(), frame_bytes.begin(), frame_bytes.end());
835 }
836
837 // Get next packet number
838 auto level_idx = static_cast<size_t>(level);
839 uint64_t pn = next_packet_number_[level_idx]++;
840
841 // Build header
842 std::vector<uint8_t> header;
843 if (level == encryption_level::initial)
844 {
847 }
848 else if (level == encryption_level::handshake)
849 {
852 }
853 else
854 {
857 }
858
859 // Protect (encrypt) the packet
860 auto protect_result = packet_protection::protect(
861 keys_result.value(), header, payload, pn);
862
863 if (protect_result.is_err())
864 {
865 return error_void(
867 "Failed to protect packet",
868 "quic_socket",
869 protect_result.error().message);
870 }
871
872 // Send the packet
873 auto& protected_packet = protect_result.value();
874
875 auto self = shared_from_this();
876 auto buffer = std::make_shared<std::vector<uint8_t>>(std::move(protected_packet));
877
878 udp_socket_.async_send_to(
879 asio::buffer(*buffer),
881 [self, buffer](std::error_code ec, std::size_t /*bytes_sent*/)
882 {
883 if (ec && ec != asio::error::operation_aborted)
884 {
885 std::lock_guard<std::mutex> lock(self->callback_mutex_);
886 if (self->error_cb_)
887 {
888 self->error_cb_(ec);
889 }
890 }
891 });
892
893 return ok();
894}
static auto build(const frame &f) -> std::vector< uint8_t >
Build any frame from variant.
Definition frame.cpp:891
static auto build_handshake(const connection_id &dest_cid, const connection_id &src_cid, uint64_t packet_number, uint32_t version=quic_version::version_1) -> std::vector< uint8_t >
Build a Handshake packet header.
Definition packet.cpp:467
static auto build_short(const connection_id &dest_cid, uint64_t packet_number, bool key_phase=false, bool spin_bit=false) -> std::vector< uint8_t >
Build a Short Header (1-RTT) packet.
Definition packet.cpp:578
static auto build_initial(const connection_id &dest_cid, const connection_id &src_cid, const std::vector< uint8_t > &token, uint64_t packet_number, uint32_t version=quic_version::version_1) -> std::vector< uint8_t >
Build an Initial packet header.
Definition packet.cpp:423
static auto protect(const quic_keys &keys, std::span< const uint8_t > header, std::span< const uint8_t > payload, uint64_t packet_number) -> Result< std::vector< uint8_t > >
Protect (encrypt) a QUIC packet.
Definition crypto.cpp:425
auto get_write_keys(encryption_level level) const -> Result< quic_keys >
Get write keys for an encryption level.
Definition crypto.cpp:1013
auto key_phase() const noexcept -> uint8_t
Get current key phase (for key updates)
Definition crypto.cpp:1137

References kcenon::network::protocols::quic::frame_builder::build(), kcenon::network::protocols::quic::packet_builder::build_handshake(), kcenon::network::protocols::quic::packet_builder::build_initial(), kcenon::network::protocols::quic::packet_builder::build_short(), kcenon::network::error_void(), kcenon::network::error_codes::common_errors::internal_error, kcenon::network::error_codes::common_errors::not_initialized, kcenon::network::ok(), and kcenon::network::protocols::quic::packet_protection::protect().

Here is the call graph for this function:

◆ send_pending_packets()

auto kcenon::network::internal::quic_socket::send_pending_packets ( ) -> void
private

Send pending outgoing packets.

Definition at line 761 of file quic_socket.cpp.

762{
763 auto current_state = state_.load();
764 if (current_state == quic_connection_state::closed ||
765 current_state == quic_connection_state::idle)
766 {
767 return;
768 }
769
770 // Determine which encryption level to use
772
773 std::vector<frame> frames;
774
775 // Add pending CRYPTO data
776 {
777 std::lock_guard<std::mutex> lock(state_mutex_);
778 auto level_idx = static_cast<size_t>(level);
779 while (!pending_crypto_data_[level_idx].empty())
780 {
781 auto& data = pending_crypto_data_[level_idx].front();
782 crypto_frame cf;
783 cf.offset = 0; // Simplified - full impl needs offset tracking
784 cf.data = std::move(data);
785 frames.push_back(std::move(cf));
786 pending_crypto_data_[level_idx].pop_front();
787 }
788 }
789
790 // Add pending STREAM data (only if connected)
791 if (is_connected())
792 {
793 std::lock_guard<std::mutex> lock(state_mutex_);
794 for (auto& [stream_id, queue] : pending_stream_data_)
795 {
796 while (!queue.empty())
797 {
798 auto& [data, fin] = queue.front();
799 stream_frame sf;
800 sf.stream_id = stream_id;
801 sf.offset = 0; // Simplified - full impl needs offset tracking
802 sf.data = std::move(data);
803 sf.fin = fin;
804 frames.push_back(std::move(sf));
805 queue.pop_front();
806 }
807 }
808 }
809
810 if (!frames.empty())
811 {
812 (void)send_packet(level, std::move(frames));
813 }
814}
constexpr uint8_t fin
Stream is finished.
Definition frame_types.h:63
encryption_level
QUIC encryption levels (RFC 9001 Section 4)
Definition keys.h:54

References kcenon::network::internal::closed, kcenon::network::protocols::quic::crypto_frame::data, kcenon::network::protocols::quic::stream_frame::data, kcenon::network::protocols::quic::stream_frame::fin, kcenon::network::internal::idle, kcenon::network::protocols::quic::crypto_frame::offset, kcenon::network::protocols::quic::stream_frame::offset, and kcenon::network::protocols::quic::stream_frame::stream_id.

◆ send_stream_data()

auto kcenon::network::internal::quic_socket::send_stream_data ( uint64_t stream_id,
std::vector< uint8_t > && data,
bool fin = false ) -> VoidResult
nodiscard

Send data on a stream.

Parameters
stream_idTarget stream ID
dataData to send (moved for efficiency)
finTrue if this is the final data on the stream
Returns
Success or error

Definition at line 315 of file quic_socket.cpp.

318{
319 if (!is_connected())
320 {
321 return error_void(
323 "Connection not established",
324 "quic_socket");
325 }
326
327 {
328 std::lock_guard<std::mutex> lock(state_mutex_);
329 pending_stream_data_[stream_id].push_back({std::move(data), fin});
330 }
331
333
334 return ok();
335}

References kcenon::network::error_codes::network_system::connection_failed, kcenon::network::error_void(), and kcenon::network::ok().

Here is the call graph for this function:

◆ set_close_callback()

auto kcenon::network::internal::quic_socket::set_close_callback ( close_callback cb) -> void

Set callback for connection close.

Parameters
cbCallback function

Definition at line 125 of file quic_socket.cpp.

126{
127 std::lock_guard<std::mutex> lock(callback_mutex_);
128 close_cb_ = std::move(cb);
129}

◆ set_connected_callback()

auto kcenon::network::internal::quic_socket::set_connected_callback ( connected_callback cb) -> void

Set callback for connection establishment.

Parameters
cbCallback function

Definition at line 113 of file quic_socket.cpp.

114{
115 std::lock_guard<std::mutex> lock(callback_mutex_);
116 connected_cb_ = std::move(cb);
117}

◆ set_error_callback()

auto kcenon::network::internal::quic_socket::set_error_callback ( error_callback cb) -> void

Set callback for errors.

Parameters
cbCallback function

Definition at line 119 of file quic_socket.cpp.

120{
121 std::lock_guard<std::mutex> lock(callback_mutex_);
122 error_cb_ = std::move(cb);
123}

◆ set_stream_data_callback()

auto kcenon::network::internal::quic_socket::set_stream_data_callback ( stream_data_callback cb) -> void

Set callback for stream data reception.

Parameters
cbCallback function

Definition at line 107 of file quic_socket.cpp.

108{
109 std::lock_guard<std::mutex> lock(callback_mutex_);
110 stream_data_cb_ = std::move(cb);
111}

◆ socket() [1/2]

auto kcenon::network::internal::quic_socket::socket ( ) -> asio::ip::udp::socket&
inline

Access the underlying UDP socket.

Returns
Reference to the UDP socket

Definition at line 285 of file quic_socket.h.

285{ return udp_socket_; }

References udp_socket_.

◆ socket() [2/2]

auto kcenon::network::internal::quic_socket::socket ( ) const -> const asio::ip::udp::socket&
inline

Access the underlying UDP socket (const)

Returns
Const reference to the UDP socket

Definition at line 291 of file quic_socket.h.

291{ return udp_socket_; }

References udp_socket_.

◆ start_receive()

auto kcenon::network::internal::quic_socket::start_receive ( ) -> void

Start the receive loop.

Once called, the socket continuously receives UDP datagrams, processes QUIC packets, and invokes appropriate callbacks.

Definition at line 304 of file quic_socket.cpp.

305{
306 is_receiving_.store(true);
307 do_receive();
308}

◆ state()

auto kcenon::network::internal::quic_socket::state ( ) const -> quic_connection_state
nodiscardnoexcept

Get the current connection state.

Returns
Connection state

Definition at line 412 of file quic_socket.cpp.

413{
414 return state_.load();
415}

References state_.

◆ stop_receive()

auto kcenon::network::internal::quic_socket::stop_receive ( ) -> void

Stop the receive loop.

Definition at line 310 of file quic_socket.cpp.

311{
312 is_receiving_.store(false);
313}

Referenced by ~quic_socket().

Here is the caller graph for this function:

◆ transition_state()

auto kcenon::network::internal::quic_socket::transition_state ( quic_connection_state new_state) -> void
private

Transition to a new connection state.

Parameters
new_stateNew state

Definition at line 952 of file quic_socket.cpp.

953{
954 state_.store(new_state);
955}

Member Data Documentation

◆ callback_mutex_

std::mutex kcenon::network::internal::quic_socket::callback_mutex_
mutableprivate

Mutex for callback protection.

Definition at line 445 of file quic_socket.h.

◆ close_cb_

close_callback kcenon::network::internal::quic_socket::close_cb_
private

Close callback.

Definition at line 457 of file quic_socket.h.

◆ connected_cb_

connected_callback kcenon::network::internal::quic_socket::connected_cb_
private

Connected callback.

Definition at line 451 of file quic_socket.h.

◆ crypto_

protocols::quic::quic_crypto kcenon::network::internal::quic_socket::crypto_
private

QUIC crypto handler.

Definition at line 413 of file quic_socket.h.

◆ error_cb_

error_callback kcenon::network::internal::quic_socket::error_cb_
private

Error callback.

Definition at line 454 of file quic_socket.h.

◆ handshake_complete_

std::atomic<bool> kcenon::network::internal::quic_socket::handshake_complete_ {false}
private

Is handshake complete.

Definition at line 467 of file quic_socket.h.

467{false};

Referenced by is_handshake_complete().

◆ idle_timer_

asio::steady_timer kcenon::network::internal::quic_socket::idle_timer_
private

Idle timeout timer.

Definition at line 477 of file quic_socket.h.

Referenced by ~quic_socket().

◆ is_receiving_

std::atomic<bool> kcenon::network::internal::quic_socket::is_receiving_ {false}
private

Is receive loop running.

Definition at line 464 of file quic_socket.h.

464{false};

◆ largest_received_pn_

std::array<uint64_t, 4> kcenon::network::internal::quic_socket::largest_received_pn_ {0, 0, 0, 0}
private

Largest received packet number for each level.

Definition at line 425 of file quic_socket.h.

425{0, 0, 0, 0};

◆ local_conn_id_

protocols::quic::connection_id kcenon::network::internal::quic_socket::local_conn_id_
private

Local connection ID.

Definition at line 416 of file quic_socket.h.

Referenced by local_connection_id(), and quic_socket().

◆ next_packet_number_

std::array<uint64_t, 4> kcenon::network::internal::quic_socket::next_packet_number_ {0, 0, 0, 0}
private

Packet number for each encryption level.

Definition at line 422 of file quic_socket.h.

422{0, 0, 0, 0};

◆ next_stream_id_

uint64_t kcenon::network::internal::quic_socket::next_stream_id_ {0}
private

Next stream ID to allocate.

Definition at line 428 of file quic_socket.h.

428{0};

Referenced by quic_socket().

◆ pending_crypto_data_

std::array<std::deque<std::vector<uint8_t> >, 4> kcenon::network::internal::quic_socket::pending_crypto_data_
private

Pending crypto data to send per encryption level.

Definition at line 435 of file quic_socket.h.

◆ pending_stream_data_

std::map<uint64_t, std::deque<std::pair<std::vector<uint8_t>, bool> > > kcenon::network::internal::quic_socket::pending_stream_data_
private

Pending stream data to send (stream_id -> data queue)

Definition at line 438 of file quic_socket.h.

◆ recv_buffer_

std::array<uint8_t, 65536> kcenon::network::internal::quic_socket::recv_buffer_
private

Receive buffer (max UDP datagram size)

Definition at line 404 of file quic_socket.h.

◆ remote_conn_id_

protocols::quic::connection_id kcenon::network::internal::quic_socket::remote_conn_id_
private

Remote connection ID.

Definition at line 419 of file quic_socket.h.

Referenced by remote_connection_id().

◆ remote_endpoint_

asio::ip::udp::endpoint kcenon::network::internal::quic_socket::remote_endpoint_
private

Remote endpoint.

Definition at line 401 of file quic_socket.h.

Referenced by remote_endpoint().

◆ retransmit_timer_

asio::steady_timer kcenon::network::internal::quic_socket::retransmit_timer_
private

Retransmission timer.

Definition at line 474 of file quic_socket.h.

Referenced by ~quic_socket().

◆ role_

quic_role kcenon::network::internal::quic_socket::role_
private

Socket role (client/server)

Definition at line 407 of file quic_socket.h.

Referenced by quic_socket(), and role().

◆ state_

std::atomic<quic_connection_state> kcenon::network::internal::quic_socket::state_ {quic_connection_state::idle}
private

Connection state.

Definition at line 410 of file quic_socket.h.

Referenced by is_connected(), and state().

◆ state_mutex_

std::mutex kcenon::network::internal::quic_socket::state_mutex_
mutableprivate

Mutex for state protection.

Definition at line 480 of file quic_socket.h.

◆ stream_data_cb_

stream_data_callback kcenon::network::internal::quic_socket::stream_data_cb_
private

Stream data callback.

Definition at line 448 of file quic_socket.h.

◆ udp_socket_

asio::ip::udp::socket kcenon::network::internal::quic_socket::udp_socket_
private

Underlying UDP socket.

Definition at line 398 of file quic_socket.h.

Referenced by socket(), and socket().


The documentation for this class was generated from the following files: