Nexus HTTP/3
A QUIC and HTTP/3 library
connection_state.hpp
1 #pragma once
2 
3 #include <variant>
4 #include <boost/circular_buffer.hpp>
5 #include <boost/intrusive/list.hpp>
6 #include <nexus/quic/connection_id.hpp>
7 #include <nexus/quic/detail/stream_impl.hpp>
8 #include <nexus/udp.hpp>
9 
10 struct lsquic_conn;
11 
12 namespace nexus::quic::detail {
13 
14 struct accept_operation;
15 struct stream_accept_operation;
16 struct stream_connect_operation;
17 
18 using stream_list = boost::intrusive::list<stream_impl>;
19 
20 inline void list_erase(stream_impl& s, stream_list& from)
21 {
22  from.erase(from.iterator_to(s));
23 }
24 
25 inline void list_transfer(stream_impl& s, stream_list& from, stream_list& to)
26 {
27  from.erase(from.iterator_to(s));
28  to.push_back(s);
29 }
30 
31 struct connection_context {
32  bool incoming;
33  explicit connection_context(bool incoming) noexcept : incoming(incoming) {}
34 };
35 
36 struct incoming_connection : connection_context {
37  lsquic_conn* handle;
38  boost::circular_buffer<lsquic_stream*> incoming_streams; // TODO: allocator
39 
40  incoming_connection(lsquic_conn* handle, uint32_t max_streams)
41  : connection_context(true),
42  handle(handle),
43  incoming_streams(max_streams) {}
44 };
45 
47 namespace connection_state {
48 
51 struct accepting {
52  accept_operation* op = nullptr;
53 };
54 
56 struct open {
57  lsquic_conn& handle;
58  boost::circular_buffer<lsquic_stream*> incoming_streams;
59  stream_list connecting_streams;
60  stream_list accepting_streams;
61  stream_list open_streams;
62  stream_list closing_streams;
63  // handshake errors are stored here until they can be delivered on close
64  error_code ec;
65 
66  explicit open(lsquic_conn& handle) noexcept : handle(handle) {}
67 };
68 
70 struct going_away {
71  lsquic_conn& handle;
72  stream_list open_streams;
73  stream_list closing_streams;
74  // handshake errors are stored here until they can be delivered on close
75  error_code ec;
76 
77  explicit going_away(lsquic_conn& handle) noexcept : handle(handle) {}
78 };
79 
82 struct error {
83  error_code ec;
84 };
85 
87 struct closed {
88 };
89 
90 using variant = std::variant<accepting, open, going_away, error, closed>;
91 
93 enum class transition {
94  none,
95  accepting_to_closed,
96  open_to_going_away,
97  open_to_closed,
98  open_to_error,
99  going_away_to_closed,
100  going_away_to_error,
101  error_to_closed,
102 };
103 
104 // connection accessors
105 bool is_open(const variant& state);
106 connection_id id(const variant& state, error_code& ec);
107 udp::endpoint remote_endpoint(const variant& state, error_code& ec);
108 
109 // connection events
110 void on_connect(variant& state, lsquic_conn* handle);
111 void on_handshake(variant& state, int status);
112 void accept(variant& state, accept_operation& op);
113 void accept_incoming(variant& state, incoming_connection&& incoming);
114 void on_accept(variant& state, lsquic_conn* handle);
115 
116 bool stream_connect(variant& state, stream_connect_operation& op);
117 stream_impl* on_stream_connect(variant& state, lsquic_stream* handle,
118  bool is_http);
119 
120 void stream_accept(variant& state, stream_accept_operation& op, bool is_http);
121 stream_impl* on_stream_accept(variant& state, lsquic_stream* handle,
122  bool is_http);
123 
124 transition goaway(variant& state, error_code& ec);
125 transition on_remote_goaway(variant& state);
126 transition reset(variant& state, error_code ec);
127 transition close(variant& state, error_code& ec);
128 transition on_close(variant& state);
129 transition on_remote_close(variant& state, error_code ec);
130 void destroy(variant& state);
131 
132 } // namespace connection_state
133 
134 } // namespace nexus::quic::detail
error
global error codes
Definition: error.hpp:11
@ going_away
sent GOAWAY to peer