3 #include <boost/intrusive/list.hpp>
4 #include <boost/circular_buffer.hpp>
5 #include <nexus/ssl.hpp>
6 #include <nexus/quic/detail/connection_impl.hpp>
9 struct lsquic_out_spec;
11 namespace nexus::quic::detail {
14 struct connection_impl;
16 union sockaddr_union {
17 sockaddr_storage storage;
23 using connection_list = boost::intrusive::list<connection_impl>;
25 inline void list_erase(connection_impl& s, connection_list& from)
27 from.erase(from.iterator_to(s));
30 inline void list_transfer(connection_impl& s, connection_list& from,
33 from.erase(from.iterator_to(s));
37 struct socket_impl : boost::intrusive::list_base_hook<> {
41 udp::endpoint local_addr;
42 boost::circular_buffer<incoming_connection> incoming_connections;
43 connection_list accepting_connections;
44 connection_list open_connections;
45 bool receiving =
false;
47 socket_impl(engine_impl& engine, udp::socket&& socket,
49 socket_impl(engine_impl& engine,
const udp::endpoint& endpoint,
50 bool is_server, ssl::context& ssl);
55 using executor_type = boost::asio::any_io_executor;
56 executor_type get_executor()
const;
58 udp::endpoint local_endpoint()
const {
return local_addr; }
60 void listen(
int backlog);
62 void connect(connection_impl& c,
63 const udp::endpoint& endpoint,
64 const char* hostname);
65 void on_connect(connection_impl& c, lsquic_conn* conn);
67 void accept(connection_impl& c, accept_operation& op);
68 connection_context* on_accept(lsquic_conn* conn);
70 template <
typename Connection,
typename CompletionToken>
71 decltype(
auto) async_accept(Connection& conn,
72 CompletionToken&& token) {
74 return boost::asio::async_initiate<CompletionToken, void(error_code)>(
76 using Handler = std::decay_t<decltype(h)>;
77 using op_type = accept_async<Handler, executor_type>;
78 auto p = handler_allocate<op_type>(h, std::move(h), get_executor());
79 auto op = handler_ptr<op_type, Handler>{p, &p->handler};
87 void abort_connections(error_code ec);
93 const lsquic_out_spec* send_packets(
const lsquic_out_spec* begin,
94 const lsquic_out_spec* end,
97 size_t recv_packet(iovec iov, udp::endpoint& peer, sockaddr_union&
self,
98 int& ecn, error_code& ec);