Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
dtls_socket.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
7#include <array>
8#include <atomic>
9#include <functional>
10#include <memory>
11#include <mutex>
12#include <system_error>
13#include <vector>
14
15#include <asio.hpp>
16
20
22{
49 class dtls_socket : public std::enable_shared_from_this<dtls_socket>
50 {
51 public:
55 enum class handshake_type
56 {
57 client,
58 server
59 };
60
69 [[nodiscard]] static Result<std::shared_ptr<dtls_socket>> create(
70 asio::ip::udp::socket socket, SSL_CTX* ssl_ctx);
71
76
77 // Non-copyable, non-movable
78 dtls_socket(const dtls_socket&) = delete;
82
91 auto async_handshake(
92 handshake_type type,
93 std::function<void(std::error_code)> handler) -> void;
94
104 std::function<void(const std::vector<uint8_t>&,
105 const asio::ip::udp::endpoint&)> callback) -> void;
106
114 auto set_error_callback(std::function<void(std::error_code)> callback)
115 -> void;
116
124 auto start_receive() -> void;
125
129 auto stop_receive() -> void;
130
149 auto deliver_encrypted(const std::vector<uint8_t>& data,
150 const asio::ip::udp::endpoint& sender) -> void;
151
161 auto async_send(
162 std::vector<uint8_t>&& data,
163 std::function<void(std::error_code, std::size_t)> handler) -> void;
164
173 auto async_send_to(
174 std::vector<uint8_t>&& data,
175 const asio::ip::udp::endpoint& endpoint,
176 std::function<void(std::error_code, std::size_t)> handler) -> void;
177
182 auto set_peer_endpoint(const asio::ip::udp::endpoint& endpoint) -> void;
183
188 auto peer_endpoint() const -> asio::ip::udp::endpoint;
189
194 auto socket() -> asio::ip::udp::socket& { return socket_; }
195
200 auto is_handshake_complete() const -> bool
201 {
202 return handshake_complete_.load();
203 }
204
205 private:
206 dtls_socket(asio::ip::udp::socket socket, SSL* ssl, BIO* rbio, BIO* wbio);
207
211 auto do_receive() -> void;
212
218 auto process_received_data(const std::vector<uint8_t>& data,
219 const asio::ip::udp::endpoint& sender) -> void;
220
224 auto flush_bio_output() -> void;
225
229 auto continue_handshake() -> void;
230
235 auto make_ssl_error() const -> std::error_code;
236
237 private:
238 asio::ip::udp::socket socket_;
239 asio::ip::udp::endpoint peer_endpoint_;
240 asio::ip::udp::endpoint sender_endpoint_;
244 BIO* rbio_;
245 BIO* wbio_;
247 std::array<uint8_t, 65536> read_buffer_;
253 std::function<void(const std::vector<uint8_t>&, const asio::ip::udp::endpoint&)>
255 std::function<void(std::error_code)>
257 std::function<void(std::error_code)>
260 std::atomic<bool> is_receiving_{false};
261 std::atomic<bool> handshake_complete_{false};
262 std::atomic<bool> handshake_in_progress_{false};
264 };
265
266} // namespace kcenon::network::internal
A wrapper around ASIO UDP socket with OpenSSL DTLS encryption.
Definition dtls_socket.h:50
std::atomic< bool > handshake_in_progress_
std::array< uint8_t, 65536 > read_buffer_
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 deliver_encrypted(const std::vector< uint8_t > &data, const asio::ip::udp::endpoint &sender) -> void
Injects an already-received encrypted datagram for DTLS processing.
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.
dtls_socket(const 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.
asio::ip::udp::endpoint peer_endpoint_
auto make_ssl_error() const -> std::error_code
Creates an OpenSSL error code from the current error state.
handshake_type
Handshake type enumeration.
Definition dtls_socket.h:56
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.
std::function< void(const std::vector< uint8_t > &, const asio::ip::udp::endpoint &)> receive_callback_
auto set_error_callback(std::function< void(std::error_code)> callback) -> void
Sets a callback to handle socket errors.
auto stop_receive() -> void
Stops the receive loop.
dtls_socket & operator=(const dtls_socket &)=delete
auto set_peer_endpoint(const asio::ip::udp::endpoint &endpoint) -> void
Sets the peer endpoint for connected mode.
auto is_handshake_complete() const -> bool
Checks if the DTLS handshake is complete.
std::function< void(std::error_code)> handshake_callback_
asio::ip::udp::endpoint sender_endpoint_
auto flush_bio_output() -> void
Flushes pending DTLS output to the network.
auto start_receive() -> void
Begins the continuous asynchronous receive loop.
auto process_received_data(const std::vector< uint8_t > &data, const asio::ip::udp::endpoint &sender) -> void
Processes received encrypted data through DTLS.
auto socket() -> asio::ip::udp::socket &
Provides direct access to the underlying UDP socket.
std::function< void(std::error_code)> error_callback_
auto peer_endpoint() const -> asio::ip::udp::endpoint
Returns the peer endpoint.
auto continue_handshake() -> void
Continues the handshake process.
auto do_receive() -> void
Internal function to handle the receive logic.
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.
dtls_socket(dtls_socket &&)=delete
~dtls_socket()
Destructor. Cleans up OpenSSL resources.
struct ssl_ctx_st SSL_CTX
Definition crypto.h:20
struct ssl_st SSL
Definition crypto.h:21
std::mutex mutex
OpenSSL utilities and version definitions.
Network-specific error and result type definitions.