Nexus HTTP/3
A QUIC and HTTP/3 library
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
connection_impl.hpp
1 #pragma once
2 
3 #include <boost/intrusive/list.hpp>
4 #include <nexus/quic/detail/connection_state.hpp>
5 #include <nexus/quic/detail/service.hpp>
6 #include <nexus/quic/detail/stream_impl.hpp>
7 #include <nexus/udp.hpp>
8 
9 struct lsquic_conn;
10 struct lsquic_stream;
11 
12 namespace nexus::quic::detail {
13 
14 struct accept_operation;
15 struct socket_impl;
16 
17 struct connection_impl : public connection_context,
18  public boost::intrusive::list_base_hook<>,
19  public service_list_base_hook {
20  service<connection_impl>& svc;
21  socket_impl& socket;
22  connection_state::variant state;
23 
24  explicit connection_impl(socket_impl& socket);
25  ~connection_impl();
26 
27  void service_shutdown();
28 
29  using executor_type = boost::asio::any_io_executor;
30  executor_type get_executor() const;
31 
32  connection_id id(error_code& ec) const;
33  udp::endpoint remote_endpoint(error_code& ec) const;
34 
35  void connect(stream_connect_operation& op);
36  stream_impl* on_connect(lsquic_stream* stream);
37 
38  template <typename Stream, typename CompletionToken>
39  decltype(auto) async_connect(Stream& stream, CompletionToken&& token) {
40  auto& s = stream.impl;
41  return boost::asio::async_initiate<CompletionToken, void(error_code)>(
42  [this, &s] (auto h) {
43  using Handler = std::decay_t<decltype(h)>;
44  using op_type = stream_connect_async<Handler, executor_type>;
45  auto p = handler_allocate<op_type>(h, std::move(h), get_executor(), s);
46  auto op = handler_ptr<op_type, Handler>{p, &p->handler};
47  connect(*op);
48  op.release(); // release ownership
49  }, token);
50  }
51 
52  void accept(stream_accept_operation& op);
53  stream_impl* on_accept(lsquic_stream* stream);
54 
55  template <typename Stream, typename CompletionToken>
56  decltype(auto) async_accept(Stream& stream, CompletionToken&& token) {
57  auto& s = stream.impl;
58  return boost::asio::async_initiate<CompletionToken, void(error_code)>(
59  [this, &s] (auto h) {
60  using Handler = std::decay_t<decltype(h)>;
61  using op_type = stream_accept_async<Handler, executor_type>;
62  auto p = handler_allocate<op_type>(h, std::move(h), get_executor(), s);
63  auto op = handler_ptr<op_type, Handler>{p, &p->handler};
64  accept(*op);
65  op.release(); // release ownership
66  }, token);
67  }
68 
69  bool is_open() const;
70 
71  void go_away(error_code& ec);
72  void close(error_code& ec);
73 
74  void on_close();
75  void on_handshake(int status);
76  void on_remote_goaway();
77  void on_remote_close(int app_error, uint64_t code);
78 
79  void on_incoming_stream_closed(stream_impl& s);
80  void on_accepting_stream_closed(stream_impl& s);
81  void on_connecting_stream_closed(stream_impl& s);
82  void on_open_stream_closing(stream_impl& s);
83  void on_open_stream_closed(stream_impl& s);
84  void on_closing_stream_closed(stream_impl& s);
85 };
86 
87 } // namespace nexus::quic::detail