mirror of https://github.com/nodejs/node.git
quic: cleanup QuicSocketFlags, used shared state struct
Some of the flags were no longer being used. Switched to use an AliasedStruct for shared state to avoid extraneous expensive JS=>C++ calls. Removed unused QuicSocket option PR-URL: https://github.com/nodejs/node/pull/34247 Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
d08e99de24
commit
fe11f6bf7c
|
@ -1327,17 +1327,17 @@ added: REPLACEME
|
|||
-->
|
||||
|
||||
Emitted when the server busy state has been toggled using
|
||||
`quicSocket.serverBusy = true | false`. The callback is invoked with a
|
||||
single boolean argument indicating `true` if busy status is enabled,
|
||||
`false` otherwise. This event is strictly informational.
|
||||
`quicSocket.serverBusy = true | false`. The callback is invoked with no
|
||||
arguments. Use the `quicsocket.serverBusy` property to determine the
|
||||
current status. This event is strictly informational.
|
||||
|
||||
```js
|
||||
const { createQuicSocket } = require('net');
|
||||
|
||||
const socket = createQuicSocket();
|
||||
|
||||
socket.on('busy', (busy) => {
|
||||
if (busy)
|
||||
socket.on('busy', () => {
|
||||
if (socket.serverBusy)
|
||||
console.log('Server is busy');
|
||||
else
|
||||
console.log('Server is not busy');
|
||||
|
|
|
@ -12,6 +12,7 @@ assertCrypto();
|
|||
const {
|
||||
Array,
|
||||
BigInt64Array,
|
||||
Boolean,
|
||||
Error,
|
||||
Map,
|
||||
Number,
|
||||
|
@ -38,6 +39,7 @@ const {
|
|||
validateQuicEndpointOptions,
|
||||
validateCreateSecureContextOptions,
|
||||
validateQuicSocketConnectOptions,
|
||||
QuicSocketSharedState,
|
||||
QuicSessionSharedState,
|
||||
QLogStream,
|
||||
} = require('internal/quic/util');
|
||||
|
@ -269,8 +271,8 @@ function onSocketClose(err) {
|
|||
|
||||
// Called by the C++ internals when the server busy state of
|
||||
// the QuicSocket has been changed.
|
||||
function onSocketServerBusy(on) {
|
||||
this[owner_symbol][kServerBusy](on);
|
||||
function onSocketServerBusy() {
|
||||
this[owner_symbol][kServerBusy]();
|
||||
}
|
||||
|
||||
// Called by the C++ internals when a new server QuicSession has been created.
|
||||
|
@ -845,19 +847,17 @@ class QuicEndpoint {
|
|||
class QuicSocket extends EventEmitter {
|
||||
[kInternalState] = {
|
||||
alpn: undefined,
|
||||
autoClose: undefined,
|
||||
client: undefined,
|
||||
defaultEncoding: undefined,
|
||||
endpoints: new Set(),
|
||||
highWaterMark: undefined,
|
||||
listenPending: false,
|
||||
lookup: undefined,
|
||||
server: undefined,
|
||||
serverBusy: false,
|
||||
serverListening: false,
|
||||
serverSecureContext: undefined,
|
||||
sessions: new Set(),
|
||||
state: kSocketUnbound,
|
||||
statelessResetEnabled: true,
|
||||
sharedState: undefined,
|
||||
stats: undefined,
|
||||
};
|
||||
|
||||
|
@ -865,11 +865,6 @@ class QuicSocket extends EventEmitter {
|
|||
const {
|
||||
endpoint,
|
||||
|
||||
// True if the QuicSocket should automatically enter a graceful shutdown
|
||||
// if it is not listening as a server and the last QuicClientSession
|
||||
// closes
|
||||
autoClose,
|
||||
|
||||
// Default configuration for QuicClientSessions
|
||||
client,
|
||||
|
||||
|
@ -913,7 +908,6 @@ class QuicSocket extends EventEmitter {
|
|||
|
||||
const state = this[kInternalState];
|
||||
|
||||
state.autoClose = autoClose;
|
||||
state.client = client;
|
||||
state.lookup = lookup || (type === AF_INET6 ? lookup6 : lookup4);
|
||||
state.server = server;
|
||||
|
@ -976,6 +970,10 @@ class QuicSocket extends EventEmitter {
|
|||
if (handle !== undefined) {
|
||||
handle[owner_symbol] = this;
|
||||
this[async_id_symbol] = handle.getAsyncId();
|
||||
this[kInternalState].sharedState =
|
||||
new QuicSocketSharedState(handle.state);
|
||||
} else {
|
||||
this[kInternalState].sharedState = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1081,16 +1079,13 @@ class QuicSocket extends EventEmitter {
|
|||
}
|
||||
|
||||
// Called by the C++ internals to notify when server busy status is toggled.
|
||||
[kServerBusy](on) {
|
||||
this[kInternalState].serverBusy = on;
|
||||
// In a nextTick because the event ends up being
|
||||
// emitted synchronously when quicSocket.serverBusy
|
||||
// is called.
|
||||
[kServerBusy]() {
|
||||
const busy = this.serverBusy;
|
||||
process.nextTick(() => {
|
||||
try {
|
||||
this.emit('busy', on);
|
||||
this.emit('busy', busy);
|
||||
} catch (error) {
|
||||
this[kRejections](error, 'busy', on);
|
||||
this[kRejections](error, 'busy', busy);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1161,6 +1156,7 @@ class QuicSocket extends EventEmitter {
|
|||
// server and will emit session events whenever a new QuicServerSession
|
||||
// is created.
|
||||
const state = this[kInternalState];
|
||||
state.listenPending = false;
|
||||
this[kHandle].listen(
|
||||
state.serverSecureContext.context,
|
||||
address,
|
||||
|
@ -1225,14 +1221,12 @@ class QuicSocket extends EventEmitter {
|
|||
// function.
|
||||
listen(options, callback) {
|
||||
const state = this[kInternalState];
|
||||
if (state.serverListening)
|
||||
throw new ERR_QUICSOCKET_LISTENING();
|
||||
|
||||
if (state.state === kSocketDestroyed ||
|
||||
state.state === kSocketClosing) {
|
||||
throw new ERR_QUICSOCKET_DESTROYED('listen');
|
||||
}
|
||||
|
||||
if (this.listening || state.listenPending)
|
||||
throw new ERR_QUICSOCKET_LISTENING();
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
|
@ -1265,8 +1259,8 @@ class QuicSocket extends EventEmitter {
|
|||
|
||||
state.highWaterMark = highWaterMark;
|
||||
state.defaultEncoding = defaultEncoding;
|
||||
state.serverListening = true;
|
||||
state.alpn = alpn;
|
||||
state.listenPending = true;
|
||||
|
||||
// If the callback function is provided, it is registered as a
|
||||
// handler for the on('session') event and will be called whenever
|
||||
|
@ -1403,10 +1397,8 @@ class QuicSocket extends EventEmitter {
|
|||
// listening for new QuicServerSession connections.
|
||||
// New initial connection packets for currently unknown
|
||||
// DCID's will be ignored.
|
||||
if (this[kHandle]) {
|
||||
this[kHandle].stopListening();
|
||||
}
|
||||
state.serverListening = false;
|
||||
if (this[kHandle])
|
||||
this[kInternalState].sharedState.serverListening = false;
|
||||
|
||||
// If there are no sessions, calling maybeDestroy
|
||||
// will immediately and synchronously destroy the
|
||||
|
@ -1502,7 +1494,7 @@ class QuicSocket extends EventEmitter {
|
|||
|
||||
// True if listen() has been called successfully
|
||||
get listening() {
|
||||
return this[kInternalState].serverListening;
|
||||
return Boolean(this[kInternalState].sharedState?.serverListening);
|
||||
}
|
||||
|
||||
// True if the QuicSocket is currently waiting on at least one
|
||||
|
@ -1518,12 +1510,27 @@ class QuicSocket extends EventEmitter {
|
|||
if (state.state === kSocketDestroyed)
|
||||
throw new ERR_QUICSOCKET_DESTROYED('serverBusy');
|
||||
validateBoolean(on, 'on');
|
||||
if (state.serverBusy !== on)
|
||||
this[kHandle].setServerBusy(on);
|
||||
if (state.sharedState.serverBusy !== on) {
|
||||
state.sharedState.serverBusy = on;
|
||||
this[kServerBusy]();
|
||||
}
|
||||
}
|
||||
|
||||
get serverBusy() {
|
||||
return this[kInternalState].serverBusy;
|
||||
return Boolean(this[kInternalState].sharedState?.serverBusy);
|
||||
}
|
||||
|
||||
set statelessResetDisabled(on) {
|
||||
const state = this[kInternalState];
|
||||
if (state.state === kSocketDestroyed)
|
||||
throw new ERR_QUICSOCKET_DESTROYED('statelessResetDisabled');
|
||||
validateBoolean(on, 'on');
|
||||
if (state.sharedState.statelessResetDisabled !== on)
|
||||
state.sharedState.statelessResetDisabled = on;
|
||||
}
|
||||
|
||||
get statelessResetDisabled() {
|
||||
return Boolean(this[kInternalState].sharedState?.statelessResetDisabled);
|
||||
}
|
||||
|
||||
get duration() {
|
||||
|
@ -1613,21 +1620,6 @@ class QuicSocket extends EventEmitter {
|
|||
}
|
||||
this[kHandle].setDiagnosticPacketLoss(rx, tx);
|
||||
}
|
||||
|
||||
get statelessResetEnabled() {
|
||||
return this[kInternalState].statelessResetEnabled;
|
||||
}
|
||||
|
||||
set statelessResetEnabled(on) {
|
||||
const state = this[kInternalState];
|
||||
if (state.state === kSocketDestroyed)
|
||||
throw new ERR_QUICSOCKET_DESTROYED('serverBusy');
|
||||
validateBoolean(on, 'on');
|
||||
if (state.statelessResetEnabled !== on) {
|
||||
this[kHandle].enableStatelessReset(on);
|
||||
state.statelessResetEnabled = on;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class QuicSession extends EventEmitter {
|
||||
|
|
|
@ -82,6 +82,10 @@ const {
|
|||
IDX_QUICSESSION_STATE_MAX_DATA_LEFT,
|
||||
IDX_QUICSESSION_STATE_BYTES_IN_FLIGHT,
|
||||
|
||||
IDX_QUICSOCKET_STATE_SERVER_LISTENING,
|
||||
IDX_QUICSOCKET_STATE_SERVER_BUSY,
|
||||
IDX_QUICSOCKET_STATE_STATELESS_RESET_DISABLED,
|
||||
|
||||
IDX_HTTP3_QPACK_MAX_TABLE_CAPACITY,
|
||||
IDX_HTTP3_QPACK_BLOCKED_STREAMS,
|
||||
IDX_HTTP3_MAX_HEADER_LIST_SIZE,
|
||||
|
@ -514,7 +518,6 @@ function validateQuicSocketOptions(options = {}) {
|
|||
validateObject(options, 'options');
|
||||
|
||||
const {
|
||||
autoClose = false,
|
||||
client = {},
|
||||
disableStatelessReset = false,
|
||||
endpoint = { port: 0, type: 'udp4' },
|
||||
|
@ -538,7 +541,6 @@ function validateQuicSocketOptions(options = {}) {
|
|||
validateLookup(lookup);
|
||||
validateBoolean(validateAddress, 'options.validateAddress');
|
||||
validateBoolean(validateAddressLRU, 'options.validateAddressLRU');
|
||||
validateBoolean(autoClose, 'options.autoClose');
|
||||
validateBoolean(qlog, 'options.qlog');
|
||||
validateBoolean(disableStatelessReset, 'options.disableStatelessReset');
|
||||
|
||||
|
@ -576,7 +578,6 @@ function validateQuicSocketOptions(options = {}) {
|
|||
|
||||
return {
|
||||
endpoint,
|
||||
autoClose,
|
||||
client,
|
||||
lookup,
|
||||
maxConnections,
|
||||
|
@ -803,6 +804,39 @@ function toggleListeners(state, event, on) {
|
|||
}
|
||||
}
|
||||
|
||||
class QuicSocketSharedState {
|
||||
constructor(state) {
|
||||
this[kHandle] = Buffer.from(state);
|
||||
}
|
||||
|
||||
get serverListening() {
|
||||
return Boolean(this[kHandle]
|
||||
.readUInt8(IDX_QUICSOCKET_STATE_SERVER_LISTENING));
|
||||
}
|
||||
|
||||
set serverListening(on) {
|
||||
this[kHandle].writeUInt8(on ? 1 : 0, IDX_QUICSOCKET_STATE_SERVER_LISTENING);
|
||||
}
|
||||
|
||||
get serverBusy() {
|
||||
return Boolean(this[kHandle].readUInt8(IDX_QUICSOCKET_STATE_SERVER_BUSY));
|
||||
}
|
||||
|
||||
set serverBusy(on) {
|
||||
this[kHandle].writeUInt8(on ? 1 : 0, IDX_QUICSOCKET_STATE_SERVER_BUSY);
|
||||
}
|
||||
|
||||
get statelessResetDisabled() {
|
||||
return Boolean(this[kHandle]
|
||||
.readUInt8(IDX_QUICSOCKET_STATE_STATELESS_RESET_DISABLED));
|
||||
}
|
||||
|
||||
set statelessResetDisabled(on) {
|
||||
this[kHandle].writeUInt8(on ? 1 : 0,
|
||||
IDX_QUICSOCKET_STATE_STATELESS_RESET_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
// A utility class used to handle reading / modifying shared JS/C++
|
||||
// state associated with a QuicSession
|
||||
class QuicSessionSharedState {
|
||||
|
@ -938,6 +972,7 @@ module.exports = {
|
|||
validateQuicEndpointOptions,
|
||||
validateCreateSecureContextOptions,
|
||||
validateQuicSocketConnectOptions,
|
||||
QuicSocketSharedState,
|
||||
QuicSessionSharedState,
|
||||
QLogStream,
|
||||
};
|
||||
|
|
|
@ -205,6 +205,11 @@ void Initialize(Local<Object> target,
|
|||
QUICSESSION_SHARED_STATE(V)
|
||||
#undef V
|
||||
|
||||
#define V(id, _, __) \
|
||||
NODE_DEFINE_CONSTANT(constants, IDX_QUICSOCKET_STATE_##id);
|
||||
QUICSOCKET_SHARED_STATE(V)
|
||||
#undef V
|
||||
|
||||
#define V(name, _, __) \
|
||||
NODE_DEFINE_CONSTANT(constants, IDX_QUIC_SESSION_STATS_##name);
|
||||
SESSION_STATS(V)
|
||||
|
|
|
@ -90,20 +90,6 @@ void QuicSocket::DisassociateStatelessResetToken(
|
|||
token_map_.erase(token);
|
||||
}
|
||||
|
||||
// StopListening is called when the QuicSocket is no longer
|
||||
// accepting new server connections. Typically, this is called
|
||||
// when the QuicSocket enters a graceful closing state where
|
||||
// existing sessions are allowed to close naturally but new
|
||||
// sessions are rejected.
|
||||
void QuicSocket::StopListening() {
|
||||
if (is_server_listening()) {
|
||||
Debug(this, "Stop listening");
|
||||
set_server_listening(false);
|
||||
// It is important to not call ReceiveStop here as there
|
||||
// is ongoing traffic being exchanged by the peers.
|
||||
}
|
||||
}
|
||||
|
||||
void QuicSocket::ReceiveStart() {
|
||||
for (const auto& endpoint : endpoints_)
|
||||
CHECK_EQ(endpoint->ReceiveStart(), 0);
|
||||
|
@ -157,8 +143,8 @@ size_t QuicSocket::GetCurrentStatelessResetCounter(const SocketAddress& addr) {
|
|||
|
||||
void QuicSocket::ServerBusy(bool on) {
|
||||
Debug(this, "Turning Server Busy Response %s", on ? "on" : "off");
|
||||
set_server_busy(on);
|
||||
listener_->OnServerBusy(on);
|
||||
state_->server_busy = on ? 1 : 0;
|
||||
listener_->OnServerBusy();
|
||||
}
|
||||
|
||||
bool QuicSocket::is_diagnostic_packet_loss(double prob) const {
|
||||
|
@ -173,11 +159,6 @@ void QuicSocket::set_diagnostic_packet_loss(double rx, double tx) {
|
|||
tx_loss_ = tx;
|
||||
}
|
||||
|
||||
bool QuicSocket::EnableStatelessReset(bool on) {
|
||||
set_stateless_reset_disabled(!on);
|
||||
return !is_stateless_reset_disabled();
|
||||
}
|
||||
|
||||
void QuicSocket::set_validated_address(const SocketAddress& addr) {
|
||||
if (has_option_validate_address_lru()) {
|
||||
// Remove the oldest item if we've hit the LRU limit
|
||||
|
@ -215,7 +196,7 @@ void QuicSocket::AddEndpoint(
|
|||
if (preferred || endpoints_.empty())
|
||||
preferred_endpoint_ = endpoint_;
|
||||
endpoints_.emplace_back(endpoint_);
|
||||
if (is_server_listening())
|
||||
if (state_->server_listening)
|
||||
endpoint_->ReceiveStart();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "node_quic_socket-inl.h" // NOLINT(build/include)
|
||||
#include "aliased_struct-inl.h"
|
||||
#include "allocated_buffer-inl.h"
|
||||
#include "async_wrap-inl.h"
|
||||
#include "debug_utils-inl.h"
|
||||
|
@ -38,6 +39,7 @@ using v8::Local;
|
|||
using v8::Number;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::PropertyAttribute;
|
||||
using v8::String;
|
||||
using v8::Value;
|
||||
|
||||
|
@ -115,9 +117,9 @@ void QuicSocketListener::OnSessionReady(BaseObjectPtr<QuicSession> session) {
|
|||
previous_listener_->OnSessionReady(session);
|
||||
}
|
||||
|
||||
void QuicSocketListener::OnServerBusy(bool busy) {
|
||||
void QuicSocketListener::OnServerBusy() {
|
||||
if (previous_listener_ != nullptr)
|
||||
previous_listener_->OnServerBusy(busy);
|
||||
previous_listener_->OnServerBusy();
|
||||
}
|
||||
|
||||
void QuicSocketListener::OnEndpointDone(QuicEndpoint* endpoint) {
|
||||
|
@ -145,12 +147,12 @@ void JSQuicSocketListener::OnSessionReady(BaseObjectPtr<QuicSession> session) {
|
|||
socket()->MakeCallback(env->quic_on_session_ready_function(), 1, &arg);
|
||||
}
|
||||
|
||||
void JSQuicSocketListener::OnServerBusy(bool busy) {
|
||||
void JSQuicSocketListener::OnServerBusy() {
|
||||
Environment* env = socket()->env();
|
||||
HandleScope handle_scope(env->isolate());
|
||||
Context::Scope context_scope(env->context());
|
||||
Local<Value> arg = Boolean::New(env->isolate(), busy);
|
||||
socket()->MakeCallback(env->quic_on_socket_server_busy_function(), 1, &arg);
|
||||
socket()->MakeCallback(
|
||||
env->quic_on_socket_server_busy_function(), 0, nullptr);
|
||||
}
|
||||
|
||||
void JSQuicSocketListener::OnEndpointDone(QuicEndpoint* endpoint) {
|
||||
|
@ -252,6 +254,7 @@ QuicSocket::QuicSocket(
|
|||
StatsBase(quic_state->env(), wrap),
|
||||
alloc_info_(MakeAllocator()),
|
||||
options_(options),
|
||||
state_(quic_state->env()->isolate()),
|
||||
max_connections_(max_connections),
|
||||
max_connections_per_host_(max_connections_per_host),
|
||||
max_stateless_resets_per_host_(max_stateless_resets_per_host),
|
||||
|
@ -266,8 +269,14 @@ QuicSocket::QuicSocket(
|
|||
|
||||
EntropySource(token_secret_, kTokenSecretLen);
|
||||
|
||||
wrap->DefineOwnProperty(
|
||||
env()->context(),
|
||||
env()->state_string(),
|
||||
state_.GetArrayBuffer(),
|
||||
PropertyAttribute::ReadOnly).Check();
|
||||
|
||||
if (disable_stateless_reset)
|
||||
set_stateless_reset_disabled();
|
||||
state_->stateless_reset_disabled = 1;
|
||||
|
||||
// Set the session reset secret to the one provided or random.
|
||||
// Note that a random secret is going to make it exceedingly
|
||||
|
@ -316,13 +325,13 @@ void QuicSocket::Listen(
|
|||
const std::string& alpn,
|
||||
uint32_t options) {
|
||||
CHECK(sc);
|
||||
CHECK(!is_server_listening());
|
||||
CHECK_NE(state_->server_listening, 1);
|
||||
Debug(this, "Starting to listen");
|
||||
server_session_config_.Set(quic_state(), preferred_address);
|
||||
server_secure_context_ = sc;
|
||||
server_alpn_ = alpn;
|
||||
server_options_ = options;
|
||||
set_server_listening();
|
||||
state_->server_listening = 1;
|
||||
RecordTimestamp(&QuicSocketStats::listen_at);
|
||||
ReceiveStart();
|
||||
}
|
||||
|
@ -391,7 +400,7 @@ bool QuicSocket::MaybeStatelessReset(
|
|||
const SocketAddress& local_addr,
|
||||
const SocketAddress& remote_addr,
|
||||
unsigned int flags) {
|
||||
if (UNLIKELY(is_stateless_reset_disabled() || nread < 16))
|
||||
if (UNLIKELY(state_->stateless_reset_disabled || nread < 16))
|
||||
return false;
|
||||
StatelessResetToken possible_token(
|
||||
data + nread - NGTCP2_STATELESS_RESET_TOKENLEN);
|
||||
|
@ -620,7 +629,7 @@ bool QuicSocket::SendStatelessReset(
|
|||
const SocketAddress& local_addr,
|
||||
const SocketAddress& remote_addr,
|
||||
size_t source_len) {
|
||||
if (UNLIKELY(is_stateless_reset_disabled()))
|
||||
if (UNLIKELY(state_->stateless_reset_disabled))
|
||||
return false;
|
||||
constexpr static size_t kRandlen = NGTCP2_MIN_STATELESS_RESET_RANDLEN * 5;
|
||||
constexpr static size_t kMinStatelessResetLen = 41;
|
||||
|
@ -737,7 +746,7 @@ BaseObjectPtr<QuicSession> QuicSocket::AcceptInitialPacket(
|
|||
QuicCID ocid;
|
||||
|
||||
// If the QuicSocket is not listening, the paket will be ignored.
|
||||
if (!is_server_listening()) {
|
||||
if (!state_->server_listening) {
|
||||
Debug(this, "QuicSocket is not listening");
|
||||
return {};
|
||||
}
|
||||
|
@ -762,7 +771,7 @@ BaseObjectPtr<QuicSession> QuicSocket::AcceptInitialPacket(
|
|||
// Else, check to see if the number of connections total for this QuicSocket
|
||||
// has been exceeded. If the count has been exceeded, shutdown the connection
|
||||
// immediately after the initial keys are installed.
|
||||
if (UNLIKELY(is_server_busy()) ||
|
||||
if (UNLIKELY(state_->server_busy == 1) ||
|
||||
sessions_.size() >= max_connections_ ||
|
||||
GetCurrentSocketAddressCounter(remote_addr) >=
|
||||
max_connections_per_host_) {
|
||||
|
@ -1115,26 +1124,6 @@ void QuicSocketListen(const FunctionCallbackInfo<Value>& args) {
|
|||
options);
|
||||
}
|
||||
|
||||
void QuicSocketStopListening(const FunctionCallbackInfo<Value>& args) {
|
||||
QuicSocket* socket;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&socket, args.Holder());
|
||||
socket->StopListening();
|
||||
}
|
||||
|
||||
void QuicSocketSetServerBusy(const FunctionCallbackInfo<Value>& args) {
|
||||
QuicSocket* socket;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&socket, args.Holder());
|
||||
CHECK_EQ(args.Length(), 1);
|
||||
socket->ServerBusy(args[0]->IsTrue());
|
||||
}
|
||||
|
||||
void QuicSocketEnableStatelessReset(const FunctionCallbackInfo<Value>& args) {
|
||||
QuicSocket* socket;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&socket, args.Holder());
|
||||
CHECK_EQ(args.Length(), 1);
|
||||
args.GetReturnValue().Set(socket->EnableStatelessReset(args[0]->IsTrue()));
|
||||
}
|
||||
|
||||
void QuicEndpointWaitForPendingCallbacks(
|
||||
const FunctionCallbackInfo<Value>& args) {
|
||||
QuicEndpoint* endpoint;
|
||||
|
@ -1191,15 +1180,6 @@ void QuicSocket::Initialize(
|
|||
env->SetProtoMethod(socket,
|
||||
"setDiagnosticPacketLoss",
|
||||
QuicSocketSetDiagnosticPacketLoss);
|
||||
env->SetProtoMethod(socket,
|
||||
"setServerBusy",
|
||||
QuicSocketSetServerBusy);
|
||||
env->SetProtoMethod(socket,
|
||||
"stopListening",
|
||||
QuicSocketStopListening);
|
||||
env->SetProtoMethod(socket,
|
||||
"enableStatelessReset",
|
||||
QuicSocketEnableStatelessReset);
|
||||
socket->Inherit(HandleWrap::GetConstructorTemplate(env));
|
||||
target->Set(context, class_name,
|
||||
socket->GetFunction(env->context()).ToLocalChecked()).FromJust();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
|
||||
#include "aliased_struct.h"
|
||||
#include "base_object.h"
|
||||
#include "node.h"
|
||||
#include "node_crypto.h"
|
||||
|
@ -47,12 +48,24 @@ enum QuicSocketOptions : uint32_t {
|
|||
};
|
||||
#undef V
|
||||
|
||||
#define QUICSOCKET_FLAGS(V) \
|
||||
V(GRACEFUL_CLOSE, graceful_closing) \
|
||||
V(WAITING_FOR_CALLBACKS, waiting_for_callbacks) \
|
||||
V(SERVER_LISTENING, server_listening) \
|
||||
V(SERVER_BUSY, server_busy) \
|
||||
V(DISABLE_STATELESS_RESET, stateless_reset_disabled)
|
||||
#define QUICSOCKET_SHARED_STATE(V) \
|
||||
V(SERVER_LISTENING, server_listening, uint8_t) \
|
||||
V(SERVER_BUSY, server_busy, uint8_t) \
|
||||
V(STATELESS_RESET_DISABLED, stateless_reset_disabled, uint8_t)
|
||||
|
||||
#define V(_, name, type) type name;
|
||||
struct QuicSocketState {
|
||||
QUICSOCKET_SHARED_STATE(V)
|
||||
};
|
||||
#undef V
|
||||
|
||||
#define V(id, name, _) \
|
||||
IDX_QUICSOCKET_STATE_##id = offsetof(QuicSocketState, name),
|
||||
enum QuicSocketStateFields {
|
||||
QUICSOCKET_SHARED_STATE(V)
|
||||
IDX_QUICSOCKET_STATE_END
|
||||
};
|
||||
#undef V
|
||||
|
||||
#define SOCKET_STATS(V) \
|
||||
V(CREATED_AT, created_at, "Created At") \
|
||||
|
@ -98,7 +111,7 @@ class QuicSocketListener {
|
|||
|
||||
virtual void OnError(ssize_t code);
|
||||
virtual void OnSessionReady(BaseObjectPtr<QuicSession> session);
|
||||
virtual void OnServerBusy(bool busy);
|
||||
virtual void OnServerBusy();
|
||||
virtual void OnEndpointDone(QuicEndpoint* endpoint);
|
||||
virtual void OnDestroy();
|
||||
|
||||
|
@ -114,7 +127,7 @@ class JSQuicSocketListener final : public QuicSocketListener {
|
|||
public:
|
||||
void OnError(ssize_t code) override;
|
||||
void OnSessionReady(BaseObjectPtr<QuicSession> session) override;
|
||||
void OnServerBusy(bool busy) override;
|
||||
void OnServerBusy() override;
|
||||
void OnEndpointDone(QuicEndpoint* endpoint) override;
|
||||
void OnDestroy() override;
|
||||
};
|
||||
|
@ -357,35 +370,19 @@ class QuicSocket : public AsyncWrap,
|
|||
std::unique_ptr<QuicPacket> packet,
|
||||
BaseObjectPtr<QuicSession> session = BaseObjectPtr<QuicSession>());
|
||||
|
||||
#define V(id, name) \
|
||||
inline bool is_##name() const { \
|
||||
return flags_ & (1 << QUICSOCKET_FLAG_##id); } \
|
||||
inline void set_##name(bool on = true) { \
|
||||
if (on) \
|
||||
flags_ |= (1 << QUICSOCKET_FLAG_##id); \
|
||||
else \
|
||||
flags_ &= ~(1 << QUICSOCKET_FLAG_##id); \
|
||||
}
|
||||
QUICSOCKET_FLAGS(V)
|
||||
#undef V
|
||||
|
||||
#define V(id, name) \
|
||||
bool has_option_##name() const { \
|
||||
return options_ & (1 << QUICSOCKET_OPTIONS_##id); }
|
||||
QUICSOCKET_OPTIONS(V)
|
||||
#undef V
|
||||
|
||||
// Allows the server busy status to be enabled from C++. A notification
|
||||
// will be sent to the JavaScript side informing that the status has
|
||||
// changed.
|
||||
inline void ServerBusy(bool on);
|
||||
|
||||
inline void set_diagnostic_packet_loss(double rx = 0.0, double tx = 0.0);
|
||||
|
||||
inline void StopListening();
|
||||
|
||||
// Toggles whether or not stateless reset is enabled or not.
|
||||
// Returns true if stateless reset is enabled, false if it
|
||||
// is not.
|
||||
inline bool EnableStatelessReset(bool on = true);
|
||||
|
||||
BaseObjectPtr<crypto::SecureContext> server_secure_context() const {
|
||||
return server_secure_context_;
|
||||
}
|
||||
|
@ -513,13 +510,6 @@ class QuicSocket : public AsyncWrap,
|
|||
// and the current packet should be artificially considered lost.
|
||||
inline bool is_diagnostic_packet_loss(double prob) const;
|
||||
|
||||
#define V(id, _) QUICSOCKET_FLAG_##id,
|
||||
enum QuicSocketFlags : uint32_t {
|
||||
QUICSOCKET_FLAGS(V)
|
||||
QUICSOCKET_FLAG_COUNT
|
||||
};
|
||||
#undef V
|
||||
|
||||
ngtcp2_mem alloc_info_;
|
||||
|
||||
std::vector<BaseObjectPtr<QuicEndpoint>> endpoints_;
|
||||
|
@ -530,6 +520,8 @@ class QuicSocket : public AsyncWrap,
|
|||
uint32_t options_ = 0;
|
||||
uint32_t server_options_;
|
||||
|
||||
AliasedStruct<QuicSocketState> state_;
|
||||
|
||||
size_t max_connections_ = DEFAULT_MAX_CONNECTIONS;
|
||||
size_t max_connections_per_host_ = DEFAULT_MAX_CONNECTIONS_PER_HOST;
|
||||
size_t current_ngtcp2_memory_ = 0;
|
||||
|
|
|
@ -82,13 +82,6 @@ const { createQuicSocket } = require('net');
|
|||
});
|
||||
});
|
||||
|
||||
// Test invalid QuicSocket autoClose argument option
|
||||
[1, NaN, 1n, null, {}, []].forEach((autoClose) => {
|
||||
assert.throws(() => createQuicSocket({ autoClose }), {
|
||||
code: 'ERR_INVALID_ARG_TYPE'
|
||||
});
|
||||
});
|
||||
|
||||
// Test invalid QuicSocket qlog argument option
|
||||
[1, NaN, 1n, null, {}, []].forEach((qlog) => {
|
||||
assert.throws(() => createQuicSocket({ qlog }), {
|
||||
|
|
Loading…
Reference in New Issue