Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e8ea834

Browse filesBrowse files
jasnelltargos
authored andcommitted
quic: add more QUIC implementation
* add TLSContext * quic: add stat collection utilities * add Packet * add NgTcp2CallbackScope/NgHttp3CallbackScope PR-URL: #47494 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent d3fadd8 commit e8ea834
Copy full SHA for e8ea834

File tree

Expand file treeCollapse file tree

11 files changed

+1484
-8
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

11 files changed

+1484
-8
lines changed
Open diff view settings
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,16 +341,20 @@
341341
'src/quic/cid.cc',
342342
'src/quic/data.cc',
343343
'src/quic/logstream.cc',
344+
'src/quic/packet.cc',
344345
'src/quic/preferredaddress.cc',
345346
'src/quic/sessionticket.cc',
347+
'src/quic/tlscontext.cc',
346348
'src/quic/tokens.cc',
347349
'src/quic/transportparams.cc',
348350
'src/quic/bindingdata.h',
349351
'src/quic/cid.h',
350352
'src/quic/data.h',
351353
'src/quic/logstream.h',
354+
'src/quic/packet.h',
352355
'src/quic/preferredaddress.h',
353356
'src/quic/sessionticket.h',
357+
'src/quic/tlscontext.h',
354358
'src/quic/tokens.h',
355359
'src/quic/transportparams.h',
356360
],
Collapse file

‎src/async_wrap.h‎

Copy file name to clipboardExpand all lines: src/async_wrap.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ namespace node {
6161
V(PROMISE) \
6262
V(QUERYWRAP) \
6363
V(QUIC_LOGSTREAM) \
64+
V(QUIC_PACKET) \
6465
V(SHUTDOWNWRAP) \
6566
V(SIGNALWRAP) \
6667
V(STATWATCHER) \
Collapse file

‎src/node_errors.h‎

Copy file name to clipboardExpand all lines: src/node_errors.h
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ void OOMErrorHandler(const char* location, const v8::OOMDetails& details);
6363
V(ERR_DLOPEN_FAILED, Error) \
6464
V(ERR_ENCODING_INVALID_ENCODED_DATA, TypeError) \
6565
V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, Error) \
66+
V(ERR_ILLEGAL_CONSTRUCTOR, Error) \
6667
V(ERR_INVALID_ADDRESS, Error) \
6768
V(ERR_INVALID_ARG_VALUE, TypeError) \
6869
V(ERR_OSSL_EVP_INVALID_DIGEST, Error) \
@@ -156,6 +157,7 @@ ERRORS_WITH_CODE(V)
156157
V(ERR_DLOPEN_FAILED, "DLOpen failed") \
157158
V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, \
158159
"Context not associated with Node.js environment") \
160+
V(ERR_ILLEGAL_CONSTRUCTOR, "Illegal constructor") \
159161
V(ERR_INVALID_ADDRESS, "Invalid socket address") \
160162
V(ERR_INVALID_MODULE, "No such module") \
161163
V(ERR_INVALID_STATE, "Invalid state") \
Collapse file

‎src/quic/bindingdata.cc‎

Copy file name to clipboardExpand all lines: src/quic/bindingdata.cc
+45-1Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,15 @@ void BindingData::DecreaseAllocatedSize(size_t size) {
5858

5959
void BindingData::Initialize(Environment* env, Local<Object> target) {
6060
SetMethod(env->context(), target, "setCallbacks", SetCallbacks);
61+
SetMethod(env->context(), target, "flushPacketFreelist", FlushPacketFreelist);
6162
Realm::GetCurrent(env->context())
6263
->AddBindingData<BindingData>(env->context(), target);
6364
}
6465

6566
void BindingData::RegisterExternalReferences(
6667
ExternalReferenceRegistry* registry) {
6768
registry->Register(SetCallbacks);
69+
registry->Register(FlushPacketFreelist);
6870
}
6971

7072
BindingData::BindingData(Realm* realm, Local<Object> object)
@@ -140,7 +142,7 @@ QUIC_JS_CALLBACKS(V)
140142
void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) {
141143
auto env = Environment::GetCurrent(args);
142144
auto isolate = env->isolate();
143-
BindingData& state = BindingData::Get(env);
145+
auto& state = BindingData::Get(env);
144146
CHECK(args[0]->IsObject());
145147
Local<Object> obj = args[0].As<Object>();
146148

@@ -159,6 +161,48 @@ void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) {
159161
#undef V
160162
}
161163

164+
void BindingData::FlushPacketFreelist(const FunctionCallbackInfo<Value>& args) {
165+
auto env = Environment::GetCurrent(args);
166+
auto& state = BindingData::Get(env);
167+
state.packet_freelist.clear();
168+
}
169+
170+
NgTcp2CallbackScope::NgTcp2CallbackScope(Environment* env) : env(env) {
171+
auto& binding = BindingData::Get(env);
172+
CHECK(!binding.in_ngtcp2_callback_scope);
173+
binding.in_ngtcp2_callback_scope = true;
174+
}
175+
176+
NgTcp2CallbackScope::~NgTcp2CallbackScope() {
177+
auto& binding = BindingData::Get(env);
178+
binding.in_ngtcp2_callback_scope = false;
179+
}
180+
181+
bool NgTcp2CallbackScope::in_ngtcp2_callback(Environment* env) {
182+
auto& binding = BindingData::Get(env);
183+
return binding.in_ngtcp2_callback_scope;
184+
}
185+
186+
NgHttp3CallbackScope::NgHttp3CallbackScope(Environment* env) : env(env) {
187+
auto& binding = BindingData::Get(env);
188+
CHECK(!binding.in_nghttp3_callback_scope);
189+
binding.in_nghttp3_callback_scope = true;
190+
}
191+
192+
NgHttp3CallbackScope::~NgHttp3CallbackScope() {
193+
auto& binding = BindingData::Get(env);
194+
binding.in_nghttp3_callback_scope = false;
195+
}
196+
197+
bool NgHttp3CallbackScope::in_nghttp3_callback(Environment* env) {
198+
auto& binding = BindingData::Get(env);
199+
return binding.in_nghttp3_callback_scope;
200+
}
201+
202+
void IllegalConstructor(const FunctionCallbackInfo<Value>& args) {
203+
THROW_ERR_ILLEGAL_CONSTRUCTOR(Environment::GetCurrent(args));
204+
}
205+
162206
} // namespace quic
163207
} // namespace node
164208

Collapse file

‎src/quic/bindingdata.h‎

Copy file name to clipboardExpand all lines: src/quic/bindingdata.h
+44-7Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
#include <node.h>
1313
#include <node_mem.h>
1414
#include <v8.h>
15+
#include <vector>
1516

1617
namespace node {
1718
namespace quic {
1819

1920
class Endpoint;
21+
class Packet;
2022

2123
enum class Side {
2224
CLIENT = NGTCP2_CRYPTO_SIDE_CLIENT,
@@ -64,23 +66,37 @@ constexpr size_t kDefaultMaxPacketLength = NGTCP2_MAX_UDP_PAYLOAD_SIZE;
6466
#define QUIC_STRINGS(V) \
6567
V(ack_delay_exponent, "ackDelayExponent") \
6668
V(active_connection_id_limit, "activeConnectionIDLimit") \
69+
V(alpn, "alpn") \
70+
V(ca, "ca") \
71+
V(certs, "certs") \
72+
V(crl, "crl") \
73+
V(ciphers, "ciphers") \
6774
V(disable_active_migration, "disableActiveMigration") \
75+
V(enable_tls_trace, "tlsTrace") \
6876
V(endpoint, "Endpoint") \
6977
V(endpoint_udp, "Endpoint::UDP") \
78+
V(groups, "groups") \
79+
V(hostname, "hostname") \
7080
V(http3_alpn, &NGHTTP3_ALPN_H3[1]) \
7181
V(initial_max_data, "initialMaxData") \
7282
V(initial_max_stream_data_bidi_local, "initialMaxStreamDataBidiLocal") \
7383
V(initial_max_stream_data_bidi_remote, "initialMaxStreamDataBidiRemote") \
7484
V(initial_max_stream_data_uni, "initialMaxStreamDataUni") \
7585
V(initial_max_streams_bidi, "initialMaxStreamsBidi") \
7686
V(initial_max_streams_uni, "initialMaxStreamsUni") \
87+
V(keylog, "keylog") \
88+
V(keys, "keys") \
7789
V(logstream, "LogStream") \
7890
V(max_ack_delay, "maxAckDelay") \
7991
V(max_datagram_frame_size, "maxDatagramFrameSize") \
8092
V(max_idle_timeout, "maxIdleTimeout") \
8193
V(packetwrap, "PacketWrap") \
94+
V(reject_unauthorized, "rejectUnauthorized") \
95+
V(request_peer_certificate, "requestPeerCertificate") \
8296
V(session, "Session") \
83-
V(stream, "Stream")
97+
V(session_id_ctx, "sessionIDContext") \
98+
V(stream, "Stream") \
99+
V(verify_hostname_identity, "verifyHostnameIdentity")
84100

85101
// =============================================================================
86102
// The BindingState object holds state for the internalBinding('quic') binding
@@ -115,12 +131,14 @@ class BindingData final
115131
// bridge out to the JS API.
116132
static void SetCallbacks(const v8::FunctionCallbackInfo<v8::Value>& args);
117133

118-
// TODO(@jasnell) This will be added when Endpoint is implemented.
119-
// // A set of listening Endpoints. We maintain this to ensure that the
120-
// Endpoint
121-
// // cannot be gc'd while it is still listening and there are active
122-
// // connections.
123-
// std::unordered_map<Endpoint*, BaseObjectPtr<Endpoint>> listening_endpoints;
134+
std::vector<BaseObjectPtr<BaseObject>> packet_freelist;
135+
136+
// Purge the packet free list to free up memory.
137+
static void FlushPacketFreelist(
138+
const v8::FunctionCallbackInfo<v8::Value>& args);
139+
140+
bool in_ngtcp2_callback_scope = false;
141+
bool in_nghttp3_callback_scope = false;
124142

125143
// The following set up various storage and accessors for common strings,
126144
// construction templates, and callbacks stored on the BindingData. These
@@ -166,6 +184,25 @@ class BindingData final
166184
#undef V
167185
};
168186

187+
void IllegalConstructor(const v8::FunctionCallbackInfo<v8::Value>& args);
188+
189+
// The ngtcp2 and nghttp3 callbacks have certain restrictions
190+
// that forbid re-entry. We provide the following scopes for
191+
// use in those to help protect against it.
192+
struct NgTcp2CallbackScope {
193+
Environment* env;
194+
explicit NgTcp2CallbackScope(Environment* env);
195+
~NgTcp2CallbackScope();
196+
static bool in_ngtcp2_callback(Environment* env);
197+
};
198+
199+
struct NgHttp3CallbackScope {
200+
Environment* env;
201+
explicit NgHttp3CallbackScope(Environment* env);
202+
~NgHttp3CallbackScope();
203+
static bool in_nghttp3_callback(Environment* env);
204+
};
205+
169206
} // namespace quic
170207
} // namespace node
171208

Collapse file

‎src/quic/defs.h‎

Copy file name to clipboardExpand all lines: src/quic/defs.h
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
#pragma once
22

3+
#include <aliased_struct.h>
34
#include <env.h>
45
#include <node_errors.h>
6+
#include <uv.h>
57
#include <v8.h>
68

79
namespace node {
810
namespace quic {
911

12+
template <typename Opt, std::string Opt::*member>
13+
bool SetOption(Environment* env,
14+
Opt* options,
15+
const v8::Local<v8::Object>& object,
16+
const v8::Local<v8::String>& name) {
17+
v8::Local<v8::Value> value;
18+
if (!object->Get(env->context(), name).ToLocal(&value)) return false;
19+
if (!value->IsUndefined()) {
20+
Utf8Value utf8(env->isolate(), value);
21+
options->*member = *utf8;
22+
}
23+
return true;
24+
}
25+
1026
template <typename Opt, bool Opt::*member>
1127
bool SetOption(Environment* env,
1228
Opt* options,
@@ -50,5 +66,37 @@ bool SetOption(Environment* env,
5066
return true;
5167
}
5268

69+
// Utilities used to update the stats for Endpoint, Session, and Stream
70+
// objects. The stats themselves are maintained in an AliasedStruct within
71+
// each of the relevant classes.
72+
73+
template <typename Stats, uint64_t Stats::*member>
74+
void IncrementStat(Stats* stats, uint64_t amt = 1) {
75+
stats->*member += amt;
76+
}
77+
78+
template <typename Stats, uint64_t Stats::*member>
79+
void RecordTimestampStat(Stats* stats) {
80+
stats->*member = uv_hrtime();
81+
}
82+
83+
template <typename Stats, uint64_t Stats::*member>
84+
void SetStat(Stats* stats, uint64_t val) {
85+
stats->*member = val;
86+
}
87+
88+
template <typename Stats, uint64_t Stats::*member>
89+
uint64_t GetStat(Stats* stats) {
90+
return stats->*member;
91+
}
92+
93+
#define STAT_INCREMENT(Type, name) IncrementStat<Type, &Type::name>(&stats_);
94+
#define STAT_INCREMENT_N(Type, name, amt) \
95+
IncrementStat<Type, &Type::name>(&stats_, amt);
96+
#define STAT_RECORD_TIMESTAMP(Type, name) \
97+
RecordTimestampStat<Type, &Type::name>(&stats_);
98+
#define STAT_SET(Type, name, val) SetStat<Type, &Type::name>(&stats_, val);
99+
#define STAT_GET(Type, name) GetStat<Type, &Type::name>(&stats_);
100+
53101
} // namespace quic
54102
} // namespace node

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.