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

A wrapper around ASIO UDP socket with OpenSSL DTLS encryption. More...

#include <dtls_socket.h>

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

Public Types

enum class  handshake_type { client , server }
 Handshake type enumeration. More...
 

Public Member Functions

 ~dtls_socket ()
 Destructor. Cleans up OpenSSL resources.
 
 dtls_socket (const dtls_socket &)=delete
 
dtls_socket & operator= (const dtls_socket &)=delete
 
 dtls_socket (dtls_socket &&)=delete
 
dtls_socket & operator= (dtls_socket &&)=delete
 
auto async_handshake (handshake_type type, std::function< void(std::error_code)> handler) -> void
 Performs asynchronous DTLS handshake.
 
auto set_receive_callback (std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> callback) -> void
 Sets a callback to receive decrypted inbound datagrams.
 
auto set_error_callback (std::function< void(std::error_code)> callback) -> void
 Sets a callback to handle socket errors.
 
auto start_receive () -> void
 Begins the continuous asynchronous receive loop.
 
auto stop_receive () -> void
 Stops the receive loop.
 
auto deliver_encrypted (const std::vector< uint8_t > &data, const asio::ip::udp::endpoint &sender) -> void
 Injects an already-received encrypted datagram for DTLS processing.
 
auto async_send (std::vector< uint8_t > &&data, std::function< void(std::error_code, std::size_t)> handler) -> void
 Initiates an asynchronous encrypted send.
 
auto async_send_to (std::vector< uint8_t > &&data, const asio::ip::udp::endpoint &endpoint, std::function< void(std::error_code, std::size_t)> handler) -> void
 Initiates an asynchronous encrypted send to a specific endpoint.
 
auto set_peer_endpoint (const asio::ip::udp::endpoint &endpoint) -> void
 Sets the peer endpoint for connected mode.
 
auto peer_endpoint () const -> asio::ip::udp::endpoint
 Returns the peer endpoint.
 
auto socket () -> asio::ip::udp::socket &
 Provides direct access to the underlying UDP socket.
 
auto is_handshake_complete () const -> bool
 Checks if the DTLS handshake is complete.
 

Static Public Member Functions

static Result< std::shared_ptr< dtls_socket > > create (asio::ip::udp::socket socket, SSL_CTX *ssl_ctx)
 Constructs a dtls_socket with an existing UDP socket.
 

Private Member Functions

 dtls_socket (asio::ip::udp::socket socket, SSL *ssl, BIO *rbio, BIO *wbio)
 
auto do_receive () -> void
 Internal function to handle the receive logic.
 
auto process_received_data (const std::vector< uint8_t > &data, const asio::ip::udp::endpoint &sender) -> void
 Processes received encrypted data through DTLS.
 
auto flush_bio_output () -> void
 Flushes pending DTLS output to the network.
 
auto continue_handshake () -> void
 Continues the handshake process.
 
auto make_ssl_error () const -> std::error_code
 Creates an OpenSSL error code from the current error state.
 

Private Attributes

asio::ip::udp::socket socket_
 
asio::ip::udp::endpoint peer_endpoint_
 
asio::ip::udp::endpoint sender_endpoint_
 
SSL_CTX * ssl_ctx_
 
SSL * ssl_
 
BIO * rbio_
 
BIO * wbio_
 
std::array< uint8_t, 65536 > read_buffer_
 
std::mutex ssl_mutex_
 
std::mutex callback_mutex_
 
std::mutex endpoint_mutex_
 
std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> receive_callback_
 
std::function< void(std::error_code)> error_callback_
 
std::function< void(std::error_code)> handshake_callback_
 
std::atomic< bool > is_receiving_ {false}
 
std::atomic< bool > handshake_complete_ {false}
 
std::atomic< bool > handshake_in_progress_ {false}
 
handshake_type handshake_type_ {handshake_type::client}
 

Detailed Description

A wrapper around ASIO UDP socket with OpenSSL DTLS encryption.

Key Features

  • Provides DTLS (Datagram TLS) encryption over UDP transport.
  • Uses OpenSSL's DTLS implementation with memory BIOs for async I/O.
  • Exposes set_receive_callback() to handle decrypted inbound datagrams and set_error_callback() for error handling.
  • start_receive() begins an ongoing loop of receiving encrypted datagrams.
  • async_send() encrypts and sends data to the configured peer.

Thread Safety

  • All public methods are thread-safe. Callback registration is protected by callback_mutex_.
  • ASIO operations are serialized through the io_context.
  • OpenSSL operations are protected by ssl_mutex_.
  • The provided callbacks will be invoked on an ASIO worker thread; ensure that your callback logic is thread-safe if it shares data.

DTLS Characteristics

  • Provides confidentiality and integrity for UDP datagrams.
  • Handles packet loss and reordering during handshake.
  • Message boundaries are preserved (each receive is one datagram).
  • Suitable for real-time applications requiring encryption.

Definition at line 49 of file dtls_socket.h.

Member Enumeration Documentation

◆ handshake_type

Handshake type enumeration.

Enumerator
client 

Client-side handshake

server 

Server-side handshake

Definition at line 55 of file dtls_socket.h.

Constructor & Destructor Documentation

◆ ~dtls_socket()

kcenon::network::internal::dtls_socket::~dtls_socket ( )

Destructor. Cleans up OpenSSL resources.

Definition at line 89 of file dtls_socket.cpp.

90{
92
93 if (ssl_)
94 {
95 SSL_shutdown(ssl_);
96 SSL_free(ssl_); // Also frees the BIOs
97 }
98}
auto stop_receive() -> void
Stops the receive loop.

References ssl_, and stop_receive().

Here is the call graph for this function:

◆ dtls_socket() [1/3]

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

Referenced by create().

Here is the caller graph for this function:

◆ dtls_socket() [2/3]

kcenon::network::internal::dtls_socket::dtls_socket ( dtls_socket && )
delete

◆ dtls_socket() [3/3]

kcenon::network::internal::dtls_socket::dtls_socket ( asio::ip::udp::socket socket,
SSL * ssl,
BIO * rbio,
BIO * wbio )
private

Definition at line 80 of file dtls_socket.cpp.

81 : socket_(std::move(socket))
82 , ssl_ctx_(nullptr)
83 , ssl_(ssl)
84 , rbio_(rbio)
85 , wbio_(wbio)
86{
87}
auto socket() -> asio::ip::udp::socket &
Provides direct access to the underlying UDP socket.

Member Function Documentation

◆ async_handshake()

auto kcenon::network::internal::dtls_socket::async_handshake ( handshake_type type,
std::function< void(std::error_code)> handler ) -> void

Performs asynchronous DTLS handshake.

Parameters
typeHandshake type (client or server)
handlerCompletion handler with signature void(std::error_code)

Must be called before start_receive() or async_send(). The handshake involves multiple round-trips over UDP.

Definition at line 100 of file dtls_socket.cpp.

103{
104 handshake_type_ = type;
105 handshake_callback_ = std::move(handler);
106 handshake_in_progress_.store(true);
107
108 {
109 std::lock_guard<std::mutex> lock(ssl_mutex_);
110
111 if (type == handshake_type::client)
112 {
113 SSL_set_connect_state(ssl_);
114 }
115 else
116 {
117 SSL_set_accept_state(ssl_);
118 }
119 }
120
121 // Start receiving for handshake packets
123
124 // Initiate handshake
126}
std::atomic< bool > handshake_in_progress_
std::function< void(std::error_code)> handshake_callback_
auto start_receive() -> void
Begins the continuous asynchronous receive loop.
auto continue_handshake() -> void
Continues the handshake process.

◆ async_send()

auto kcenon::network::internal::dtls_socket::async_send ( std::vector< uint8_t > && data,
std::function< void(std::error_code, std::size_t)> handler ) -> void

Initiates an asynchronous encrypted send.

Parameters
dataThe plaintext data to encrypt and send (moved for efficiency).
handlerA completion handler with signature void(std::error_code, std::size_t) invoked upon completion.

The data is encrypted using DTLS before transmission.

Note
Data is moved (not copied) to avoid memory allocation overhead.

Definition at line 396 of file dtls_socket.cpp.

399{
400 asio::ip::udp::endpoint target;
401 {
402 std::lock_guard<std::mutex> lock(endpoint_mutex_);
403 target = peer_endpoint_;
404 }
405
406 async_send_to(std::move(data), target, std::move(handler));
407}
asio::ip::udp::endpoint peer_endpoint_
auto async_send_to(std::vector< uint8_t > &&data, const asio::ip::udp::endpoint &endpoint, std::function< void(std::error_code, std::size_t)> handler) -> void
Initiates an asynchronous encrypted send to a specific endpoint.

◆ async_send_to()

auto kcenon::network::internal::dtls_socket::async_send_to ( std::vector< uint8_t > && data,
const asio::ip::udp::endpoint & endpoint,
std::function< void(std::error_code, std::size_t)> handler ) -> void

Initiates an asynchronous encrypted send to a specific endpoint.

Parameters
dataThe plaintext data to encrypt and send (moved for efficiency).
endpointThe target endpoint.
handlerA completion handler invoked upon completion.

Useful for server responding to different clients.

Definition at line 409 of file dtls_socket.cpp.

413{
414 if (!handshake_complete_.load())
415 {
416 if (handler)
417 {
418 handler(std::make_error_code(std::errc::not_connected), 0);
419 }
420 return;
421 }
422
423 // Encrypt the data
424 int written;
425 {
426 std::lock_guard<std::mutex> lock(ssl_mutex_);
427 written = SSL_write(ssl_, data.data(), static_cast<int>(data.size()));
428 }
429
430 if (written <= 0)
431 {
432 if (handler)
433 {
434 handler(make_ssl_error(), 0);
435 }
436 return;
437 }
438
439 // Get encrypted data from write BIO
440 std::vector<uint8_t> encrypted;
441 {
442 std::lock_guard<std::mutex> lock(ssl_mutex_);
443 int pending = BIO_ctrl_pending(wbio_);
444 if (pending <= 0)
445 {
446 if (handler)
447 {
448 handler(std::make_error_code(std::errc::io_error), 0);
449 }
450 return;
451 }
452
453 encrypted.resize(static_cast<std::size_t>(pending));
454 int read_len = BIO_read(wbio_, encrypted.data(), pending);
455 if (read_len <= 0)
456 {
457 if (handler)
458 {
459 handler(std::make_error_code(std::errc::io_error), 0);
460 }
461 return;
462 }
463 encrypted.resize(static_cast<std::size_t>(read_len));
464 }
465
466 // Send encrypted data
467 auto self = shared_from_this();
468 auto buffer = std::make_shared<std::vector<uint8_t>>(std::move(encrypted));
469 auto original_size = data.size();
470
471 socket_.async_send_to(
472 asio::buffer(*buffer),
473 endpoint,
474 [handler = std::move(handler), buffer, original_size](
475 std::error_code ec, std::size_t /*bytes_sent*/)
476 {
477 if (handler)
478 {
479 // Report original (plaintext) size to the handler
480 handler(ec, ec ? 0 : original_size);
481 }
482 });
483}
auto make_ssl_error() const -> std::error_code
Creates an OpenSSL error code from the current error state.

◆ continue_handshake()

auto kcenon::network::internal::dtls_socket::continue_handshake ( ) -> void
private

Continues the handshake process.

Definition at line 128 of file dtls_socket.cpp.

129{
130 if (!handshake_in_progress_.load())
131 {
132 return;
133 }
134
135 int result;
136 {
137 std::lock_guard<std::mutex> lock(ssl_mutex_);
138 result = SSL_do_handshake(ssl_);
139 }
140
141 if (result == 1)
142 {
143 // Handshake complete
144 handshake_in_progress_.store(false);
145 handshake_complete_.store(true);
146
147 // Flush any remaining output
149
150 std::function<void(std::error_code)> callback;
151 {
152 std::lock_guard<std::mutex> lock(callback_mutex_);
153 callback = std::move(handshake_callback_);
154 }
155
156 if (callback)
157 {
158 callback(std::error_code{});
159 }
160 return;
161 }
162
163 int ssl_error;
164 {
165 std::lock_guard<std::mutex> lock(ssl_mutex_);
166 ssl_error = SSL_get_error(ssl_, result);
167 }
168
169 // Flush any output generated by the handshake
171
172 if (ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_WRITE)
173 {
174 // Need more data - continue receiving
175 return;
176 }
177
178 // Handshake failed
179 handshake_in_progress_.store(false);
180
181 std::function<void(std::error_code)> callback;
182 {
183 std::lock_guard<std::mutex> lock(callback_mutex_);
184 callback = std::move(handshake_callback_);
185 }
186
187 if (callback)
188 {
189 callback(make_ssl_error());
190 }
191}
auto flush_bio_output() -> void
Flushes pending DTLS output to the network.

◆ create()

Result< std::shared_ptr< dtls_socket > > kcenon::network::internal::dtls_socket::create ( asio::ip::udp::socket socket,
SSL_CTX * ssl_ctx )
staticnodiscard

Constructs a dtls_socket with an existing UDP socket.

Parameters
socketAn asio::ip::udp::socket that must be open.
ssl_ctxThe OpenSSL SSL_CTX configured for DTLS.

The socket should be connected (for client) or bound (for server) before calling handshake methods.

Definition at line 42 of file dtls_socket.cpp.

44{
45 // Create SSL object
46 SSL* ssl = SSL_new(ssl_ctx);
47 if (!ssl)
48 {
51 "Failed to create SSL object",
52 "dtls_socket::create");
53 }
54
55 // Create memory BIOs for non-blocking I/O
56 BIO* rbio = BIO_new(BIO_s_mem());
57 BIO* wbio = BIO_new(BIO_s_mem());
58 if (!rbio || !wbio)
59 {
60 if (rbio) BIO_free(rbio);
61 if (wbio) BIO_free(wbio);
62 SSL_free(ssl);
65 "Failed to create BIO objects",
66 "dtls_socket::create");
67 }
68
69 // Set BIOs to non-blocking mode
70 BIO_set_nbio(rbio, 1);
71 BIO_set_nbio(wbio, 1);
72
73 // Connect BIOs to SSL object (SSL takes ownership of BIOs)
74 SSL_set_bio(ssl, rbio, wbio);
75
76 return ok(std::shared_ptr<dtls_socket>(
77 new dtls_socket(std::move(socket), ssl, rbio, wbio)));
78}
dtls_socket(const dtls_socket &)=delete
struct ssl_st SSL
Definition crypto.h:21
@ error
Black hole detected, reset to base.
VoidResult ok()

References dtls_socket(), kcenon::network::protocols::quic::error, kcenon::network::error_codes::common_errors::internal_error, kcenon::network::ok(), and socket().

Referenced by kcenon::network::core::secure_messaging_udp_server::create_session(), and kcenon::network::core::secure_messaging_udp_client::do_start_impl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ deliver_encrypted()

auto kcenon::network::internal::dtls_socket::deliver_encrypted ( const std::vector< uint8_t > & data,
const asio::ip::udp::endpoint & sender ) -> void

Injects an already-received encrypted datagram for DTLS processing.

Intended for a server that owns the underlying UDP socket and demultiplexes datagrams to per-client sessions itself, instead of letting each dtls_socket drive its own receive loop via start_receive(). The bytes are fed through the read BIO exactly as the internal receive loop would: an in-progress handshake is advanced, and once the handshake is complete the record is decrypted and the application payload is delivered to the receive callback.

Safe to call with malformed, truncated, or pre-handshake records: such data is processed best-effort and dropped without invoking the receive callback when it does not yield a complete decrypted record.

Parameters
dataThe encrypted datagram bytes received from the peer.
senderThe endpoint the datagram was received from.

Definition at line 269 of file dtls_socket.cpp.

271{
272 if (data.empty())
273 {
274 return;
275 }
276
277 // Reuse the same record-processing path the internal receive loop uses.
278 // SSL/BIO access inside process_received_data() is serialized by
279 // ssl_mutex_, so injecting from a server's demultiplexing thread is safe.
280 process_received_data(data, sender);
281}
auto process_received_data(const std::vector< uint8_t > &data, const asio::ip::udp::endpoint &sender) -> void
Processes received encrypted data through DTLS.

◆ do_receive()

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

Internal function to handle the receive logic.

Definition at line 222 of file dtls_socket.cpp.

223{
224 if (!is_receiving_.load())
225 {
226 return;
227 }
228
229 auto self = shared_from_this();
230 socket_.async_receive_from(
231 asio::buffer(read_buffer_),
233 [this, self](std::error_code ec, std::size_t length)
234 {
235 if (!is_receiving_.load())
236 {
237 return;
238 }
239
240 if (ec)
241 {
242 std::function<void(std::error_code)> callback;
243 {
244 std::lock_guard<std::mutex> lock(callback_mutex_);
245 callback = error_callback_;
246 }
247 if (callback)
248 {
249 callback(ec);
250 }
251 return;
252 }
253
254 if (length > 0)
255 {
256 std::vector<uint8_t> data(read_buffer_.begin(),
257 read_buffer_.begin() + length);
259 }
260
261 // Continue receiving
262 if (is_receiving_.load())
263 {
264 do_receive();
265 }
266 });
267}
std::array< uint8_t, 65536 > read_buffer_
asio::ip::udp::endpoint sender_endpoint_
std::function< void(std::error_code)> error_callback_
auto do_receive() -> void
Internal function to handle the receive logic.

◆ flush_bio_output()

auto kcenon::network::internal::dtls_socket::flush_bio_output ( ) -> void
private

Flushes pending DTLS output to the network.

Definition at line 355 of file dtls_socket.cpp.

356{
357 // Check if there's data to send in the write BIO
358 std::vector<uint8_t> output;
359 {
360 std::lock_guard<std::mutex> lock(ssl_mutex_);
361 int pending = BIO_ctrl_pending(wbio_);
362 if (pending <= 0)
363 {
364 return;
365 }
366
367 output.resize(static_cast<std::size_t>(pending));
368 int read_len = BIO_read(wbio_, output.data(), pending);
369 if (read_len <= 0)
370 {
371 return;
372 }
373 output.resize(static_cast<std::size_t>(read_len));
374 }
375
376 // Send the encrypted data
377 asio::ip::udp::endpoint target;
378 {
379 std::lock_guard<std::mutex> lock(endpoint_mutex_);
380 target = peer_endpoint_;
381 }
382
383 if (target.port() != 0)
384 {
385 auto buffer = std::make_shared<std::vector<uint8_t>>(std::move(output));
386 socket_.async_send_to(
387 asio::buffer(*buffer),
388 target,
389 [buffer](std::error_code /*ec*/, std::size_t /*bytes*/)
390 {
391 // Fire and forget for handshake messages
392 });
393 }
394}

◆ is_handshake_complete()

auto kcenon::network::internal::dtls_socket::is_handshake_complete ( ) const -> bool
inline

Checks if the DTLS handshake is complete.

Returns
true if handshake completed successfully.

Definition at line 200 of file dtls_socket.h.

201 {
202 return handshake_complete_.load();
203 }

References handshake_complete_.

◆ make_ssl_error()

auto kcenon::network::internal::dtls_socket::make_ssl_error ( ) const -> std::error_code
private

Creates an OpenSSL error code from the current error state.

Returns
std::error_code representing the SSL error.

Definition at line 497 of file dtls_socket.cpp.

498{
499 unsigned long err = ERR_get_error();
500 if (err == 0)
501 {
502 return std::make_error_code(std::errc::io_error);
503 }
504 return make_ssl_error_code(static_cast<int>(err));
505}

◆ operator=() [1/2]

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

◆ operator=() [2/2]

dtls_socket & kcenon::network::internal::dtls_socket::operator= ( dtls_socket && )
delete

◆ peer_endpoint()

auto kcenon::network::internal::dtls_socket::peer_endpoint ( ) const -> asio::ip::udp::endpoint

Returns the peer endpoint.

Returns
The configured peer endpoint.

Definition at line 491 of file dtls_socket.cpp.

492{
493 std::lock_guard<std::mutex> lock(const_cast<std::mutex&>(endpoint_mutex_));
494 return peer_endpoint_;
495}

References endpoint_mutex_, and peer_endpoint_.

◆ process_received_data()

auto kcenon::network::internal::dtls_socket::process_received_data ( const std::vector< uint8_t > & data,
const asio::ip::udp::endpoint & sender ) -> void
private

Processes received encrypted data through DTLS.

Parameters
dataThe encrypted datagram.
senderThe sender's endpoint.

Definition at line 283 of file dtls_socket.cpp.

285{
286 // Write received data to the read BIO
287 {
288 std::lock_guard<std::mutex> lock(ssl_mutex_);
289 int written = BIO_write(rbio_, data.data(), static_cast<int>(data.size()));
290 if (written <= 0)
291 {
292 // BIO write failed
293 return;
294 }
295 }
296
297 // If handshake is in progress, continue it
298 if (handshake_in_progress_.load())
299 {
301 return;
302 }
303
304 // Handshake complete, try to read decrypted data
305 if (handshake_complete_.load())
306 {
307 std::vector<uint8_t> decrypted;
308 decrypted.resize(65536);
309
310 int read_len;
311 {
312 std::lock_guard<std::mutex> lock(ssl_mutex_);
313 read_len = SSL_read(ssl_, decrypted.data(), static_cast<int>(decrypted.size()));
314 }
315
316 if (read_len > 0)
317 {
318 decrypted.resize(static_cast<std::size_t>(read_len));
319
320 std::function<void(const std::vector<uint8_t>&, const asio::ip::udp::endpoint&)> callback;
321 {
322 std::lock_guard<std::mutex> lock(callback_mutex_);
323 callback = receive_callback_;
324 }
325 if (callback)
326 {
327 callback(decrypted, sender);
328 }
329 }
330 else
331 {
332 int ssl_error;
333 {
334 std::lock_guard<std::mutex> lock(ssl_mutex_);
335 ssl_error = SSL_get_error(ssl_, read_len);
336 }
337
338 if (ssl_error != SSL_ERROR_WANT_READ && ssl_error != SSL_ERROR_WANT_WRITE)
339 {
340 // Real error
341 std::function<void(std::error_code)> callback;
342 {
343 std::lock_guard<std::mutex> lock(callback_mutex_);
344 callback = error_callback_;
345 }
346 if (callback)
347 {
348 callback(make_ssl_error());
349 }
350 }
351 }
352 }
353}
std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> receive_callback_

◆ set_error_callback()

auto kcenon::network::internal::dtls_socket::set_error_callback ( std::function< void(std::error_code)> callback) -> void

Sets a callback to handle socket errors.

Parameters
callbackA function with signature void(std::error_code), invoked when any asynchronous operation fails.

If no callback is set, errors are not explicitly handled here.

Definition at line 201 of file dtls_socket.cpp.

203{
204 std::lock_guard<std::mutex> lock(callback_mutex_);
205 error_callback_ = std::move(callback);
206}

◆ set_peer_endpoint()

auto kcenon::network::internal::dtls_socket::set_peer_endpoint ( const asio::ip::udp::endpoint & endpoint) -> void

Sets the peer endpoint for connected mode.

Parameters
endpointThe peer's UDP endpoint.

Definition at line 485 of file dtls_socket.cpp.

486{
487 std::lock_guard<std::mutex> lock(endpoint_mutex_);
488 peer_endpoint_ = endpoint;
489}

◆ set_receive_callback()

auto kcenon::network::internal::dtls_socket::set_receive_callback ( std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> callback) -> void

Sets a callback to receive decrypted inbound datagrams.

Parameters
callbackA function with signature void(const std::vector<uint8_t>&, const asio::ip::udp::endpoint&), called whenever a datagram is successfully received and decrypted.

If no callback is set, received data is effectively discarded.

Definition at line 193 of file dtls_socket.cpp.

196{
197 std::lock_guard<std::mutex> lock(callback_mutex_);
198 receive_callback_ = std::move(callback);
199}

◆ socket()

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

Provides direct access to the underlying UDP socket.

Returns
A reference to the wrapped asio::ip::udp::socket.

Definition at line 194 of file dtls_socket.h.

194{ return socket_; }

References socket_.

Referenced by create().

Here is the caller graph for this function:

◆ start_receive()

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

Begins the continuous asynchronous receive loop.

Once called, the class repeatedly receives encrypted datagrams, decrypts them, and invokes the receive callback. If an error occurs, the error callback is triggered.

Definition at line 208 of file dtls_socket.cpp.

209{
210 bool expected = false;
211 if (is_receiving_.compare_exchange_strong(expected, true))
212 {
213 do_receive();
214 }
215}

◆ stop_receive()

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

Stops the receive loop.

Definition at line 217 of file dtls_socket.cpp.

218{
219 is_receiving_.store(false);
220}

Referenced by ~dtls_socket().

Here is the caller graph for this function:

Member Data Documentation

◆ callback_mutex_

std::mutex kcenon::network::internal::dtls_socket::callback_mutex_
private

Protects callback registration.

Definition at line 250 of file dtls_socket.h.

◆ endpoint_mutex_

std::mutex kcenon::network::internal::dtls_socket::endpoint_mutex_
private

Protects endpoint access.

Definition at line 251 of file dtls_socket.h.

Referenced by peer_endpoint().

◆ error_callback_

std::function<void(std::error_code)> kcenon::network::internal::dtls_socket::error_callback_
private

Error callback.

Definition at line 256 of file dtls_socket.h.

◆ handshake_callback_

std::function<void(std::error_code)> kcenon::network::internal::dtls_socket::handshake_callback_
private

Handshake completion callback.

Definition at line 258 of file dtls_socket.h.

◆ handshake_complete_

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

Handshake completed flag.

Definition at line 261 of file dtls_socket.h.

261{false};

Referenced by is_handshake_complete().

◆ handshake_in_progress_

std::atomic<bool> kcenon::network::internal::dtls_socket::handshake_in_progress_ {false}
private

Handshake in progress flag.

Definition at line 262 of file dtls_socket.h.

262{false};

◆ handshake_type_

handshake_type kcenon::network::internal::dtls_socket::handshake_type_ {handshake_type::client}
private

Handshake mode.

Definition at line 263 of file dtls_socket.h.

◆ is_receiving_

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

Receive loop active flag.

Definition at line 260 of file dtls_socket.h.

260{false};

◆ peer_endpoint_

asio::ip::udp::endpoint kcenon::network::internal::dtls_socket::peer_endpoint_
private

Peer endpoint for connected mode.

Definition at line 239 of file dtls_socket.h.

Referenced by peer_endpoint().

◆ rbio_

BIO* kcenon::network::internal::dtls_socket::rbio_
private

Read BIO (memory).

Definition at line 244 of file dtls_socket.h.

◆ read_buffer_

std::array<uint8_t, 65536> kcenon::network::internal::dtls_socket::read_buffer_
private

Buffer for receiving datagrams.

Definition at line 247 of file dtls_socket.h.

◆ receive_callback_

std::function<void(const std::vector<uint8_t>&, const asio::ip::udp::endpoint&)> kcenon::network::internal::dtls_socket::receive_callback_
private

Inbound data callback.

Definition at line 254 of file dtls_socket.h.

◆ sender_endpoint_

asio::ip::udp::endpoint kcenon::network::internal::dtls_socket::sender_endpoint_
private

Sender endpoint for receives.

Definition at line 240 of file dtls_socket.h.

◆ socket_

asio::ip::udp::socket kcenon::network::internal::dtls_socket::socket_
private

The underlying UDP socket.

Definition at line 238 of file dtls_socket.h.

Referenced by socket().

◆ ssl_

SSL* kcenon::network::internal::dtls_socket::ssl_
private

OpenSSL SSL object.

Definition at line 243 of file dtls_socket.h.

Referenced by ~dtls_socket().

◆ ssl_ctx_

SSL_CTX* kcenon::network::internal::dtls_socket::ssl_ctx_
private

OpenSSL context (not owned).

Definition at line 242 of file dtls_socket.h.

◆ ssl_mutex_

std::mutex kcenon::network::internal::dtls_socket::ssl_mutex_
private

Protects SSL operations.

Definition at line 249 of file dtls_socket.h.

◆ wbio_

BIO* kcenon::network::internal::dtls_socket::wbio_
private

Write BIO (memory).

Definition at line 245 of file dtls_socket.h.


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