Skip to content

Commit 5b32e21

Browse files
jasnellRafaelGSS
authored andcommitted
quic: add quic internalBinding, refine Endpoint, add types
PR-URL: #51112 Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent 82de660 commit 5b32e21

26 files changed

+996
-256
lines changed

node.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@
377377
'src/quic/tlscontext.h',
378378
'src/quic/tokens.h',
379379
'src/quic/transportparams.h',
380+
'src/quic/quic.cc',
380381
],
381382
'node_cctest_sources': [
382383
'src/node_snapshot_stub.cc',

src/node_binding.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@
8989
NODE_BUILTIN_STANDARD_BINDINGS(V) \
9090
NODE_BUILTIN_OPENSSL_BINDINGS(V) \
9191
NODE_BUILTIN_ICU_BINDINGS(V) \
92-
NODE_BUILTIN_PROFILER_BINDINGS(V)
92+
NODE_BUILTIN_PROFILER_BINDINGS(V) \
93+
NODE_BUILTIN_QUIC_BINDINGS(V)
9394

9495
// This is used to load built-in bindings. Instead of using
9596
// __attribute__((constructor)), we call the _register_<modname>

src/node_binding.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
3030
#define NODE_BUILTIN_ICU_BINDINGS(V)
3131
#endif
3232

33+
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
34+
#define NODE_BUILTIN_QUIC_BINDINGS(V) V(quic)
35+
#else
36+
#define NODE_BUILTIN_QUIC_BINDINGS(V)
37+
#endif
38+
3339
#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) \
3440
V(async_wrap) \
3541
V(blob) \
@@ -47,7 +53,8 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
4753
V(timers) \
4854
V(url) \
4955
V(worker) \
50-
NODE_BUILTIN_ICU_BINDINGS(V)
56+
NODE_BUILTIN_ICU_BINDINGS(V) \
57+
NODE_BUILTIN_QUIC_BINDINGS(V)
5158

5259
#define NODE_BINDING_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \
5360
static node::node_module _module = { \

src/node_external_reference.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,18 @@ class ExternalReferenceRegistry {
154154
#define EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V)
155155
#endif // HAVE_OPENSSL
156156

157+
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
158+
#define EXTERNAL_REFERENCE_BINDING_LIST_QUIC(V) V(quic)
159+
#else
160+
#define EXTERNAL_REFERENCE_BINDING_LIST_QUIC(V)
161+
#endif
162+
157163
#define EXTERNAL_REFERENCE_BINDING_LIST(V) \
158164
EXTERNAL_REFERENCE_BINDING_LIST_BASE(V) \
159165
EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V) \
160166
EXTERNAL_REFERENCE_BINDING_LIST_I18N(V) \
161-
EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V)
167+
EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V) \
168+
EXTERNAL_REFERENCE_BINDING_LIST_QUIC(V)
162169

163170
} // namespace node
164171

src/quic/application.cc

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
#include "node_bob.h"
2-
#include "uv.h"
31
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
42

3+
#include "application.h"
4+
#include <node_bob.h>
55
#include <node_sockaddr-inl.h>
6+
#include <uv.h>
67
#include <v8.h>
7-
#include "application.h"
88
#include "defs.h"
99
#include "endpoint.h"
1010
#include "packet.h"
@@ -38,14 +38,23 @@ const Session::Application_Options Session::Application_Options::kDefault = {};
3838

3939
Maybe<Session::Application_Options> Session::Application_Options::From(
4040
Environment* env, Local<Value> value) {
41-
if (value.IsEmpty() || !value->IsObject()) {
41+
if (value.IsEmpty()) {
4242
THROW_ERR_INVALID_ARG_TYPE(env, "options must be an object");
4343
return Nothing<Application_Options>();
4444
}
4545

46+
Application_Options options;
4647
auto& state = BindingData::Get(env);
48+
if (value->IsUndefined()) {
49+
return Just<Application_Options>(options);
50+
}
51+
52+
if (!value->IsObject()) {
53+
THROW_ERR_INVALID_ARG_TYPE(env, "options must be an object");
54+
return Nothing<Application_Options>();
55+
}
56+
4757
auto params = value.As<Object>();
48-
Application_Options options;
4958

5059
#define SET(name) \
5160
SetOption<Session::Application_Options, \

src/quic/bindingdata.cc

+5-4
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ void BindingData::DecreaseAllocatedSize(size_t size) {
5656
current_ngtcp2_memory_ -= size;
5757
}
5858

59-
void BindingData::Initialize(Environment* env, Local<Object> target) {
60-
SetMethod(env->context(), target, "setCallbacks", SetCallbacks);
61-
SetMethod(env->context(), target, "flushPacketFreelist", FlushPacketFreelist);
62-
Realm::GetCurrent(env->context())->AddBindingData<BindingData>(target);
59+
void BindingData::InitPerContext(Realm* realm, Local<Object> target) {
60+
SetMethod(realm->context(), target, "setCallbacks", SetCallbacks);
61+
SetMethod(
62+
realm->context(), target, "flushPacketFreelist", FlushPacketFreelist);
63+
Realm::GetCurrent(realm->context())->AddBindingData<BindingData>(target);
6364
}
6465

6566
void BindingData::RegisterExternalReferences(

src/quic/bindingdata.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,14 @@ constexpr size_t kMaxVectorCount = 16;
118118
V(address_lru_size, "addressLRUSize") \
119119
V(alpn, "alpn") \
120120
V(application_options, "application") \
121+
V(bbr, "bbr") \
122+
V(bbr2, "bbr2") \
121123
V(ca, "ca") \
122124
V(certs, "certs") \
123125
V(cc_algorithm, "cc") \
124126
V(crl, "crl") \
125127
V(ciphers, "ciphers") \
128+
V(cubic, "cubic") \
126129
V(disable_active_migration, "disableActiveMigration") \
127130
V(disable_stateless_reset, "disableStatelessReset") \
128131
V(enable_tls_trace, "tlsTrace") \
@@ -162,6 +165,7 @@ constexpr size_t kMaxVectorCount = 16;
162165
V(qpack_encoder_max_dtable_capacity, "qpackEncoderMaxDTableCapacity") \
163166
V(qpack_max_dtable_capacity, "qpackMaxDTableCapacity") \
164167
V(reject_unauthorized, "rejectUnauthorized") \
168+
V(reno, "reno") \
165169
V(retry_token_expiration, "retryTokenExpiration") \
166170
V(request_peer_certificate, "requestPeerCertificate") \
167171
V(reset_token_secret, "resetTokenSecret") \
@@ -194,7 +198,7 @@ class BindingData final
194198
public mem::NgLibMemoryManager<BindingData, ngtcp2_mem> {
195199
public:
196200
SET_BINDING_ID(quic_binding_data)
197-
static void Initialize(Environment* env, v8::Local<v8::Object> target);
201+
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target);
198202
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
199203

200204
static BindingData& Get(Environment* env);

src/quic/defs.h

+40-6
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,38 @@ bool SetOption(Environment* env,
2828
}
2929

3030
template <typename Opt, bool Opt::*member>
31+
bool SetOption(Environment* env,
32+
Opt* options,
33+
const v8::Local<v8::Object>& object,
34+
const v8::Local<v8::String>& name) {
35+
v8::Local<v8::Value> value;
36+
if (!object->Get(env->context(), name).ToLocal(&value)) return false;
37+
options->*member = value->BooleanValue(env->isolate());
38+
return true;
39+
}
40+
41+
template <typename Opt, uint32_t Opt::*member>
3142
bool SetOption(Environment* env,
3243
Opt* options,
3344
const v8::Local<v8::Object>& object,
3445
const v8::Local<v8::String>& name) {
3546
v8::Local<v8::Value> value;
3647
if (!object->Get(env->context(), name).ToLocal(&value)) return false;
3748
if (!value->IsUndefined()) {
38-
CHECK(value->IsBoolean());
39-
options->*member = value->IsTrue();
49+
if (!value->IsUint32()) {
50+
Utf8Value nameStr(env->isolate(), name);
51+
THROW_ERR_INVALID_ARG_VALUE(
52+
env, "The %s option must be an uint32", *nameStr);
53+
return false;
54+
}
55+
v8::Local<v8::Uint32> num;
56+
if (!value->ToUint32(env->context()).ToLocal(&num)) {
57+
Utf8Value nameStr(env->isolate(), name);
58+
THROW_ERR_INVALID_ARG_VALUE(
59+
env, "The %s option must be an uint32", *nameStr);
60+
return false;
61+
}
62+
options->*member = num->Value();
4063
}
4164
return true;
4265
}
@@ -50,20 +73,31 @@ bool SetOption(Environment* env,
5073
if (!object->Get(env->context(), name).ToLocal(&value)) return false;
5174

5275
if (!value->IsUndefined()) {
53-
CHECK_IMPLIES(!value->IsBigInt(), value->IsNumber());
76+
if (!value->IsBigInt() && !value->IsNumber()) {
77+
Utf8Value nameStr(env->isolate(), name);
78+
THROW_ERR_INVALID_ARG_VALUE(
79+
env, "option %s must be a bigint or number", *nameStr);
80+
return false;
81+
}
82+
DCHECK_IMPLIES(!value->IsBigInt(), value->IsNumber());
5483

5584
uint64_t val = 0;
5685
if (value->IsBigInt()) {
5786
bool lossless = true;
5887
val = value.As<v8::BigInt>()->Uint64Value(&lossless);
5988
if (!lossless) {
6089
Utf8Value label(env->isolate(), name);
61-
THROW_ERR_OUT_OF_RANGE(
62-
env, ("options." + label.ToString() + " is out of range").c_str());
90+
THROW_ERR_INVALID_ARG_VALUE(env, "option %s is out of range", *label);
6391
return false;
6492
}
6593
} else {
66-
val = static_cast<int64_t>(value.As<v8::Number>()->Value());
94+
double dbl = value.As<v8::Number>()->Value();
95+
if (dbl < 0) {
96+
Utf8Value label(env->isolate(), name);
97+
THROW_ERR_INVALID_ARG_VALUE(env, "option %s is out of range", *label);
98+
return false;
99+
}
100+
val = static_cast<uint64_t>(dbl);
67101
}
68102
options->*member = val;
69103
}

0 commit comments

Comments
 (0)