Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quic: add quic internalBinding, refine Endpoint, add types #51112

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions node.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@
'src/quic/tlscontext.h',
'src/quic/tokens.h',
'src/quic/transportparams.h',
'src/quic/quic.cc',
],
'node_cctest_sources': [
'src/node_snapshot_stub.cc',
Expand Down
3 changes: 2 additions & 1 deletion src/node_binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@
NODE_BUILTIN_STANDARD_BINDINGS(V) \
NODE_BUILTIN_OPENSSL_BINDINGS(V) \
NODE_BUILTIN_ICU_BINDINGS(V) \
NODE_BUILTIN_PROFILER_BINDINGS(V)
NODE_BUILTIN_PROFILER_BINDINGS(V) \
NODE_BUILTIN_QUIC_BINDINGS(V)

// This is used to load built-in bindings. Instead of using
// __attribute__((constructor)), we call the _register_<modname>
Expand Down
9 changes: 8 additions & 1 deletion src/node_binding.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
#define NODE_BUILTIN_ICU_BINDINGS(V)
#endif

#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
#define NODE_BUILTIN_QUIC_BINDINGS(V) V(quic)
#else
#define NODE_BUILTIN_QUIC_BINDINGS(V)
#endif

#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) \
V(async_wrap) \
V(blob) \
Expand All @@ -47,7 +53,8 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
V(timers) \
V(url) \
V(worker) \
NODE_BUILTIN_ICU_BINDINGS(V)
NODE_BUILTIN_ICU_BINDINGS(V) \
NODE_BUILTIN_QUIC_BINDINGS(V)

#define NODE_BINDING_CONTEXT_AWARE_CPP(modname, regfunc, priv, flags) \
static node::node_module _module = { \
Expand Down
9 changes: 8 additions & 1 deletion src/node_external_reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,18 @@ class ExternalReferenceRegistry {
#define EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V)
#endif // HAVE_OPENSSL

#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
#define EXTERNAL_REFERENCE_BINDING_LIST_QUIC(V) V(quic)
#else
#define EXTERNAL_REFERENCE_BINDING_LIST_QUIC(V)
#endif

#define EXTERNAL_REFERENCE_BINDING_LIST(V) \
EXTERNAL_REFERENCE_BINDING_LIST_BASE(V) \
EXTERNAL_REFERENCE_BINDING_LIST_INSPECTOR(V) \
EXTERNAL_REFERENCE_BINDING_LIST_I18N(V) \
EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V)
EXTERNAL_REFERENCE_BINDING_LIST_CRYPTO(V) \
EXTERNAL_REFERENCE_BINDING_LIST_QUIC(V)

} // namespace node

Expand Down
19 changes: 14 additions & 5 deletions src/quic/application.cc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "node_bob.h"
#include "uv.h"
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC

#include "application.h"
#include <node_bob.h>
#include <node_sockaddr-inl.h>
#include <uv.h>
#include <v8.h>
#include "application.h"
#include "defs.h"
#include "endpoint.h"
#include "packet.h"
Expand Down Expand Up @@ -38,14 +38,23 @@ const Session::Application_Options Session::Application_Options::kDefault = {};

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

Application_Options options;
auto& state = BindingData::Get(env);
if (value->IsUndefined()) {
return Just<Application_Options>(options);
}

if (!value->IsObject()) {
THROW_ERR_INVALID_ARG_TYPE(env, "options must be an object");
return Nothing<Application_Options>();
}

auto params = value.As<Object>();
Application_Options options;

#define SET(name) \
SetOption<Session::Application_Options, \
Expand Down
9 changes: 5 additions & 4 deletions src/quic/bindingdata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ void BindingData::DecreaseAllocatedSize(size_t size) {
current_ngtcp2_memory_ -= size;
}

void BindingData::Initialize(Environment* env, Local<Object> target) {
SetMethod(env->context(), target, "setCallbacks", SetCallbacks);
SetMethod(env->context(), target, "flushPacketFreelist", FlushPacketFreelist);
Realm::GetCurrent(env->context())->AddBindingData<BindingData>(target);
void BindingData::InitPerContext(Realm* realm, Local<Object> target) {
SetMethod(realm->context(), target, "setCallbacks", SetCallbacks);
SetMethod(
realm->context(), target, "flushPacketFreelist", FlushPacketFreelist);
Realm::GetCurrent(realm->context())->AddBindingData<BindingData>(target);
}

void BindingData::RegisterExternalReferences(
Expand Down
6 changes: 5 additions & 1 deletion src/quic/bindingdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,14 @@ constexpr size_t kMaxVectorCount = 16;
V(address_lru_size, "addressLRUSize") \
V(alpn, "alpn") \
V(application_options, "application") \
V(bbr, "bbr") \
V(bbr2, "bbr2") \
V(ca, "ca") \
V(certs, "certs") \
V(cc_algorithm, "cc") \
V(crl, "crl") \
V(ciphers, "ciphers") \
V(cubic, "cubic") \
V(disable_active_migration, "disableActiveMigration") \
V(disable_stateless_reset, "disableStatelessReset") \
V(enable_tls_trace, "tlsTrace") \
Expand Down Expand Up @@ -162,6 +165,7 @@ constexpr size_t kMaxVectorCount = 16;
V(qpack_encoder_max_dtable_capacity, "qpackEncoderMaxDTableCapacity") \
V(qpack_max_dtable_capacity, "qpackMaxDTableCapacity") \
V(reject_unauthorized, "rejectUnauthorized") \
V(reno, "reno") \
V(retry_token_expiration, "retryTokenExpiration") \
V(request_peer_certificate, "requestPeerCertificate") \
V(reset_token_secret, "resetTokenSecret") \
Expand Down Expand Up @@ -194,7 +198,7 @@ class BindingData final
public mem::NgLibMemoryManager<BindingData, ngtcp2_mem> {
public:
SET_BINDING_ID(quic_binding_data)
static void Initialize(Environment* env, v8::Local<v8::Object> target);
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);

static BindingData& Get(Environment* env);
Expand Down
46 changes: 40 additions & 6 deletions src/quic/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,38 @@ bool SetOption(Environment* env,
}

template <typename Opt, bool Opt::*member>
bool SetOption(Environment* env,
Opt* options,
const v8::Local<v8::Object>& object,
const v8::Local<v8::String>& name) {
v8::Local<v8::Value> value;
if (!object->Get(env->context(), name).ToLocal(&value)) return false;
options->*member = value->BooleanValue(env->isolate());
return true;
}

template <typename Opt, uint32_t Opt::*member>
bool SetOption(Environment* env,
Opt* options,
const v8::Local<v8::Object>& object,
const v8::Local<v8::String>& name) {
v8::Local<v8::Value> value;
if (!object->Get(env->context(), name).ToLocal(&value)) return false;
if (!value->IsUndefined()) {
CHECK(value->IsBoolean());
options->*member = value->IsTrue();
if (!value->IsUint32()) {
Utf8Value nameStr(env->isolate(), name);
THROW_ERR_INVALID_ARG_VALUE(
env, "The %s option must be an uint32", *nameStr);
return false;
}
v8::Local<v8::Uint32> num;
if (!value->ToUint32(env->context()).ToLocal(&num)) {
Utf8Value nameStr(env->isolate(), name);
THROW_ERR_INVALID_ARG_VALUE(
env, "The %s option must be an uint32", *nameStr);
return false;
}
options->*member = num->Value();
}
return true;
}
Expand All @@ -50,20 +73,31 @@ bool SetOption(Environment* env,
if (!object->Get(env->context(), name).ToLocal(&value)) return false;

if (!value->IsUndefined()) {
CHECK_IMPLIES(!value->IsBigInt(), value->IsNumber());
if (!value->IsBigInt() && !value->IsNumber()) {
Utf8Value nameStr(env->isolate(), name);
THROW_ERR_INVALID_ARG_VALUE(
env, "option %s must be a bigint or number", *nameStr);
return false;
}
DCHECK_IMPLIES(!value->IsBigInt(), value->IsNumber());

uint64_t val = 0;
if (value->IsBigInt()) {
bool lossless = true;
val = value.As<v8::BigInt>()->Uint64Value(&lossless);
if (!lossless) {
Utf8Value label(env->isolate(), name);
THROW_ERR_OUT_OF_RANGE(
env, ("options." + label.ToString() + " is out of range").c_str());
THROW_ERR_INVALID_ARG_VALUE(env, "option %s is out of range", *label);
return false;
}
} else {
val = static_cast<int64_t>(value.As<v8::Number>()->Value());
double dbl = value.As<v8::Number>()->Value();
if (dbl < 0) {
Utf8Value label(env->isolate(), name);
THROW_ERR_INVALID_ARG_VALUE(env, "option %s is out of range", *label);
return false;
}
val = static_cast<uint64_t>(dbl);
}
options->*member = val;
}
Expand Down
Loading
Loading