• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
4 #if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
5 
6 #include <env.h>
7 #include <ngtcp2/ngtcp2.h>
8 #include <node_sockaddr.h>
9 #include <optional>
10 #include "bindingdata.h"
11 #include "cid.h"
12 #include "data.h"
13 #include "tokens.h"
14 
15 namespace node {
16 namespace quic {
17 
18 class Endpoint;
19 class Session;
20 
21 // The Transport Params are the set of configuration options that are sent to
22 // the remote peer. They communicate the protocol options the other peer
23 // should use when communicating with this session.
24 class TransportParams final {
25  public:
26   enum class Type {
27     CLIENT_HELLO = NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
28     ENCRYPTED_EXTENSIONS = NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS,
29   };
30 
31   static constexpr uint64_t DEFAULT_MAX_STREAM_DATA_BIDI_LOCAL = 256 * 1024;
32   static constexpr uint64_t DEFAULT_MAX_STREAM_DATA_BIDI_REMOTE = 256 * 1024;
33   static constexpr uint64_t DEFAULT_MAX_STREAM_DATA_UNI = 256 * 1024;
34   static constexpr uint64_t DEFAULT_MAX_DATA = 1 * 1024 * 1024;
35   static constexpr uint64_t DEFAULT_MAX_IDLE_TIMEOUT = 10;  // seconds
36   static constexpr uint64_t DEFAULT_MAX_STREAMS_BIDI = 100;
37   static constexpr uint64_t DEFAULT_MAX_STREAMS_UNI = 3;
38   static constexpr uint64_t DEFAULT_ACTIVE_CONNECTION_ID_LIMIT = 2;
39 
40   struct Config {
41     Side side;
42     const CID& ocid;
43     const CID& retry_scid;
44     Config(Side side,
45            const CID& ocid = CID::kInvalid,
46            const CID& retry_scid = CID::kInvalid);
47   };
48 
49   struct Options {
50     // Set only on server Sessions, the preferred address communicates the IP
51     // address and port that the server would prefer the client to use when
52     // communicating with it. See the QUIC specification for more detail on how
53     // the preferred address mechanism works.
54     std::optional<SocketAddress> preferred_address_ipv4{};
55     std::optional<SocketAddress> preferred_address_ipv6{};
56 
57     // The initial size of the flow control window of locally initiated streams.
58     // This is the maximum number of bytes that the *remote* endpoint can send
59     // when the connection is started.
60     uint64_t initial_max_stream_data_bidi_local =
61         DEFAULT_MAX_STREAM_DATA_BIDI_LOCAL;
62 
63     // The initial size of the flow control window of remotely initiated
64     // streams. This is the maximum number of bytes that the remote endpoint can
65     // send when the connection is started.
66     uint64_t initial_max_stream_data_bidi_remote =
67         DEFAULT_MAX_STREAM_DATA_BIDI_REMOTE;
68 
69     // The initial size of the flow control window of remotely initiated
70     // unidirectional streams. This is the maximum number of bytes that the
71     // remote endpoint can send when the connection is started.
72     uint64_t initial_max_stream_data_uni = DEFAULT_MAX_STREAM_DATA_UNI;
73 
74     // The initial size of the session-level flow control window.
75     uint64_t initial_max_data = DEFAULT_MAX_DATA;
76 
77     // The initial maximum number of concurrent bidirectional streams the remote
78     // endpoint is permitted to open.
79     uint64_t initial_max_streams_bidi = DEFAULT_MAX_STREAMS_BIDI;
80 
81     // The initial maximum number of concurrent unidirectional streams the
82     // remote endpoint is permitted to open.
83     uint64_t initial_max_streams_uni = DEFAULT_MAX_STREAMS_UNI;
84 
85     // The maximum amount of time that a Session is permitted to remain idle
86     // before it is silently closed and state is discarded.
87     uint64_t max_idle_timeout = DEFAULT_MAX_IDLE_TIMEOUT;
88 
89     // The maximum number of Connection IDs that the peer can store. A single
90     // Session may have several connection IDs over it's lifetime.
91     uint64_t active_connection_id_limit = DEFAULT_ACTIVE_CONNECTION_ID_LIMIT;
92 
93     // Establishes the exponent used in ACK Delay field in the ACK frame. See
94     // the QUIC specification for details. This is an advanced option that
95     // should rarely be modified and only if there is really good reason.
96     uint64_t ack_delay_exponent = NGTCP2_DEFAULT_ACK_DELAY_EXPONENT;
97 
98     // The maximum amount of time by which the endpoint will delay sending
99     // acknowledgements. This is an advanced option that should rarely be
100     // modified and only if there is a really good reason. It is used to
101     // determine how long a Session will wait to determine that a packet has
102     // been lost.
103     uint64_t max_ack_delay = NGTCP2_DEFAULT_MAX_ACK_DELAY;
104 
105     // The maximum size of DATAGRAM frames that the endpoint will accept.
106     // Setting the value to 0 will disable DATAGRAM support.
107     uint64_t max_datagram_frame_size = kDefaultMaxPacketLength;
108 
109     // When true, communicates that the Session does not support active
110     // connection migration. See the QUIC specification for more details on
111     // connection migration.
112     bool disable_active_migration = false;
113 
114     static v8::Maybe<const Options> From(Environment* env,
115                                          v8::Local<v8::Value> value);
116   };
117 
118   explicit TransportParams(Type type);
119 
120   // Creates an instance of TransportParams wrapping the existing const
121   // ngtcp2_transport_params pointer.
122   TransportParams(Type type, const ngtcp2_transport_params* ptr);
123 
124   TransportParams(const Config& config, const Options& options);
125 
126   // Creates an instance of TransportParams by decoding the given buffer.
127   // If the parameters cannot be successfully decoded, the error()
128   // property will be set with an appropriate QuicError and the bool()
129   // operator will return false.
130   TransportParams(Type type, const ngtcp2_vec& buf);
131 
132   void GenerateStatelessResetToken(const TokenSecret& token_secret,
133                                    const CID& cid);
134   CID GeneratePreferredAddressToken(const Session& session);
135   void SetPreferredAddress(const SocketAddress& address);
136 
137   Type type() const;
138 
139   operator const ngtcp2_transport_params&() const;
140   operator const ngtcp2_transport_params*() const;
141 
142   operator bool() const;
143 
144   const QuicError& error() const;
145 
146   // Returns an ArrayBuffer containing the encoded transport parameters.
147   // If an error occurs during encoding, an empty shared_ptr will be returned
148   // and the error() property will be set to an appropriate QuicError.
149   Store Encode(Environment* env);
150 
151  private:
152   Type type_;
153   ngtcp2_transport_params params_{};
154   const ngtcp2_transport_params* ptr_;
155   QuicError error_ = QuicError::TRANSPORT_NO_ERROR;
156 };
157 
158 }  // namespace quic
159 }  // namespace node
160 
161 #endif  // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
162 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
163