mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
quic: reduce boilerplate and other minor cleanups
While I get that macros aren't the most loved thing in the world, they do help reduce boilerplate, and there's a lot of boilerplate in the QUIC code. This commit cleans up some of that boilerplate, particularly around the use of v8 APIs. PR-URL: https://github.com/nodejs/node/pull/59342 Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
This commit is contained in:
parent
cd9fd09a27
commit
b4af647920
|
|
@ -1826,16 +1826,6 @@ added: v21.2.0
|
||||||
|
|
||||||
Disable exposition of [Navigator API][] on the global scope.
|
Disable exposition of [Navigator API][] on the global scope.
|
||||||
|
|
||||||
### `--no-experimental-quic`
|
|
||||||
|
|
||||||
<!-- YAML
|
|
||||||
added: REPLACEME
|
|
||||||
-->
|
|
||||||
|
|
||||||
> Stability: 1.1 - Active Development
|
|
||||||
|
|
||||||
Use this flag to disable QUIC.
|
|
||||||
|
|
||||||
### `--no-experimental-repl-await`
|
### `--no-experimental-repl-await`
|
||||||
|
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
|
|
@ -3462,6 +3452,7 @@ one is included in the list below.
|
||||||
* `--experimental-loader`
|
* `--experimental-loader`
|
||||||
* `--experimental-modules`
|
* `--experimental-modules`
|
||||||
* `--experimental-print-required-tla`
|
* `--experimental-print-required-tla`
|
||||||
|
* `--experimental-quic`
|
||||||
* `--experimental-require-module`
|
* `--experimental-require-module`
|
||||||
* `--experimental-shadow-realm`
|
* `--experimental-shadow-realm`
|
||||||
* `--experimental-specifier-resolution`
|
* `--experimental-specifier-resolution`
|
||||||
|
|
|
||||||
|
|
@ -226,9 +226,6 @@ flag is no longer required as WASI is enabled by default.
|
||||||
.It Fl -experimental-quic
|
.It Fl -experimental-quic
|
||||||
Enable the experimental QUIC support.
|
Enable the experimental QUIC support.
|
||||||
.
|
.
|
||||||
.It Fl -no-experimental-quic
|
|
||||||
Disable the experimental QUIC support.
|
|
||||||
.
|
|
||||||
.It Fl -experimental-inspector-network-resource
|
.It Fl -experimental-inspector-network-resource
|
||||||
Enable experimental support for inspector network resources.
|
Enable experimental support for inspector network resources.
|
||||||
.
|
.
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,14 @@ const {
|
||||||
Uint8Array,
|
Uint8Array,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
|
||||||
// QUIC requires that Node.js be compiled with crypto support.
|
|
||||||
const {
|
const {
|
||||||
assertCrypto,
|
getOptionValue,
|
||||||
} = require('internal/util');
|
} = require('internal/options');
|
||||||
assertCrypto();
|
|
||||||
|
// QUIC requires that Node.js be compiled with crypto support.
|
||||||
|
if (!process.features.quic || !getOptionValue('--experimental-quic')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { inspect } = require('internal/util/inspect');
|
const { inspect } = require('internal/util/inspect');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,14 @@ const {
|
||||||
JSONStringify,
|
JSONStringify,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
|
||||||
|
const {
|
||||||
|
getOptionValue,
|
||||||
|
} = require('internal/options');
|
||||||
|
|
||||||
|
if (!process.features.quic || !getOptionValue('--experimental-quic')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
codes: {
|
codes: {
|
||||||
ERR_ILLEGAL_CONSTRUCTOR,
|
ERR_ILLEGAL_CONSTRUCTOR,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,14 @@ const {
|
||||||
JSONStringify,
|
JSONStringify,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
|
||||||
|
const {
|
||||||
|
getOptionValue,
|
||||||
|
} = require('internal/options');
|
||||||
|
|
||||||
|
if (!process.features.quic || !getOptionValue('--experimental-quic')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isArrayBuffer,
|
isArrayBuffer,
|
||||||
} = require('util/types');
|
} = require('util/types');
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,14 @@ const {
|
||||||
Symbol,
|
Symbol,
|
||||||
} = primordials;
|
} = primordials;
|
||||||
|
|
||||||
|
const {
|
||||||
|
getOptionValue,
|
||||||
|
} = require('internal/options');
|
||||||
|
|
||||||
|
if (!process.features.quic || !getOptionValue('--experimental-quic')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
customInspectSymbol: kInspect,
|
customInspectSymbol: kInspect,
|
||||||
} = require('internal/util');
|
} = require('internal/util');
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ namespace node {
|
||||||
V(simdutf) \
|
V(simdutf) \
|
||||||
V(ada) \
|
V(ada) \
|
||||||
V(nbytes) \
|
V(nbytes) \
|
||||||
|
V(ngtcp2) \
|
||||||
|
V(nghttp3) \
|
||||||
NODE_VERSIONS_KEY_AMARO(V) \
|
NODE_VERSIONS_KEY_AMARO(V) \
|
||||||
NODE_VERSIONS_KEY_UNDICI(V) \
|
NODE_VERSIONS_KEY_UNDICI(V) \
|
||||||
V(cjs_module_lexer)
|
V(cjs_module_lexer)
|
||||||
|
|
@ -80,14 +82,6 @@ namespace node {
|
||||||
#define NODE_VERSIONS_KEY_INTL(V)
|
#define NODE_VERSIONS_KEY_INTL(V)
|
||||||
#endif // NODE_HAVE_I18N_SUPPORT
|
#endif // NODE_HAVE_I18N_SUPPORT
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_QUIC
|
|
||||||
#define NODE_VERSIONS_KEY_QUIC(V) \
|
|
||||||
V(ngtcp2) \
|
|
||||||
V(nghttp3)
|
|
||||||
#else
|
|
||||||
#define NODE_VERSIONS_KEY_QUIC(V)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_SQLITE
|
#if HAVE_SQLITE
|
||||||
#define NODE_VERSIONS_KEY_SQLITE(V) V(sqlite)
|
#define NODE_VERSIONS_KEY_SQLITE(V) V(sqlite)
|
||||||
#else
|
#else
|
||||||
|
|
@ -98,7 +92,6 @@ namespace node {
|
||||||
NODE_VERSIONS_KEYS_BASE(V) \
|
NODE_VERSIONS_KEYS_BASE(V) \
|
||||||
NODE_VERSIONS_KEY_CRYPTO(V) \
|
NODE_VERSIONS_KEY_CRYPTO(V) \
|
||||||
NODE_VERSIONS_KEY_INTL(V) \
|
NODE_VERSIONS_KEY_INTL(V) \
|
||||||
NODE_VERSIONS_KEY_QUIC(V) \
|
|
||||||
NODE_VERSIONS_KEY_SQLITE(V)
|
NODE_VERSIONS_KEY_SQLITE(V)
|
||||||
|
|
||||||
#define V(key) +1
|
#define V(key) +1
|
||||||
|
|
|
||||||
|
|
@ -551,10 +551,11 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
|
||||||
kAllowedInEnvvar,
|
kAllowedInEnvvar,
|
||||||
true);
|
true);
|
||||||
AddOption("--experimental-quic",
|
AddOption("--experimental-quic",
|
||||||
"" /* undocumented until its development */,
|
|
||||||
#ifndef OPENSSL_NO_QUIC
|
#ifndef OPENSSL_NO_QUIC
|
||||||
|
"experimental QUIC support",
|
||||||
&EnvironmentOptions::experimental_quic,
|
&EnvironmentOptions::experimental_quic,
|
||||||
#else
|
#else
|
||||||
|
"" /* undocumented when no-op */,
|
||||||
NoOp{},
|
NoOp{},
|
||||||
#endif
|
#endif
|
||||||
kAllowedInEnvvar);
|
kAllowedInEnvvar);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
using v8::Function;
|
using v8::Function;
|
||||||
using v8::FunctionCallbackInfo;
|
|
||||||
using v8::FunctionTemplate;
|
using v8::FunctionTemplate;
|
||||||
using v8::Local;
|
using v8::Local;
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
|
|
@ -144,7 +143,7 @@ QUIC_JS_CALLBACKS(V)
|
||||||
|
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(BindingData::SetCallbacks) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
auto isolate = env->isolate();
|
auto isolate = env->isolate();
|
||||||
auto& state = Get(env);
|
auto& state = Get(env);
|
||||||
|
|
@ -166,7 +165,7 @@ void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) {
|
||||||
#undef V
|
#undef V
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindingData::FlushPacketFreelist(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(BindingData::FlushPacketFreelist) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
auto& state = Get(env);
|
auto& state = Get(env);
|
||||||
state.packet_freelist.clear();
|
state.packet_freelist.clear();
|
||||||
|
|
@ -217,7 +216,7 @@ CallbackScopeBase::~CallbackScopeBase() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IllegalConstructor(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(IllegalConstructor) {
|
||||||
THROW_ERR_ILLEGAL_CONSTRUCTOR(Environment::GetCurrent(args));
|
THROW_ERR_ILLEGAL_CONSTRUCTOR(Environment::GetCurrent(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,16 +167,15 @@ class BindingData final
|
||||||
|
|
||||||
// Installs the set of JavaScript callback functions that are used to
|
// Installs the set of JavaScript callback functions that are used to
|
||||||
// bridge out to the JS API.
|
// bridge out to the JS API.
|
||||||
static void SetCallbacks(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD(SetCallbacks);
|
||||||
|
|
||||||
|
// Purge the packet free list to free up memory.
|
||||||
|
JS_METHOD(FlushPacketFreelist);
|
||||||
|
|
||||||
std::vector<BaseObjectPtr<BaseObject>> packet_freelist;
|
std::vector<BaseObjectPtr<BaseObject>> packet_freelist;
|
||||||
|
|
||||||
std::unordered_map<Endpoint*, BaseObjectPtr<BaseObject>> listening_endpoints;
|
std::unordered_map<Endpoint*, BaseObjectPtr<BaseObject>> listening_endpoints;
|
||||||
|
|
||||||
// Purge the packet free list to free up memory.
|
|
||||||
static void FlushPacketFreelist(
|
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
|
|
||||||
bool in_ngtcp2_callback_scope = false;
|
bool in_ngtcp2_callback_scope = false;
|
||||||
bool in_nghttp3_callback_scope = false;
|
bool in_nghttp3_callback_scope = false;
|
||||||
size_t current_ngtcp2_memory_ = 0;
|
size_t current_ngtcp2_memory_ = 0;
|
||||||
|
|
@ -223,7 +222,7 @@ class BindingData final
|
||||||
#undef V
|
#undef V
|
||||||
};
|
};
|
||||||
|
|
||||||
void IllegalConstructor(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD_IMPL(IllegalConstructor);
|
||||||
|
|
||||||
// The ngtcp2 and nghttp3 callbacks have certain restrictions
|
// The ngtcp2 and nghttp3 callbacks have certain restrictions
|
||||||
// that forbid re-entry. We provide the following scopes for
|
// that forbid re-entry. We provide the following scopes for
|
||||||
|
|
|
||||||
|
|
@ -375,8 +375,6 @@ QuicError QuicError::FromConnectionClose(ngtcp2_conn* session) {
|
||||||
return QuicError(ngtcp2_conn_get_ccerr(session));
|
return QuicError(ngtcp2_conn_get_ccerr(session));
|
||||||
}
|
}
|
||||||
|
|
||||||
const QuicError QuicError::TRANSPORT_NO_ERROR =
|
|
||||||
ForTransport(TransportError::NO_ERROR_);
|
|
||||||
#define V(name) \
|
#define V(name) \
|
||||||
const QuicError QuicError::TRANSPORT_##name = \
|
const QuicError QuicError::TRANSPORT_##name = \
|
||||||
ForTransport(TransportError::name);
|
ForTransport(TransportError::name);
|
||||||
|
|
|
||||||
|
|
@ -156,9 +156,6 @@ class QuicError final : public MemoryRetainer {
|
||||||
// it as is.
|
// it as is.
|
||||||
NO_ERROR_ = NGTCP2_NO_ERROR,
|
NO_ERROR_ = NGTCP2_NO_ERROR,
|
||||||
#define V(name) name = NGTCP2_##name,
|
#define V(name) name = NGTCP2_##name,
|
||||||
// The NO_ERROR here has to be treated as a special case since there
|
|
||||||
// is a NO_ERROR macro defined in Windows that conflicts.
|
|
||||||
NO_ERROR_ = NGTCP2_NO_ERROR,
|
|
||||||
QUIC_TRANSPORT_ERRORS(V)
|
QUIC_TRANSPORT_ERRORS(V)
|
||||||
#undef V
|
#undef V
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -161,8 +161,96 @@ uint64_t GetStat(Stats* stats) {
|
||||||
name##_STATS(STAT_FIELD) \
|
name##_STATS(STAT_FIELD) \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define JS_METHOD(name) \
|
#define JS_METHOD_IMPL(name) \
|
||||||
static void name(const v8::FunctionCallbackInfo<v8::Value>& args)
|
void name(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||||||
|
|
||||||
|
#define JS_METHOD(name) static JS_METHOD_IMPL(name)
|
||||||
|
|
||||||
|
#define JS_CONSTRUCTOR(name) \
|
||||||
|
inline static bool HasInstance(Environment* env, \
|
||||||
|
v8::Local<v8::Value> value) { \
|
||||||
|
return GetConstructorTemplate(env)->HasInstance(value); \
|
||||||
|
} \
|
||||||
|
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( \
|
||||||
|
Environment* env)
|
||||||
|
|
||||||
|
#define JS_CONSTRUCTOR_IMPL(name, template, body) \
|
||||||
|
v8::Local<v8::FunctionTemplate> name::GetConstructorTemplate( \
|
||||||
|
Environment* env) { \
|
||||||
|
auto& state = BindingData::Get(env); \
|
||||||
|
auto tmpl = state.template(); \
|
||||||
|
if (tmpl.IsEmpty()) { \
|
||||||
|
body state.set_##template(tmpl); \
|
||||||
|
} \
|
||||||
|
return tmpl; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define JS_ILLEGAL_CONSTRUCTOR() \
|
||||||
|
tmpl = NewFunctionTemplate(env->isolate(), IllegalConstructor)
|
||||||
|
|
||||||
|
#define JS_NEW_CONSTRUCTOR() tmpl = NewFunctionTemplate(env->isolate(), New)
|
||||||
|
|
||||||
|
#define JS_INHERIT(name) tmpl->Inherit(name::GetConstructorTemplate(env));
|
||||||
|
|
||||||
|
#define JS_CLASS(name) \
|
||||||
|
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount); \
|
||||||
|
tmpl->SetClassName(state.name##_string())
|
||||||
|
|
||||||
|
#define JS_CLASS_FIELDS(name, fields) \
|
||||||
|
tmpl->InstanceTemplate()->SetInternalFieldCount(fields); \
|
||||||
|
tmpl->SetClassName(state.name##_string())
|
||||||
|
|
||||||
|
#define JS_NEW_INSTANCE_OR_RETURN(env, name, ret) \
|
||||||
|
v8::Local<v8::Object> name; \
|
||||||
|
if (!GetConstructorTemplate(env) \
|
||||||
|
->InstanceTemplate() \
|
||||||
|
->NewInstance(env->context()) \
|
||||||
|
.ToLocal(&obj)) { \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define JS_NEW_INSTANCE(env, name) \
|
||||||
|
v8::Local<v8::Object> name; \
|
||||||
|
if (!GetConstructorTemplate(env) \
|
||||||
|
->InstanceTemplate() \
|
||||||
|
->NewInstance(env->context()) \
|
||||||
|
.ToLocal(&obj)) { \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define JS_BINDING_INIT_BOILERPLATE() \
|
||||||
|
static void InitPerIsolate(IsolateData* isolate_data, \
|
||||||
|
v8::Local<v8::ObjectTemplate> target); \
|
||||||
|
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target); \
|
||||||
|
static void RegisterExternalReferences(ExternalReferenceRegistry* registry)
|
||||||
|
|
||||||
|
#define JS_TRY_ALLOCATE_BACKING(env, name, len) \
|
||||||
|
auto name = v8::ArrayBuffer::NewBackingStore( \
|
||||||
|
env->isolate(), \
|
||||||
|
len, \
|
||||||
|
v8::BackingStoreInitializationMode::kUninitialized, \
|
||||||
|
v8::BackingStoreOnFailureMode::kReturnNull); \
|
||||||
|
if (!name) { \
|
||||||
|
THROW_ERR_MEMORY_ALLOCATION_FAILED(env); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define JS_TRY_ALLOCATE_BACKING_OR_RETURN(env, name, len, ret) \
|
||||||
|
auto name = v8::ArrayBuffer::NewBackingStore( \
|
||||||
|
env->isolate(), \
|
||||||
|
len, \
|
||||||
|
v8::BackingStoreInitializationMode::kUninitialized, \
|
||||||
|
v8::BackingStoreOnFailureMode::kReturnNull); \
|
||||||
|
if (!name) { \
|
||||||
|
THROW_ERR_MEMORY_ALLOCATION_FAILED(env); \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define JS_DEFINE_READONLY_PROPERTY(env, target, name, value) \
|
||||||
|
target \
|
||||||
|
->DefineOwnProperty( \
|
||||||
|
env->context(), name, value, v8::PropertyAttribute::ReadOnly) \
|
||||||
|
.Check();
|
||||||
|
|
||||||
enum class Side : uint8_t {
|
enum class Side : uint8_t {
|
||||||
CLIENT,
|
CLIENT,
|
||||||
|
|
@ -222,7 +310,7 @@ CC_ALGOS(V)
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
constexpr size_t kDefaultMaxPacketLength = NGTCP2_MAX_UDP_PAYLOAD_SIZE;
|
constexpr size_t kDefaultMaxPacketLength = NGTCP2_MAX_UDP_PAYLOAD_SIZE;
|
||||||
constexpr size_t kMaxSizeT = std::numeric_limits<size_t>::max();
|
constexpr uint64_t kMaxSizeT = std::numeric_limits<size_t>::max();
|
||||||
constexpr uint64_t kMaxSafeJsInteger = 9007199254740991;
|
constexpr uint64_t kMaxSafeJsInteger = 9007199254740991;
|
||||||
constexpr auto kSocketAddressInfoTimeout = 60 * NGTCP2_SECONDS;
|
constexpr auto kSocketAddressInfoTimeout = 60 * NGTCP2_SECONDS;
|
||||||
constexpr size_t kMaxVectorCount = 16;
|
constexpr size_t kMaxVectorCount = 16;
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ namespace node {
|
||||||
|
|
||||||
using v8::ArrayBufferView;
|
using v8::ArrayBufferView;
|
||||||
using v8::BackingStore;
|
using v8::BackingStore;
|
||||||
using v8::FunctionCallbackInfo;
|
|
||||||
using v8::FunctionTemplate;
|
|
||||||
using v8::HandleScope;
|
using v8::HandleScope;
|
||||||
using v8::Integer;
|
using v8::Integer;
|
||||||
using v8::Just;
|
using v8::Just;
|
||||||
|
|
@ -38,7 +36,6 @@ using v8::Nothing;
|
||||||
using v8::Number;
|
using v8::Number;
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
using v8::ObjectTemplate;
|
using v8::ObjectTemplate;
|
||||||
using v8::PropertyAttribute;
|
|
||||||
using v8::String;
|
using v8::String;
|
||||||
using v8::Uint32;
|
using v8::Uint32;
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
@ -284,27 +281,10 @@ std::string Endpoint::Options::ToString() const {
|
||||||
|
|
||||||
class Endpoint::UDP::Impl final : public HandleWrap {
|
class Endpoint::UDP::Impl final : public HandleWrap {
|
||||||
public:
|
public:
|
||||||
static Local<FunctionTemplate> GetConstructorTemplate(Environment* env) {
|
JS_CONSTRUCTOR(Impl);
|
||||||
auto& state = BindingData::Get(env);
|
|
||||||
auto tmpl = state.udp_constructor_template();
|
|
||||||
if (tmpl.IsEmpty()) {
|
|
||||||
tmpl = NewFunctionTemplate(env->isolate(), IllegalConstructor);
|
|
||||||
tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
|
|
||||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
|
||||||
tmpl->SetClassName(state.endpoint_udp_string());
|
|
||||||
state.set_udp_constructor_template(tmpl);
|
|
||||||
}
|
|
||||||
return tmpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Impl* Create(Endpoint* endpoint) {
|
static Impl* Create(Endpoint* endpoint) {
|
||||||
Local<Object> obj;
|
JS_NEW_INSTANCE_OR_RETURN(endpoint->env(), obj, nullptr);
|
||||||
if (!GetConstructorTemplate(endpoint->env())
|
|
||||||
->InstanceTemplate()
|
|
||||||
->NewInstance(endpoint->env()->context())
|
|
||||||
.ToLocal(&obj)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return new Impl(endpoint, obj);
|
return new Impl(endpoint, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,6 +347,12 @@ class Endpoint::UDP::Impl final : public HandleWrap {
|
||||||
friend class UDP;
|
friend class UDP;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JS_CONSTRUCTOR_IMPL(Endpoint::UDP::Impl, udp_constructor_template, {
|
||||||
|
JS_ILLEGAL_CONSTRUCTOR();
|
||||||
|
JS_INHERIT(HandleWrap);
|
||||||
|
JS_CLASS(endpoint_udp);
|
||||||
|
})
|
||||||
|
|
||||||
Endpoint::UDP::UDP(Endpoint* endpoint) : impl_(Impl::Create(endpoint)) {
|
Endpoint::UDP::UDP(Endpoint* endpoint) : impl_(Impl::Create(endpoint)) {
|
||||||
DCHECK(impl_);
|
DCHECK(impl_);
|
||||||
// The endpoint starts in an inactive, unref'd state. It will be ref'd when
|
// The endpoint starts in an inactive, unref'd state. It will be ref'd when
|
||||||
|
|
@ -512,29 +498,18 @@ void Endpoint::UDP::MemoryInfo(MemoryTracker* tracker) const {
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
bool Endpoint::HasInstance(Environment* env, Local<Value> value) {
|
JS_CONSTRUCTOR_IMPL(Endpoint, endpoint_constructor_template, {
|
||||||
return GetConstructorTemplate(env)->HasInstance(value);
|
auto isolate = env->isolate();
|
||||||
}
|
JS_NEW_CONSTRUCTOR();
|
||||||
|
JS_INHERIT(AsyncWrap);
|
||||||
Local<FunctionTemplate> Endpoint::GetConstructorTemplate(Environment* env) {
|
JS_CLASS(endpoint);
|
||||||
auto& state = BindingData::Get(env);
|
SetProtoMethod(isolate, tmpl, "listen", DoListen);
|
||||||
auto tmpl = state.endpoint_constructor_template();
|
SetProtoMethod(isolate, tmpl, "closeGracefully", DoCloseGracefully);
|
||||||
if (tmpl.IsEmpty()) {
|
SetProtoMethod(isolate, tmpl, "connect", DoConnect);
|
||||||
auto isolate = env->isolate();
|
SetProtoMethod(isolate, tmpl, "markBusy", MarkBusy);
|
||||||
tmpl = NewFunctionTemplate(isolate, New);
|
SetProtoMethod(isolate, tmpl, "ref", Ref);
|
||||||
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
|
SetProtoMethodNoSideEffect(isolate, tmpl, "address", LocalAddress);
|
||||||
tmpl->SetClassName(state.endpoint_string());
|
})
|
||||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
|
||||||
SetProtoMethod(isolate, tmpl, "listen", DoListen);
|
|
||||||
SetProtoMethod(isolate, tmpl, "closeGracefully", DoCloseGracefully);
|
|
||||||
SetProtoMethod(isolate, tmpl, "connect", DoConnect);
|
|
||||||
SetProtoMethod(isolate, tmpl, "markBusy", MarkBusy);
|
|
||||||
SetProtoMethod(isolate, tmpl, "ref", Ref);
|
|
||||||
SetProtoMethodNoSideEffect(isolate, tmpl, "address", LocalAddress);
|
|
||||||
state.set_endpoint_constructor_template(tmpl);
|
|
||||||
}
|
|
||||||
return tmpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Endpoint::InitPerIsolate(IsolateData* data, Local<ObjectTemplate> target) {
|
void Endpoint::InitPerIsolate(IsolateData* data, Local<ObjectTemplate> target) {
|
||||||
// TODO(@jasnell): Implement the per-isolate state
|
// TODO(@jasnell): Implement the per-isolate state
|
||||||
|
|
@ -576,17 +551,17 @@ void Endpoint::InitPerContext(Realm* realm, Local<Object> target) {
|
||||||
NODE_DEFINE_CONSTANT(target, DEFAULT_MAX_PACKET_LENGTH);
|
NODE_DEFINE_CONSTANT(target, DEFAULT_MAX_PACKET_LENGTH);
|
||||||
|
|
||||||
static constexpr auto CLOSECONTEXT_CLOSE =
|
static constexpr auto CLOSECONTEXT_CLOSE =
|
||||||
static_cast<int>(CloseContext::CLOSE);
|
static_cast<uint8_t>(CloseContext::CLOSE);
|
||||||
static constexpr auto CLOSECONTEXT_BIND_FAILURE =
|
static constexpr auto CLOSECONTEXT_BIND_FAILURE =
|
||||||
static_cast<int>(CloseContext::BIND_FAILURE);
|
static_cast<uint8_t>(CloseContext::BIND_FAILURE);
|
||||||
static constexpr auto CLOSECONTEXT_LISTEN_FAILURE =
|
static constexpr auto CLOSECONTEXT_LISTEN_FAILURE =
|
||||||
static_cast<int>(CloseContext::LISTEN_FAILURE);
|
static_cast<uint8_t>(CloseContext::LISTEN_FAILURE);
|
||||||
static constexpr auto CLOSECONTEXT_RECEIVE_FAILURE =
|
static constexpr auto CLOSECONTEXT_RECEIVE_FAILURE =
|
||||||
static_cast<int>(CloseContext::RECEIVE_FAILURE);
|
static_cast<uint8_t>(CloseContext::RECEIVE_FAILURE);
|
||||||
static constexpr auto CLOSECONTEXT_SEND_FAILURE =
|
static constexpr auto CLOSECONTEXT_SEND_FAILURE =
|
||||||
static_cast<int>(CloseContext::SEND_FAILURE);
|
static_cast<uint8_t>(CloseContext::SEND_FAILURE);
|
||||||
static constexpr auto CLOSECONTEXT_START_FAILURE =
|
static constexpr auto CLOSECONTEXT_START_FAILURE =
|
||||||
static_cast<int>(CloseContext::START_FAILURE);
|
static_cast<uint8_t>(CloseContext::START_FAILURE);
|
||||||
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_CLOSE);
|
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_CLOSE);
|
||||||
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_BIND_FAILURE);
|
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_BIND_FAILURE);
|
||||||
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_LISTEN_FAILURE);
|
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_LISTEN_FAILURE);
|
||||||
|
|
@ -628,15 +603,10 @@ Endpoint::Endpoint(Environment* env,
|
||||||
Debug(this, "Endpoint created. Options %s", options.ToString());
|
Debug(this, "Endpoint created. Options %s", options.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto defineProperty = [&](auto name, auto value) {
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
object
|
env, object, env->state_string(), state_.GetArrayBuffer());
|
||||||
->DefineOwnProperty(
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
env->context(), name, value, PropertyAttribute::ReadOnly)
|
env, object, env->stats_string(), stats_.GetArrayBuffer());
|
||||||
.Check();
|
|
||||||
};
|
|
||||||
|
|
||||||
defineProperty(env->state_string(), state_.GetArrayBuffer());
|
|
||||||
defineProperty(env->stats_string(), stats_.GetArrayBuffer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketAddress Endpoint::local_address() const {
|
SocketAddress Endpoint::local_address() const {
|
||||||
|
|
@ -1676,7 +1646,7 @@ void Endpoint::EmitClose(CloseContext context, int status) {
|
||||||
// ======================================================================================
|
// ======================================================================================
|
||||||
// Endpoint JavaScript API
|
// Endpoint JavaScript API
|
||||||
|
|
||||||
void Endpoint::New(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(Endpoint::New) {
|
||||||
DCHECK(args.IsConstructCall());
|
DCHECK(args.IsConstructCall());
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Options options;
|
Options options;
|
||||||
|
|
@ -1689,7 +1659,7 @@ void Endpoint::New(const FunctionCallbackInfo<Value>& args) {
|
||||||
new Endpoint(env, args.This(), options);
|
new Endpoint(env, args.This(), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Endpoint::DoConnect(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(Endpoint::DoConnect) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Endpoint* endpoint;
|
Endpoint* endpoint;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||||
|
|
@ -1723,7 +1693,7 @@ void Endpoint::DoConnect(const FunctionCallbackInfo<Value>& args) {
|
||||||
if (session) args.GetReturnValue().Set(session->object());
|
if (session) args.GetReturnValue().Set(session->object());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Endpoint::DoListen(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(Endpoint::DoListen) {
|
||||||
Endpoint* endpoint;
|
Endpoint* endpoint;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
|
|
@ -1734,19 +1704,19 @@ void Endpoint::DoListen(const FunctionCallbackInfo<Value>& args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Endpoint::MarkBusy(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(Endpoint::MarkBusy) {
|
||||||
Endpoint* endpoint;
|
Endpoint* endpoint;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||||
endpoint->MarkAsBusy(args[0]->IsTrue());
|
endpoint->MarkAsBusy(args[0]->IsTrue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Endpoint::DoCloseGracefully(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(Endpoint::DoCloseGracefully) {
|
||||||
Endpoint* endpoint;
|
Endpoint* endpoint;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||||
endpoint->CloseGracefully();
|
endpoint->CloseGracefully();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Endpoint::LocalAddress(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(Endpoint::LocalAddress) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Endpoint* endpoint;
|
Endpoint* endpoint;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||||
|
|
@ -1756,7 +1726,7 @@ void Endpoint::LocalAddress(const FunctionCallbackInfo<Value>& args) {
|
||||||
if (addr) args.GetReturnValue().Set(addr->object());
|
if (addr) args.GetReturnValue().Set(addr->object());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Endpoint::Ref(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(Endpoint::Ref) {
|
||||||
Endpoint* endpoint;
|
Endpoint* endpoint;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace node::quic {
|
||||||
class Endpoint final : public AsyncWrap, public Packet::Listener {
|
class Endpoint final : public AsyncWrap, public Packet::Listener {
|
||||||
public:
|
public:
|
||||||
static constexpr uint64_t DEFAULT_MAX_CONNECTIONS =
|
static constexpr uint64_t DEFAULT_MAX_CONNECTIONS =
|
||||||
std::min<uint64_t>(kMaxSizeT, static_cast<uint64_t>(kMaxSafeJsInteger));
|
std::min<uint64_t>(kMaxSizeT, kMaxSafeJsInteger);
|
||||||
static constexpr uint64_t DEFAULT_MAX_CONNECTIONS_PER_HOST = 100;
|
static constexpr uint64_t DEFAULT_MAX_CONNECTIONS_PER_HOST = 100;
|
||||||
static constexpr uint64_t DEFAULT_MAX_SOCKETADDRESS_LRU_SIZE =
|
static constexpr uint64_t DEFAULT_MAX_SOCKETADDRESS_LRU_SIZE =
|
||||||
(DEFAULT_MAX_CONNECTIONS_PER_HOST * 10);
|
(DEFAULT_MAX_CONNECTIONS_PER_HOST * 10);
|
||||||
|
|
@ -143,13 +143,8 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool HasInstance(Environment* env, v8::Local<v8::Value> value);
|
JS_CONSTRUCTOR(Endpoint);
|
||||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
JS_BINDING_INIT_BOILERPLATE();
|
||||||
Environment* env);
|
|
||||||
static void InitPerIsolate(IsolateData* data,
|
|
||||||
v8::Local<v8::ObjectTemplate> target);
|
|
||||||
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target);
|
|
||||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
|
|
||||||
|
|
||||||
Endpoint(Environment* env,
|
Endpoint(Environment* env,
|
||||||
v8::Local<v8::Object> object,
|
v8::Local<v8::Object> object,
|
||||||
|
|
@ -300,7 +295,7 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
|
||||||
void MaybeDestroy();
|
void MaybeDestroy();
|
||||||
|
|
||||||
// Specifies the general reason the endpoint is being destroyed.
|
// Specifies the general reason the endpoint is being destroyed.
|
||||||
enum class CloseContext {
|
enum class CloseContext : uint8_t {
|
||||||
CLOSE,
|
CLOSE,
|
||||||
BIND_FAILURE,
|
BIND_FAILURE,
|
||||||
START_FAILURE,
|
START_FAILURE,
|
||||||
|
|
@ -330,7 +325,7 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
|
||||||
|
|
||||||
// Create a new Endpoint.
|
// Create a new Endpoint.
|
||||||
// @param Endpoint::Options options - Options to configure the Endpoint.
|
// @param Endpoint::Options options - Options to configure the Endpoint.
|
||||||
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD(New);
|
||||||
|
|
||||||
// Methods on the Endpoint instance:
|
// Methods on the Endpoint instance:
|
||||||
|
|
||||||
|
|
@ -341,31 +336,30 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
|
||||||
// the Session.
|
// the Session.
|
||||||
// @param v8::ArrayBufferView remote_transport_params - The remote transport
|
// @param v8::ArrayBufferView remote_transport_params - The remote transport
|
||||||
// params.
|
// params.
|
||||||
static void DoConnect(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD(DoConnect);
|
||||||
|
|
||||||
// Start listening as a QUIC server
|
// Start listening as a QUIC server
|
||||||
// @param Session::Options options - Options to configure the Session.
|
// @param Session::Options options - Options to configure the Session.
|
||||||
static void DoListen(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD(DoListen);
|
||||||
|
|
||||||
// Mark the Endpoint as busy, temporarily pausing handling of new initial
|
// Mark the Endpoint as busy, temporarily pausing handling of new initial
|
||||||
// packets.
|
// packets.
|
||||||
// @param bool on - If true, mark the Endpoint as busy.
|
// @param bool on - If true, mark the Endpoint as busy.
|
||||||
static void MarkBusy(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD(MarkBusy);
|
||||||
static void FastMarkBusy(v8::Local<v8::Object> receiver, bool on);
|
static void FastMarkBusy(v8::Local<v8::Object> receiver, bool on);
|
||||||
|
|
||||||
// DoCloseGracefully is the signal that endpoint should close. Any packets
|
// DoCloseGracefully is the signal that endpoint should close. Any packets
|
||||||
// that are already in the queue or in flight will be allowed to finish, but
|
// that are already in the queue or in flight will be allowed to finish, but
|
||||||
// the EndpoingWrap will be otherwise no longer able to receive or send
|
// the EndpoingWrap will be otherwise no longer able to receive or send
|
||||||
// packets.
|
// packets.
|
||||||
static void DoCloseGracefully(
|
JS_METHOD(DoCloseGracefully);
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
|
|
||||||
// Get the local address of the Endpoint.
|
// Get the local address of the Endpoint.
|
||||||
// @return node::SocketAddress - The local address of the Endpoint.
|
// @return node::SocketAddress - The local address of the Endpoint.
|
||||||
static void LocalAddress(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD(LocalAddress);
|
||||||
|
|
||||||
// Ref() causes a listening Endpoint to keep the event loop active.
|
// Ref() causes a listening Endpoint to keep the event loop active.
|
||||||
static void Ref(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD(Ref);
|
||||||
static void FastRef(v8::Local<v8::Object> receiver, bool on);
|
static void FastRef(v8::Local<v8::Object> receiver, bool on);
|
||||||
|
|
||||||
void Receive(const uv_buf_t& buf, const SocketAddress& from);
|
void Receive(const uv_buf_t& buf, const SocketAddress& from);
|
||||||
|
|
|
||||||
|
|
@ -20,34 +20,18 @@
|
||||||
|
|
||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
using v8::FunctionCallbackInfo;
|
|
||||||
using v8::FunctionTemplate;
|
|
||||||
using v8::Local;
|
using v8::Local;
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
using v8::ObjectTemplate;
|
using v8::ObjectTemplate;
|
||||||
using v8::Value;
|
|
||||||
|
|
||||||
namespace quic {
|
namespace quic {
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
bool Http3Application::HasInstance(Environment* env, Local<Value> value) {
|
JS_CONSTRUCTOR_IMPL(Http3Application, http3application_constructor_template, {
|
||||||
return GetConstructorTemplate(env)->HasInstance(value);
|
JS_NEW_CONSTRUCTOR();
|
||||||
}
|
JS_CLASS(http3application);
|
||||||
|
})
|
||||||
Local<FunctionTemplate> Http3Application::GetConstructorTemplate(
|
|
||||||
Environment* env) {
|
|
||||||
auto& state = BindingData::Get(env);
|
|
||||||
auto tmpl = state.http3application_constructor_template();
|
|
||||||
if (tmpl.IsEmpty()) {
|
|
||||||
auto isolate = env->isolate();
|
|
||||||
tmpl = NewFunctionTemplate(isolate, New);
|
|
||||||
tmpl->SetClassName(state.http3application_string());
|
|
||||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
|
||||||
state.set_http3application_constructor_template(tmpl);
|
|
||||||
}
|
|
||||||
return tmpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Http3Application::InitPerIsolate(IsolateData* isolate_data,
|
void Http3Application::InitPerIsolate(IsolateData* isolate_data,
|
||||||
Local<ObjectTemplate> target) {
|
Local<ObjectTemplate> target) {
|
||||||
|
|
@ -73,17 +57,11 @@ Http3Application::Http3Application(Environment* env,
|
||||||
MakeWeak();
|
MakeWeak();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Http3Application::New(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD_IMPL(Http3Application::New) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
CHECK(args.IsConstructCall());
|
CHECK(args.IsConstructCall());
|
||||||
|
|
||||||
Local<Object> obj;
|
JS_NEW_INSTANCE(env, obj);
|
||||||
if (!GetConstructorTemplate(env)
|
|
||||||
->InstanceTemplate()
|
|
||||||
->NewInstance(env->context())
|
|
||||||
.ToLocal(&obj)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::Application::Options options;
|
Session::Application::Options options;
|
||||||
if (!args[0]->IsUndefined() &&
|
if (!args[0]->IsUndefined() &&
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,8 @@ namespace node::quic {
|
||||||
// Provides an implementation of the HTTP/3 Application implementation
|
// Provides an implementation of the HTTP/3 Application implementation
|
||||||
class Http3Application final : public Session::ApplicationProvider {
|
class Http3Application final : public Session::ApplicationProvider {
|
||||||
public:
|
public:
|
||||||
static bool HasInstance(Environment* env, v8::Local<v8::Value> value);
|
JS_CONSTRUCTOR(Http3Application);
|
||||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
JS_BINDING_INIT_BOILERPLATE();
|
||||||
Environment* env);
|
|
||||||
static void InitPerIsolate(IsolateData* isolate_data,
|
|
||||||
v8::Local<v8::ObjectTemplate> target);
|
|
||||||
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target);
|
|
||||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
|
|
||||||
|
|
||||||
Http3Application(Environment* env,
|
Http3Application(Environment* env,
|
||||||
v8::Local<v8::Object> object,
|
v8::Local<v8::Object> object,
|
||||||
|
|
@ -32,7 +27,7 @@ class Http3Application final : public Session::ApplicationProvider {
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
JS_METHOD(New);
|
||||||
|
|
||||||
Session::Application_Options options_;
|
Session::Application_Options options_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -20,29 +20,15 @@ using v8::Object;
|
||||||
|
|
||||||
namespace quic {
|
namespace quic {
|
||||||
|
|
||||||
Local<FunctionTemplate> LogStream::GetConstructorTemplate(Environment* env) {
|
JS_CONSTRUCTOR_IMPL(LogStream, logstream_constructor_template, {
|
||||||
auto& state = BindingData::Get(env);
|
tmpl = FunctionTemplate::New(env->isolate());
|
||||||
auto tmpl = state.logstream_constructor_template();
|
JS_INHERIT(AsyncWrap);
|
||||||
if (tmpl.IsEmpty()) {
|
JS_CLASS_FIELDS(logstream, StreamBase::kInternalFieldCount);
|
||||||
tmpl = FunctionTemplate::New(env->isolate());
|
StreamBase::AddMethods(env, tmpl);
|
||||||
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
|
})
|
||||||
tmpl->InstanceTemplate()->SetInternalFieldCount(
|
|
||||||
StreamBase::kInternalFieldCount);
|
|
||||||
tmpl->SetClassName(state.logstream_string());
|
|
||||||
StreamBase::AddMethods(env, tmpl);
|
|
||||||
state.set_logstream_constructor_template(tmpl);
|
|
||||||
}
|
|
||||||
return tmpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseObjectPtr<LogStream> LogStream::Create(Environment* env) {
|
BaseObjectPtr<LogStream> LogStream::Create(Environment* env) {
|
||||||
Local<Object> obj;
|
JS_NEW_INSTANCE_OR_RETURN(env, obj, nullptr);
|
||||||
if (!GetConstructorTemplate(env)
|
|
||||||
->InstanceTemplate()
|
|
||||||
->NewInstance(env->context())
|
|
||||||
.ToLocal(&obj)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return MakeDetachedBaseObject<LogStream>(env, obj);
|
return MakeDetachedBaseObject<LogStream>(env, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <stream_base.h>
|
#include <stream_base.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include "defs.h"
|
||||||
|
|
||||||
namespace node::quic {
|
namespace node::quic {
|
||||||
|
|
||||||
|
|
@ -14,8 +15,7 @@ namespace node::quic {
|
||||||
// and Keylog diagnostic data (one instance for each).
|
// and Keylog diagnostic data (one instance for each).
|
||||||
class LogStream final : public AsyncWrap, public StreamBase {
|
class LogStream final : public AsyncWrap, public StreamBase {
|
||||||
public:
|
public:
|
||||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
JS_CONSTRUCTOR(LogStream);
|
||||||
Environment* env);
|
|
||||||
|
|
||||||
static BaseObjectPtr<LogStream> Create(Environment* env);
|
static BaseObjectPtr<LogStream> Create(Environment* env);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
using v8::FunctionTemplate;
|
|
||||||
using v8::Local;
|
using v8::Local;
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
|
|
||||||
|
|
@ -97,18 +96,11 @@ void Packet::Truncate(size_t len) {
|
||||||
data_->data_.SetLength(len);
|
data_->data_.SetLength(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<FunctionTemplate> Packet::GetConstructorTemplate(Environment* env) {
|
JS_CONSTRUCTOR_IMPL(Packet, packet_constructor_template, {
|
||||||
auto& state = BindingData::Get(env);
|
JS_ILLEGAL_CONSTRUCTOR();
|
||||||
Local<FunctionTemplate> tmpl = state.packet_constructor_template();
|
JS_INHERIT(ReqWrap<uv_udp_send_t>);
|
||||||
if (tmpl.IsEmpty()) {
|
JS_CLASS(packetwrap);
|
||||||
tmpl = NewFunctionTemplate(env->isolate(), IllegalConstructor);
|
})
|
||||||
tmpl->Inherit(ReqWrap<uv_udp_send_t>::GetConstructorTemplate(env));
|
|
||||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
|
||||||
tmpl->SetClassName(state.packetwrap_string());
|
|
||||||
state.set_packet_constructor_template(tmpl);
|
|
||||||
}
|
|
||||||
return tmpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseObjectPtr<Packet> Packet::Create(Environment* env,
|
BaseObjectPtr<Packet> Packet::Create(Environment* env,
|
||||||
Listener* listener,
|
Listener* listener,
|
||||||
|
|
@ -116,14 +108,7 @@ BaseObjectPtr<Packet> Packet::Create(Environment* env,
|
||||||
size_t length,
|
size_t length,
|
||||||
const char* diagnostic_label) {
|
const char* diagnostic_label) {
|
||||||
if (BindingData::Get(env).packet_freelist.empty()) {
|
if (BindingData::Get(env).packet_freelist.empty()) {
|
||||||
Local<Object> obj;
|
JS_NEW_INSTANCE_OR_RETURN(env, obj, {});
|
||||||
if (!GetConstructorTemplate(env)
|
|
||||||
->InstanceTemplate()
|
|
||||||
->NewInstance(env->context())
|
|
||||||
.ToLocal(&obj)) [[unlikely]] {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return MakeBaseObject<Packet>(
|
return MakeBaseObject<Packet>(
|
||||||
env, listener, obj, destination, length, diagnostic_label);
|
env, listener, obj, destination, length, diagnostic_label);
|
||||||
}
|
}
|
||||||
|
|
@ -137,14 +122,7 @@ BaseObjectPtr<Packet> Packet::Create(Environment* env,
|
||||||
BaseObjectPtr<Packet> Packet::Clone() const {
|
BaseObjectPtr<Packet> Packet::Clone() const {
|
||||||
auto& binding = BindingData::Get(env());
|
auto& binding = BindingData::Get(env());
|
||||||
if (binding.packet_freelist.empty()) {
|
if (binding.packet_freelist.empty()) {
|
||||||
Local<Object> obj;
|
JS_NEW_INSTANCE_OR_RETURN(env(), obj, {});
|
||||||
if (!GetConstructorTemplate(env())
|
|
||||||
->InstanceTemplate()
|
|
||||||
->NewInstance(env()->context())
|
|
||||||
.ToLocal(&obj)) [[unlikely]] {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return MakeBaseObject<Packet>(env(), listener_, obj, destination_, data_);
|
return MakeBaseObject<Packet>(env(), listener_, obj, destination_, data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,7 @@ class Packet final : public ReqWrap<uv_udp_send_t> {
|
||||||
struct Data;
|
struct Data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
JS_CONSTRUCTOR(Packet);
|
||||||
Environment* env);
|
|
||||||
|
|
||||||
class Listener {
|
class Listener {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,9 @@
|
||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
using v8::Array;
|
using v8::Array;
|
||||||
using v8::ArrayBuffer;
|
|
||||||
using v8::ArrayBufferView;
|
using v8::ArrayBufferView;
|
||||||
using v8::BackingStoreInitializationMode;
|
|
||||||
using v8::BigInt;
|
using v8::BigInt;
|
||||||
using v8::Boolean;
|
using v8::Boolean;
|
||||||
using v8::FunctionCallbackInfo;
|
|
||||||
using v8::FunctionTemplate;
|
|
||||||
using v8::HandleScope;
|
using v8::HandleScope;
|
||||||
using v8::Int32;
|
using v8::Int32;
|
||||||
using v8::Integer;
|
using v8::Integer;
|
||||||
|
|
@ -55,9 +51,7 @@ using v8::MaybeLocal;
|
||||||
using v8::Nothing;
|
using v8::Nothing;
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
using v8::ObjectTemplate;
|
using v8::ObjectTemplate;
|
||||||
using v8::PropertyAttribute;
|
|
||||||
using v8::String;
|
using v8::String;
|
||||||
using v8::Uint32;
|
|
||||||
using v8::Undefined;
|
using v8::Undefined;
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
||||||
|
|
@ -319,7 +313,7 @@ bool SetOption(Environment* env,
|
||||||
"The cc_algorithm option is invalid");
|
"The cc_algorithm option is invalid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
algo = static_cast<ngtcp2_cc_algo>(num->Value());
|
algo = FromV8Value<ngtcp2_cc_algo>(num);
|
||||||
}
|
}
|
||||||
options->*member = algo;
|
options->*member = algo;
|
||||||
}
|
}
|
||||||
|
|
@ -653,7 +647,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
|
|
||||||
// JavaScript APIs
|
// JavaScript APIs
|
||||||
|
|
||||||
static void Destroy(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(Destroy) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -663,7 +657,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
session->Destroy();
|
session->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetRemoteAddress(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(GetRemoteAddress) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -678,7 +672,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
->object());
|
->object());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetCertificate(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(GetCertificate) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -692,7 +686,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
args.GetReturnValue().Set(ret);
|
args.GetReturnValue().Set(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetEphemeralKeyInfo(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(GetEphemeralKeyInfo) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -707,7 +701,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
args.GetReturnValue().Set(ret);
|
args.GetReturnValue().Set(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetPeerCertificate(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(GetPeerCertificate) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -721,7 +715,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
args.GetReturnValue().Set(ret);
|
args.GetReturnValue().Set(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GracefulClose(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(GracefulClose) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -733,7 +727,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
session->Close(CloseMethod::GRACEFUL);
|
session->Close(CloseMethod::GRACEFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SilentClose(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(SilentClose) {
|
||||||
// This is exposed for testing purposes only!
|
// This is exposed for testing purposes only!
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
|
|
@ -746,7 +740,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
session->Close(CloseMethod::SILENT);
|
session->Close(CloseMethod::SILENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UpdateKey(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(UpdateKey) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -763,7 +757,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
args.GetReturnValue().Set(session->tls_session().InitiateKeyUpdate());
|
args.GetReturnValue().Set(session->tls_session().InitiateKeyUpdate());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OpenStream(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(OpenStream) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -782,7 +776,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
SendPendingDataScope send_scope(session);
|
SendPendingDataScope send_scope(session);
|
||||||
auto direction = static_cast<Direction>(args[0].As<Uint32>()->Value());
|
auto direction = FromV8Value<Direction>(args[0]);
|
||||||
Local<Object> stream;
|
Local<Object> stream;
|
||||||
if (session->OpenStream(direction, std::move(data_source)).ToLocal(&stream))
|
if (session->OpenStream(direction, std::move(data_source)).ToLocal(&stream))
|
||||||
[[likely]] {
|
[[likely]] {
|
||||||
|
|
@ -790,7 +784,7 @@ struct Session::Impl final : public MemoryRetainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SendDatagram(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(SendDatagram) {
|
||||||
auto env = Environment::GetCurrent(args);
|
auto env = Environment::GetCurrent(args);
|
||||||
Session* session;
|
Session* session;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||||
|
|
@ -1276,23 +1270,12 @@ Session::SendPendingDataScope::~SendPendingDataScope() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
bool Session::HasInstance(Environment* env, Local<Value> value) {
|
|
||||||
return GetConstructorTemplate(env)->HasInstance(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseObjectPtr<Session> Session::Create(
|
BaseObjectPtr<Session> Session::Create(
|
||||||
Endpoint* endpoint,
|
Endpoint* endpoint,
|
||||||
const Config& config,
|
const Config& config,
|
||||||
TLSContext* tls_context,
|
TLSContext* tls_context,
|
||||||
const std::optional<SessionTicket>& ticket) {
|
const std::optional<SessionTicket>& ticket) {
|
||||||
Local<Object> obj;
|
JS_NEW_INSTANCE_OR_RETURN(endpoint->env(), obj, {});
|
||||||
if (!GetConstructorTemplate(endpoint->env())
|
|
||||||
->InstanceTemplate()
|
|
||||||
->NewInstance(endpoint->env()->context())
|
|
||||||
.ToLocal(&obj)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return MakeDetachedBaseObject<Session>(
|
return MakeDetachedBaseObject<Session>(
|
||||||
endpoint, obj, config, tls_context, ticket);
|
endpoint, obj, config, tls_context, ticket);
|
||||||
}
|
}
|
||||||
|
|
@ -1311,27 +1294,23 @@ Session::Session(Endpoint* endpoint,
|
||||||
DCHECK(impl_);
|
DCHECK(impl_);
|
||||||
MakeWeak();
|
MakeWeak();
|
||||||
Debug(this, "Session created.");
|
Debug(this, "Session created.");
|
||||||
|
|
||||||
const auto defineProperty = [&](auto name, auto value) {
|
|
||||||
object
|
|
||||||
->DefineOwnProperty(
|
|
||||||
env()->context(), name, value, PropertyAttribute::ReadOnly)
|
|
||||||
.Check();
|
|
||||||
};
|
|
||||||
|
|
||||||
defineProperty(env()->state_string(), impl_->state_.GetArrayBuffer());
|
|
||||||
defineProperty(env()->stats_string(), impl_->stats_.GetArrayBuffer());
|
|
||||||
|
|
||||||
auto& binding = BindingData::Get(env());
|
auto& binding = BindingData::Get(env());
|
||||||
|
|
||||||
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
|
env(), object, env()->stats_string(), impl_->stats_.GetArrayBuffer());
|
||||||
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
|
env(), object, env()->state_string(), impl_->state_.GetArrayBuffer());
|
||||||
|
|
||||||
if (config.options.qlog) [[unlikely]] {
|
if (config.options.qlog) [[unlikely]] {
|
||||||
qlog_stream_ = LogStream::Create(env());
|
qlog_stream_ = LogStream::Create(env());
|
||||||
defineProperty(binding.qlog_string(), qlog_stream_->object());
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
|
env(), object, binding.qlog_string(), qlog_stream_->object());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.options.tls_options.keylog) [[unlikely]] {
|
if (config.options.tls_options.keylog) [[unlikely]] {
|
||||||
keylog_stream_ = LogStream::Create(env());
|
keylog_stream_ = LogStream::Create(env());
|
||||||
defineProperty(binding.keylog_string(), keylog_stream_->object());
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
|
env(), object, binding.keylog_string(), keylog_stream_->object());
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateDataStats();
|
UpdateDataStats();
|
||||||
|
|
@ -2348,10 +2327,7 @@ void Session::DatagramReceived(const uint8_t* data,
|
||||||
Debug(this, "Session is receiving datagram of size %zu", datalen);
|
Debug(this, "Session is receiving datagram of size %zu", datalen);
|
||||||
auto& stats_ = impl_->stats_;
|
auto& stats_ = impl_->stats_;
|
||||||
STAT_INCREMENT(Stats, datagrams_received);
|
STAT_INCREMENT(Stats, datagrams_received);
|
||||||
auto backing = ArrayBuffer::NewBackingStore(
|
JS_TRY_ALLOCATE_BACKING(env(), backing, datalen)
|
||||||
env()->isolate(),
|
|
||||||
datalen,
|
|
||||||
BackingStoreInitializationMode::kUninitialized);
|
|
||||||
memcpy(backing->Data(), data, datalen);
|
memcpy(backing->Data(), data, datalen);
|
||||||
EmitDatagram(Store(std::move(backing), datalen), flag);
|
EmitDatagram(Store(std::move(backing), datalen), flag);
|
||||||
}
|
}
|
||||||
|
|
@ -2777,28 +2753,19 @@ void Session::EmitKeylog(const char* line) {
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
Local<FunctionTemplate> Session::GetConstructorTemplate(Environment* env) {
|
|
||||||
auto& state = BindingData::Get(env);
|
|
||||||
auto tmpl = state.session_constructor_template();
|
|
||||||
if (tmpl.IsEmpty()) {
|
|
||||||
auto isolate = env->isolate();
|
|
||||||
tmpl = NewFunctionTemplate(isolate, IllegalConstructor);
|
|
||||||
tmpl->SetClassName(state.session_string());
|
|
||||||
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
|
|
||||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
|
||||||
#define V(name, key, no_side_effect) \
|
#define V(name, key, no_side_effect) \
|
||||||
if (no_side_effect) { \
|
if (no_side_effect) { \
|
||||||
SetProtoMethodNoSideEffect(isolate, tmpl, #key, Impl::name); \
|
SetProtoMethodNoSideEffect(env->isolate(), tmpl, #key, Impl::name); \
|
||||||
} else { \
|
} else { \
|
||||||
SetProtoMethod(isolate, tmpl, #key, Impl::name); \
|
SetProtoMethod(env->isolate(), tmpl, #key, Impl::name); \
|
||||||
}
|
}
|
||||||
SESSION_JS_METHODS(V)
|
JS_CONSTRUCTOR_IMPL(Session, session_constructor_template, {
|
||||||
|
JS_ILLEGAL_CONSTRUCTOR();
|
||||||
|
JS_INHERIT(AsyncWrap);
|
||||||
|
JS_CLASS(session);
|
||||||
|
SESSION_JS_METHODS(V)
|
||||||
|
})
|
||||||
#undef V
|
#undef V
|
||||||
state.set_session_constructor_template(tmpl);
|
|
||||||
}
|
|
||||||
return tmpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Session::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
void Session::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||||
#define V(name, _, __) registry->Register(Impl::name);
|
#define V(name, _, __) registry->Register(Impl::name);
|
||||||
|
|
@ -2823,9 +2790,9 @@ void Session::InitPerContext(Realm* realm, Local<Object> target) {
|
||||||
PreferredAddress::Initialize(realm->env(), target);
|
PreferredAddress::Initialize(realm->env(), target);
|
||||||
|
|
||||||
static constexpr auto STREAM_DIRECTION_BIDIRECTIONAL =
|
static constexpr auto STREAM_DIRECTION_BIDIRECTIONAL =
|
||||||
static_cast<uint32_t>(Direction::BIDIRECTIONAL);
|
static_cast<uint8_t>(Direction::BIDIRECTIONAL);
|
||||||
static constexpr auto STREAM_DIRECTION_UNIDIRECTIONAL =
|
static constexpr auto STREAM_DIRECTION_UNIDIRECTIONAL =
|
||||||
static_cast<uint32_t>(Direction::UNIDIRECTIONAL);
|
static_cast<uint8_t>(Direction::UNIDIRECTIONAL);
|
||||||
static constexpr auto QUIC_PROTO_MAX = NGTCP2_PROTO_VER_MAX;
|
static constexpr auto QUIC_PROTO_MAX = NGTCP2_PROTO_VER_MAX;
|
||||||
static constexpr auto QUIC_PROTO_MIN = NGTCP2_PROTO_VER_MIN;
|
static constexpr auto QUIC_PROTO_MIN = NGTCP2_PROTO_VER_MIN;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -250,13 +250,8 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source {
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool HasInstance(Environment* env, v8::Local<v8::Value> value);
|
JS_CONSTRUCTOR(Session);
|
||||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
JS_BINDING_INIT_BOILERPLATE();
|
||||||
Environment* env);
|
|
||||||
static void InitPerIsolate(IsolateData* isolate_data,
|
|
||||||
v8::Local<v8::ObjectTemplate> target);
|
|
||||||
static void InitPerContext(Realm* env, v8::Local<v8::Object> target);
|
|
||||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
|
|
||||||
|
|
||||||
static BaseObjectPtr<Session> Create(
|
static BaseObjectPtr<Session> Create(
|
||||||
Endpoint* endpoint,
|
Endpoint* endpoint,
|
||||||
|
|
@ -334,7 +329,7 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source {
|
||||||
// A non-const variation to allow certain modifications.
|
// A non-const variation to allow certain modifications.
|
||||||
Config& config();
|
Config& config();
|
||||||
|
|
||||||
enum class CreateStreamOption {
|
enum class CreateStreamOption : uint8_t {
|
||||||
NOTIFY,
|
NOTIFY,
|
||||||
DO_NOT_NOTIFY,
|
DO_NOT_NOTIFY,
|
||||||
};
|
};
|
||||||
|
|
@ -423,7 +418,7 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source {
|
||||||
// defined there to manage it.
|
// defined there to manage it.
|
||||||
void set_wrapped();
|
void set_wrapped();
|
||||||
|
|
||||||
enum class CloseMethod {
|
enum class CloseMethod : uint8_t {
|
||||||
// Immediate close with a roundtrip through JavaScript, causing all
|
// Immediate close with a roundtrip through JavaScript, causing all
|
||||||
// currently opened streams to be closed. An attempt will be made to
|
// currently opened streams to be closed. An attempt will be made to
|
||||||
// send a CONNECTION_CLOSE frame to the peer. If closing while within
|
// send a CONNECTION_CLOSE frame to the peer. If closing while within
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ class SessionTicket final : public MemoryRetainer {
|
||||||
// server-side of the Session::Application that sets it.
|
// server-side of the Session::Application that sets it.
|
||||||
class SessionTicket::AppData final {
|
class SessionTicket::AppData final {
|
||||||
public:
|
public:
|
||||||
enum class Status {
|
enum class Status : uint8_t {
|
||||||
TICKET_IGNORE = SSL_TICKET_RETURN_IGNORE,
|
TICKET_IGNORE = SSL_TICKET_RETURN_IGNORE,
|
||||||
TICKET_IGNORE_RENEW = SSL_TICKET_RETURN_IGNORE_RENEW,
|
TICKET_IGNORE_RENEW = SSL_TICKET_RETURN_IGNORE_RENEW,
|
||||||
TICKET_USE = SSL_TICKET_RETURN_USE,
|
TICKET_USE = SSL_TICKET_RETURN_USE,
|
||||||
|
|
@ -83,7 +83,7 @@ class SessionTicket::AppData final {
|
||||||
// Session.
|
// Session.
|
||||||
class Source {
|
class Source {
|
||||||
public:
|
public:
|
||||||
enum class Flag { STATUS_NONE, STATUS_RENEW };
|
enum class Flag : uint8_t { STATUS_NONE, STATUS_RENEW };
|
||||||
|
|
||||||
// Collect application data into the given AppData instance.
|
// Collect application data into the given AppData instance.
|
||||||
virtual void CollectSessionTicketAppData(AppData* app_data) const = 0;
|
virtual void CollectSessionTicketAppData(AppData* app_data) const = 0;
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,7 @@ namespace node {
|
||||||
using v8::Array;
|
using v8::Array;
|
||||||
using v8::ArrayBuffer;
|
using v8::ArrayBuffer;
|
||||||
using v8::ArrayBufferView;
|
using v8::ArrayBufferView;
|
||||||
using v8::BackingStoreInitializationMode;
|
|
||||||
using v8::BigInt;
|
using v8::BigInt;
|
||||||
using v8::FunctionCallbackInfo;
|
|
||||||
using v8::FunctionTemplate;
|
|
||||||
using v8::Global;
|
using v8::Global;
|
||||||
using v8::Integer;
|
using v8::Integer;
|
||||||
using v8::Just;
|
using v8::Just;
|
||||||
|
|
@ -32,9 +29,7 @@ using v8::Maybe;
|
||||||
using v8::Nothing;
|
using v8::Nothing;
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
using v8::ObjectTemplate;
|
using v8::ObjectTemplate;
|
||||||
using v8::PropertyAttribute;
|
|
||||||
using v8::SharedArrayBuffer;
|
using v8::SharedArrayBuffer;
|
||||||
using v8::Uint32;
|
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
||||||
namespace quic {
|
namespace quic {
|
||||||
|
|
@ -185,7 +180,7 @@ Maybe<std::shared_ptr<DataQueue>> Stream::GetDataQueueFromSource(
|
||||||
// Stream object.
|
// Stream object.
|
||||||
struct Stream::Impl {
|
struct Stream::Impl {
|
||||||
// Attaches an outbound data source to the stream.
|
// Attaches an outbound data source to the stream.
|
||||||
static void AttachSource(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(AttachSource) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
|
|
||||||
std::shared_ptr<DataQueue> dataqueue;
|
std::shared_ptr<DataQueue> dataqueue;
|
||||||
|
|
@ -196,7 +191,7 @@ struct Stream::Impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Destroy(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(Destroy) {
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||||
if (args.Length() > 1) {
|
if (args.Length() > 1) {
|
||||||
|
|
@ -209,17 +204,16 @@ struct Stream::Impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SendHeaders(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(SendHeaders) {
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||||
CHECK(args[0]->IsUint32()); // Kind
|
CHECK(args[0]->IsUint32()); // Kind
|
||||||
CHECK(args[1]->IsArray()); // Headers
|
CHECK(args[1]->IsArray()); // Headers
|
||||||
CHECK(args[2]->IsUint32()); // Flags
|
CHECK(args[2]->IsUint32()); // Flags
|
||||||
|
|
||||||
HeadersKind kind = static_cast<HeadersKind>(args[0].As<Uint32>()->Value());
|
HeadersKind kind = FromV8Value<HeadersKind>(args[0]);
|
||||||
Local<Array> headers = args[1].As<Array>();
|
Local<Array> headers = args[1].As<Array>();
|
||||||
HeadersFlags flags =
|
HeadersFlags flags = FromV8Value<HeadersFlags>(args[2]);
|
||||||
static_cast<HeadersFlags>(args[2].As<Uint32>()->Value());
|
|
||||||
|
|
||||||
// If the stream is pending, the headers will be queued until the
|
// If the stream is pending, the headers will be queued until the
|
||||||
// stream is opened, at which time the queued header block will be
|
// stream is opened, at which time the queued header block will be
|
||||||
|
|
@ -236,7 +230,7 @@ struct Stream::Impl {
|
||||||
// Tells the peer to stop sending data for this stream. This has the effect
|
// Tells the peer to stop sending data for this stream. This has the effect
|
||||||
// of shutting down the readable side of the stream for this peer. Any data
|
// of shutting down the readable side of the stream for this peer. Any data
|
||||||
// that has already been received is still readable.
|
// that has already been received is still readable.
|
||||||
static void StopSending(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(StopSending) {
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||||
uint64_t code = 0;
|
uint64_t code = 0;
|
||||||
|
|
@ -261,7 +255,7 @@ struct Stream::Impl {
|
||||||
// more data for this stream. This has the effect of shutting down the
|
// more data for this stream. This has the effect of shutting down the
|
||||||
// writable side of the stream for this peer. Any data that is held in the
|
// writable side of the stream for this peer. Any data that is held in the
|
||||||
// outbound queue will be dropped. The stream may still be readable.
|
// outbound queue will be dropped. The stream may still be readable.
|
||||||
static void ResetStream(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(ResetStream) {
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||||
uint64_t code = 0;
|
uint64_t code = 0;
|
||||||
|
|
@ -288,16 +282,14 @@ struct Stream::Impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetPriority(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(SetPriority) {
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||||
CHECK(args[0]->IsUint32()); // Priority
|
CHECK(args[0]->IsUint32()); // Priority
|
||||||
CHECK(args[1]->IsUint32()); // Priority flag
|
CHECK(args[1]->IsUint32()); // Priority flag
|
||||||
|
|
||||||
StreamPriority priority =
|
StreamPriority priority = FromV8Value<StreamPriority>(args[0]);
|
||||||
static_cast<StreamPriority>(args[0].As<Uint32>()->Value());
|
StreamPriorityFlags flags = FromV8Value<StreamPriorityFlags>(args[1]);
|
||||||
StreamPriorityFlags flags =
|
|
||||||
static_cast<StreamPriorityFlags>(args[1].As<Uint32>()->Value());
|
|
||||||
|
|
||||||
if (stream->is_pending()) {
|
if (stream->is_pending()) {
|
||||||
stream->pending_priority_ = PendingPriority{
|
stream->pending_priority_ = PendingPriority{
|
||||||
|
|
@ -310,7 +302,7 @@ struct Stream::Impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetPriority(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(GetPriority) {
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||||
|
|
||||||
|
|
@ -323,7 +315,7 @@ struct Stream::Impl {
|
||||||
args.GetReturnValue().Set(static_cast<uint32_t>(priority));
|
args.GetReturnValue().Set(static_cast<uint32_t>(priority));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetReader(const FunctionCallbackInfo<Value>& args) {
|
JS_METHOD(GetReader) {
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||||
BaseObjectPtr<Blob::Reader> reader = stream->get_reader();
|
BaseObjectPtr<Blob::Reader> reader = stream->get_reader();
|
||||||
|
|
@ -697,33 +689,19 @@ class Stream::Outbound final : public MemoryRetainer {
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
bool Stream::HasInstance(Environment* env, Local<Value> value) {
|
|
||||||
return GetConstructorTemplate(env)->HasInstance(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<FunctionTemplate> Stream::GetConstructorTemplate(Environment* env) {
|
|
||||||
auto& state = BindingData::Get(env);
|
|
||||||
auto tmpl = state.stream_constructor_template();
|
|
||||||
if (tmpl.IsEmpty()) {
|
|
||||||
auto isolate = env->isolate();
|
|
||||||
tmpl = NewFunctionTemplate(isolate, IllegalConstructor);
|
|
||||||
tmpl->SetClassName(state.stream_string());
|
|
||||||
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
|
|
||||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
|
||||||
#define V(name, key, no_side_effect) \
|
#define V(name, key, no_side_effect) \
|
||||||
if (no_side_effect) { \
|
if (no_side_effect) { \
|
||||||
SetProtoMethodNoSideEffect(isolate, tmpl, #key, Impl::name); \
|
SetProtoMethodNoSideEffect(env->isolate(), tmpl, #key, Impl::name); \
|
||||||
} else { \
|
} else { \
|
||||||
SetProtoMethod(isolate, tmpl, #key, Impl::name); \
|
SetProtoMethod(env->isolate(), tmpl, #key, Impl::name); \
|
||||||
}
|
}
|
||||||
|
JS_CONSTRUCTOR_IMPL(Stream, stream_constructor_template, {
|
||||||
STREAM_JS_METHODS(V)
|
JS_ILLEGAL_CONSTRUCTOR();
|
||||||
|
JS_INHERIT(AsyncWrap);
|
||||||
|
JS_CLASS(stream);
|
||||||
|
STREAM_JS_METHODS(V)
|
||||||
|
})
|
||||||
#undef V
|
#undef V
|
||||||
state.set_stream_constructor_template(tmpl);
|
|
||||||
}
|
|
||||||
return tmpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stream::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
void Stream::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||||
#define V(name, _, __) registry->Register(Impl::name);
|
#define V(name, _, __) registry->Register(Impl::name);
|
||||||
|
|
@ -755,16 +733,16 @@ void Stream::InitPerContext(Realm* realm, Local<Object> target) {
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
constexpr int QUIC_STREAM_HEADERS_KIND_HINTS =
|
constexpr int QUIC_STREAM_HEADERS_KIND_HINTS =
|
||||||
static_cast<int>(HeadersKind::HINTS);
|
static_cast<uint8_t>(HeadersKind::HINTS);
|
||||||
constexpr int QUIC_STREAM_HEADERS_KIND_INITIAL =
|
constexpr int QUIC_STREAM_HEADERS_KIND_INITIAL =
|
||||||
static_cast<int>(HeadersKind::INITIAL);
|
static_cast<uint8_t>(HeadersKind::INITIAL);
|
||||||
constexpr int QUIC_STREAM_HEADERS_KIND_TRAILING =
|
constexpr int QUIC_STREAM_HEADERS_KIND_TRAILING =
|
||||||
static_cast<int>(HeadersKind::TRAILING);
|
static_cast<uint8_t>(HeadersKind::TRAILING);
|
||||||
|
|
||||||
constexpr int QUIC_STREAM_HEADERS_FLAGS_NONE =
|
constexpr int QUIC_STREAM_HEADERS_FLAGS_NONE =
|
||||||
static_cast<int>(HeadersFlags::NONE);
|
static_cast<uint8_t>(HeadersFlags::NONE);
|
||||||
constexpr int QUIC_STREAM_HEADERS_FLAGS_TERMINAL =
|
constexpr int QUIC_STREAM_HEADERS_FLAGS_TERMINAL =
|
||||||
static_cast<int>(HeadersFlags::TERMINAL);
|
static_cast<uint8_t>(HeadersFlags::TERMINAL);
|
||||||
|
|
||||||
NODE_DEFINE_CONSTANT(target, QUIC_STREAM_HEADERS_KIND_HINTS);
|
NODE_DEFINE_CONSTANT(target, QUIC_STREAM_HEADERS_KIND_HINTS);
|
||||||
NODE_DEFINE_CONSTANT(target, QUIC_STREAM_HEADERS_KIND_INITIAL);
|
NODE_DEFINE_CONSTANT(target, QUIC_STREAM_HEADERS_KIND_INITIAL);
|
||||||
|
|
@ -784,14 +762,7 @@ BaseObjectPtr<Stream> Stream::Create(Session* session,
|
||||||
std::shared_ptr<DataQueue> source) {
|
std::shared_ptr<DataQueue> source) {
|
||||||
DCHECK_GE(id, 0);
|
DCHECK_GE(id, 0);
|
||||||
DCHECK_NOT_NULL(session);
|
DCHECK_NOT_NULL(session);
|
||||||
Local<Object> obj;
|
JS_NEW_INSTANCE_OR_RETURN(session->env(), obj, {});
|
||||||
if (!GetConstructorTemplate(session->env())
|
|
||||||
->InstanceTemplate()
|
|
||||||
->NewInstance(session->env()->context())
|
|
||||||
.ToLocal(&obj)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return MakeDetachedBaseObject<Stream>(
|
return MakeDetachedBaseObject<Stream>(
|
||||||
BaseObjectWeakPtr<Session>(session), obj, id, std::move(source));
|
BaseObjectWeakPtr<Session>(session), obj, id, std::move(source));
|
||||||
}
|
}
|
||||||
|
|
@ -800,14 +771,7 @@ BaseObjectPtr<Stream> Stream::Create(Session* session,
|
||||||
Direction direction,
|
Direction direction,
|
||||||
std::shared_ptr<DataQueue> source) {
|
std::shared_ptr<DataQueue> source) {
|
||||||
DCHECK_NOT_NULL(session);
|
DCHECK_NOT_NULL(session);
|
||||||
Local<Object> obj;
|
JS_NEW_INSTANCE_OR_RETURN(session->env(), obj, {});
|
||||||
if (!GetConstructorTemplate(session->env())
|
|
||||||
->InstanceTemplate()
|
|
||||||
->NewInstance(session->env()->context())
|
|
||||||
.ToLocal(&obj)) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return MakeBaseObject<Stream>(
|
return MakeBaseObject<Stream>(
|
||||||
BaseObjectWeakPtr<Session>(session), obj, direction, std::move(source));
|
BaseObjectWeakPtr<Session>(session), obj, direction, std::move(source));
|
||||||
}
|
}
|
||||||
|
|
@ -829,15 +793,10 @@ Stream::Stream(BaseObjectWeakPtr<Session> session,
|
||||||
// inbound queue so that we can update the stream flow control.
|
// inbound queue so that we can update the stream flow control.
|
||||||
inbound_->addBackpressureListener(this);
|
inbound_->addBackpressureListener(this);
|
||||||
|
|
||||||
const auto defineProperty = [&](auto name, auto value) {
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
object
|
env(), object, env()->state_string(), state_.GetArrayBuffer());
|
||||||
->DefineOwnProperty(
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
env()->context(), name, value, PropertyAttribute::ReadOnly)
|
env(), object, env()->stats_string(), stats_.GetArrayBuffer());
|
||||||
.Check();
|
|
||||||
};
|
|
||||||
|
|
||||||
defineProperty(env()->state_string(), state_.GetArrayBuffer());
|
|
||||||
defineProperty(env()->stats_string(), stats_.GetArrayBuffer());
|
|
||||||
|
|
||||||
set_outbound(std::move(source));
|
set_outbound(std::move(source));
|
||||||
|
|
||||||
|
|
@ -866,15 +825,10 @@ Stream::Stream(BaseObjectWeakPtr<Session> session,
|
||||||
// inbound queue so that we can update the stream flow control.
|
// inbound queue so that we can update the stream flow control.
|
||||||
inbound_->addBackpressureListener(this);
|
inbound_->addBackpressureListener(this);
|
||||||
|
|
||||||
const auto defineProperty = [&](auto name, auto value) {
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
object
|
env(), object, env()->state_string(), state_.GetArrayBuffer());
|
||||||
->DefineOwnProperty(
|
JS_DEFINE_READONLY_PROPERTY(
|
||||||
env()->context(), name, value, PropertyAttribute::ReadOnly)
|
env(), object, env()->stats_string(), stats_.GetArrayBuffer());
|
||||||
.Check();
|
|
||||||
};
|
|
||||||
|
|
||||||
defineProperty(env()->state_string(), state_.GetArrayBuffer());
|
|
||||||
defineProperty(env()->stats_string(), stats_.GetArrayBuffer());
|
|
||||||
|
|
||||||
set_outbound(std::move(source));
|
set_outbound(std::move(source));
|
||||||
|
|
||||||
|
|
@ -1203,8 +1157,7 @@ void Stream::ReceiveData(const uint8_t* data,
|
||||||
|
|
||||||
STAT_INCREMENT_N(Stats, bytes_received, len);
|
STAT_INCREMENT_N(Stats, bytes_received, len);
|
||||||
STAT_RECORD_TIMESTAMP(Stats, received_at);
|
STAT_RECORD_TIMESTAMP(Stats, received_at);
|
||||||
auto backing = ArrayBuffer::NewBackingStore(
|
JS_TRY_ALLOCATE_BACKING(env(), backing, len)
|
||||||
env()->isolate(), len, BackingStoreInitializationMode::kUninitialized);
|
|
||||||
memcpy(backing->Data(), data, len);
|
memcpy(backing->Data(), data, len);
|
||||||
inbound_->append(DataQueue::CreateInMemoryEntryFromBackingStore(
|
inbound_->append(DataQueue::CreateInMemoryEntryFromBackingStore(
|
||||||
std::move(backing), 0, len));
|
std::move(backing), 0, len));
|
||||||
|
|
|
||||||
|
|
@ -147,13 +147,8 @@ class Stream final : public AsyncWrap,
|
||||||
|
|
||||||
static Stream* From(void* stream_user_data);
|
static Stream* From(void* stream_user_data);
|
||||||
|
|
||||||
static bool HasInstance(Environment* env, v8::Local<v8::Value> value);
|
JS_CONSTRUCTOR(Stream);
|
||||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
JS_BINDING_INIT_BOILERPLATE();
|
||||||
Environment* env);
|
|
||||||
static void InitPerIsolate(IsolateData* data,
|
|
||||||
v8::Local<v8::ObjectTemplate> target);
|
|
||||||
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target);
|
|
||||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
|
|
||||||
|
|
||||||
// Creates a new non-pending stream.
|
// Creates a new non-pending stream.
|
||||||
static BaseObjectPtr<Stream> Create(
|
static BaseObjectPtr<Stream> Create(
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@ using ncrypto::SSLPointer;
|
||||||
using ncrypto::SSLSessionPointer;
|
using ncrypto::SSLSessionPointer;
|
||||||
using ncrypto::X509Pointer;
|
using ncrypto::X509Pointer;
|
||||||
using v8::ArrayBuffer;
|
using v8::ArrayBuffer;
|
||||||
using v8::BackingStoreInitializationMode;
|
|
||||||
using v8::BackingStoreOnFailureMode;
|
|
||||||
using v8::Just;
|
using v8::Just;
|
||||||
using v8::Local;
|
using v8::Local;
|
||||||
using v8::Maybe;
|
using v8::Maybe;
|
||||||
|
|
@ -361,12 +359,7 @@ int TLSContext::OnNewSession(SSL* ssl, SSL_SESSION* sess) {
|
||||||
// enough memory to allocate the backing store, then we ignore it
|
// enough memory to allocate the backing store, then we ignore it
|
||||||
// and continue without emitting the sessionticket event.
|
// and continue without emitting the sessionticket event.
|
||||||
if (size > 0 && size <= crypto::SecureContext::kMaxSessionSize) {
|
if (size > 0 && size <= crypto::SecureContext::kMaxSessionSize) {
|
||||||
auto ticket = ArrayBuffer::NewBackingStore(
|
JS_TRY_ALLOCATE_BACKING_OR_RETURN(session.env(), ticket, size, 0);
|
||||||
session.env()->isolate(),
|
|
||||||
size,
|
|
||||||
BackingStoreInitializationMode::kUninitialized,
|
|
||||||
BackingStoreOnFailureMode::kReturnNull);
|
|
||||||
if (!ticket) return 0;
|
|
||||||
auto data = reinterpret_cast<unsigned char*>(ticket->Data());
|
auto data = reinterpret_cast<unsigned char*>(ticket->Data());
|
||||||
if (i2d_SSL_SESSION(sess, &data) > 0) {
|
if (i2d_SSL_SESSION(sess, &data) > 0) {
|
||||||
session.EmitSessionTicket(Store(std::move(ticket), size));
|
session.EmitSessionTicket(Store(std::move(ticket), size));
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,6 @@
|
||||||
|
|
||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
using v8::ArrayBuffer;
|
|
||||||
using v8::BackingStoreInitializationMode;
|
|
||||||
using v8::BackingStoreOnFailureMode;
|
|
||||||
using v8::Just;
|
using v8::Just;
|
||||||
using v8::Local;
|
using v8::Local;
|
||||||
using v8::Maybe;
|
using v8::Maybe;
|
||||||
|
|
@ -195,14 +192,7 @@ Store TransportParams::Encode(Environment* env, int version) const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = ArrayBuffer::NewBackingStore(
|
JS_TRY_ALLOCATE_BACKING_OR_RETURN(env, result, size, {});
|
||||||
env->isolate(),
|
|
||||||
size,
|
|
||||||
BackingStoreInitializationMode::kUninitialized,
|
|
||||||
BackingStoreOnFailureMode::kReturnNull);
|
|
||||||
if (!result) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ret = ngtcp2_transport_params_encode_versioned(
|
auto ret = ngtcp2_transport_params_encode_versioned(
|
||||||
static_cast<uint8_t*>(result->Data()), size, version, ¶ms_);
|
static_cast<uint8_t*>(result->Data()), size, version, ¶ms_);
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,4 @@ for (const [, envVar, config] of nodeOptionsCC.matchAll(addOptionRE)) {
|
||||||
// add alias handling
|
// add alias handling
|
||||||
manPagesOptions.delete('-trace-events-enabled');
|
manPagesOptions.delete('-trace-events-enabled');
|
||||||
|
|
||||||
// TODO(@jasnell): Need to determine why the documentation for this option is not being recognized
|
|
||||||
manPagesOptions.delete('-no-experimental-quic');
|
|
||||||
|
|
||||||
assert.strictEqual(manPagesOptions.size, 0, `Man page options not documented: ${[...manPagesOptions]}`);
|
assert.strictEqual(manPagesOptions.size, 0, `Man page options not documented: ${[...manPagesOptions]}`);
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ if (!common.hasIntl) {
|
||||||
common.skip('missing Intl');
|
common.skip('missing Intl');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.config.variables.node_quic) {
|
if (!common.hasQuic) {
|
||||||
common.skip('this test assumes default configuration options');
|
common.skip('this test requires QUIC');
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,6 @@ assert(undocumented.delete('--verify-base-objects'));
|
||||||
assert(undocumented.delete('--no-verify-base-objects'));
|
assert(undocumented.delete('--no-verify-base-objects'));
|
||||||
assert(undocumented.delete('--trace-promises'));
|
assert(undocumented.delete('--trace-promises'));
|
||||||
assert(undocumented.delete('--no-trace-promises'));
|
assert(undocumented.delete('--no-trace-promises'));
|
||||||
assert(undocumented.delete('--experimental-quic'));
|
|
||||||
assert(undocumented.delete('--no-experimental-quic'));
|
|
||||||
|
|
||||||
// Remove negated versions of the flags.
|
// Remove negated versions of the flags.
|
||||||
for (const flag of undocumented) {
|
for (const flag of undocumented) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const expectedKeys = new Map([
|
||||||
['uv', ['boolean']],
|
['uv', ['boolean']],
|
||||||
['ipv6', ['boolean']],
|
['ipv6', ['boolean']],
|
||||||
['openssl_is_boringssl', ['boolean']],
|
['openssl_is_boringssl', ['boolean']],
|
||||||
['quic', ['boolean']],
|
['quic', ['boolean', 'undefined']],
|
||||||
['tls_alpn', ['boolean']],
|
['tls_alpn', ['boolean']],
|
||||||
['tls_sni', ['boolean']],
|
['tls_sni', ['boolean']],
|
||||||
['tls_ocsp', ['boolean']],
|
['tls_ocsp', ['boolean']],
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,6 @@ if (common.hasCrypto) {
|
||||||
expected_keys.push('ncrypto');
|
expected_keys.push('ncrypto');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (common.hasQuic) {
|
|
||||||
expected_keys.push('ngtcp2');
|
|
||||||
expected_keys.push('nghttp3');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (common.hasIntl) {
|
if (common.hasIntl) {
|
||||||
expected_keys.push('icu');
|
expected_keys.push('icu');
|
||||||
expected_keys.push('cldr');
|
expected_keys.push('cldr');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user