Skip to content

Commit

Permalink
quic: multiple updates to quic impl
Browse files Browse the repository at this point in the history
* separate stats and symbols into separate files
* quic: rename `EndpointStats` and `SessionStats` to be consistent
  * s/EndpointStats/QuicEndpointStats/
  * s/SessionStats/QuicSessionStats/
* separate state into separate files and other cleanups
* extend tls options validations
* rename classes for consistency and other cleanups

PR-URL: #55971
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
jasnell committed Nov 26, 2024
1 parent a01319a commit 3511c5c
Show file tree
Hide file tree
Showing 8 changed files with 1,449 additions and 1,222 deletions.
1,323 changes: 137 additions & 1,186 deletions lib/internal/quic/quic.js

Large diffs are not rendered by default.

566 changes: 566 additions & 0 deletions lib/internal/quic/state.js

Large diffs are not rendered by default.

646 changes: 646 additions & 0 deletions lib/internal/quic/stats.js

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions lib/internal/quic/symbols.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict';

const {
Symbol,
} = primordials;

const {
customInspectSymbol: kInspect,
} = require('internal/util');

const {
kHandle: kKeyObjectHandle,
kKeyObject: kKeyObjectInner,
} = require('internal/crypto/util');

// Symbols used to hide various private properties and methods from the
// public API.

const kBlocked = Symbol('kBlocked');
const kDatagram = Symbol('kDatagram');
const kDatagramStatus = Symbol('kDatagramStatus');
const kError = Symbol('kError');
const kFinishClose = Symbol('kFinishClose');
const kHandshake = Symbol('kHandshake');
const kHeaders = Symbol('kHeaders');
const kOwner = Symbol('kOwner');
const kNewSession = Symbol('kNewSession');
const kNewStream = Symbol('kNewStream');
const kPathValidation = Symbol('kPathValidation');
const kReset = Symbol('kReset');
const kSessionTicket = Symbol('kSessionTicket');
const kTrailers = Symbol('kTrailers');
const kVersionNegotiation = Symbol('kVersionNegotiation');
const kPrivateConstructor = Symbol('kPrivateConstructor');

module.exports = {
kBlocked,
kDatagram,
kDatagramStatus,
kError,
kFinishClose,
kHandshake,
kHeaders,
kOwner,
kNewSession,
kNewStream,
kPathValidation,
kReset,
kSessionTicket,
kTrailers,
kVersionNegotiation,
kInspect,
kKeyObjectHandle,
kKeyObjectInner,
kPrivateConstructor,
};
3 changes: 2 additions & 1 deletion src/node_builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ BuiltinLoader::BuiltinCategories BuiltinLoader::GetBuiltinCategories() const {
"internal/streams/lazy_transform",
#endif // !HAVE_OPENSSL
#if !NODE_OPENSSL_HAS_QUIC
"internal/quic/quic",
"internal/quic/quic", "internal/quic/symbols", "internal/quic/stats",
"internal/quic/state",
#endif // !NODE_OPENSSL_HAS_QUIC
"sqlite", // Experimental.
"sys", // Deprecated.
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-quic-internal-endpoint-listen-defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ describe('quic internal endpoint listen defaults', { skip: !hasQuic }, async ()
} = require('net');

const {
Endpoint,
QuicEndpoint,
} = require('internal/quic/quic');

it('are reasonable and work as expected', async () => {
const endpoint = new Endpoint({
const endpoint = new QuicEndpoint({
onsession() {},
session: {},
stream: {},
Expand Down
34 changes: 17 additions & 17 deletions test/parallel/test-quic-internal-endpoint-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('quic internal endpoint options', { skip: !hasQuic }, async () => {
} = require('node:assert');

const {
Endpoint,
QuicEndpoint,
} = require('internal/quic/quic');

const {
Expand All @@ -30,17 +30,17 @@ describe('quic internal endpoint options', { skip: !hasQuic }, async () => {

it('invalid options', async () => {
['a', null, false, NaN].forEach((i) => {
throws(() => new Endpoint(callbackConfig, i), {
throws(() => new QuicEndpoint(callbackConfig, i), {
code: 'ERR_INVALID_ARG_TYPE',
});
});
});

it('valid options', async () => {
// Just Works... using all defaults
new Endpoint(callbackConfig, {});
new Endpoint(callbackConfig);
new Endpoint(callbackConfig, undefined);
new QuicEndpoint(callbackConfig, {});
new QuicEndpoint(callbackConfig);
new QuicEndpoint(callbackConfig, undefined);
});

it('various cases', async () => {
Expand Down Expand Up @@ -126,12 +126,12 @@ describe('quic internal endpoint options', { skip: !hasQuic }, async () => {
{
key: 'cc',
valid: [
Endpoint.CC_ALGO_RENO,
Endpoint.CC_ALGO_CUBIC,
Endpoint.CC_ALGO_BBR,
Endpoint.CC_ALGO_RENO_STR,
Endpoint.CC_ALGO_CUBIC_STR,
Endpoint.CC_ALGO_BBR_STR,
QuicEndpoint.CC_ALGO_RENO,
QuicEndpoint.CC_ALGO_CUBIC,
QuicEndpoint.CC_ALGO_BBR,
QuicEndpoint.CC_ALGO_RENO_STR,
QuicEndpoint.CC_ALGO_CUBIC_STR,
QuicEndpoint.CC_ALGO_BBR_STR,
],
invalid: [-1, 4, 1n, 'a', null, false, true, {}, [], () => {}],
},
Expand Down Expand Up @@ -190,39 +190,39 @@ describe('quic internal endpoint options', { skip: !hasQuic }, async () => {
for (const value of valid) {
const options = {};
options[key] = value;
new Endpoint(callbackConfig, options);
new QuicEndpoint(callbackConfig, options);
}

for (const value of invalid) {
const options = {};
options[key] = value;
throws(() => new Endpoint(callbackConfig, options), {
throws(() => new QuicEndpoint(callbackConfig, options), {
code: 'ERR_INVALID_ARG_VALUE',
});
}
}
});

it('endpoint can be ref/unrefed without error', async () => {
const endpoint = new Endpoint(callbackConfig, {});
const endpoint = new QuicEndpoint(callbackConfig, {});
endpoint.unref();
endpoint.ref();
endpoint.close();
await endpoint.closed;
});

it('endpoint can be inspected', async () => {
const endpoint = new Endpoint(callbackConfig, {});
const endpoint = new QuicEndpoint(callbackConfig, {});
strictEqual(typeof inspect(endpoint), 'string');
endpoint.close();
await endpoint.closed;
});

it('endpoint with object address', () => {
new Endpoint(callbackConfig, {
new QuicEndpoint(callbackConfig, {
address: { host: '127.0.0.1:0' },
});
throws(() => new Endpoint(callbackConfig, { address: '127.0.0.1:0' }), {
throws(() => new QuicEndpoint(callbackConfig, { address: '127.0.0.1:0' }), {
code: 'ERR_INVALID_ARG_TYPE',
});
});
Expand Down
39 changes: 23 additions & 16 deletions test/parallel/test-quic-internal-endpoint-stats-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ const {

describe('quic internal endpoint stats and state', { skip: !hasQuic }, () => {
const {
Endpoint,
QuicEndpoint,
QuicStreamState,
QuicStreamStats,
SessionState,
SessionStats,
kFinishClose,
QuicSessionState,
QuicSessionStats,
} = require('internal/quic/quic');

const {
kFinishClose,
kPrivateConstructor,
} = require('internal/quic/symbols');

const {
inspect,
} = require('util');
Expand All @@ -29,7 +33,7 @@ describe('quic internal endpoint stats and state', { skip: !hasQuic }, () => {
} = require('node:assert');

it('endpoint state', () => {
const endpoint = new Endpoint({
const endpoint = new QuicEndpoint({
onsession() {},
session: {},
stream: {},
Expand Down Expand Up @@ -62,7 +66,7 @@ describe('quic internal endpoint stats and state', { skip: !hasQuic }, () => {
});

it('state is not readable after close', () => {
const endpoint = new Endpoint({
const endpoint = new QuicEndpoint({
onsession() {},
session: {},
stream: {},
Expand All @@ -74,24 +78,25 @@ describe('quic internal endpoint stats and state', { skip: !hasQuic }, () => {
});

it('state constructor argument is ArrayBuffer', () => {
const endpoint = new Endpoint({
const endpoint = new QuicEndpoint({
onsession() {},
session: {},
stream: {},
}, {});
const Cons = endpoint.state.constructor;
throws(() => new Cons(1), {
throws(() => new Cons(kPrivateConstructor, 1), {
code: 'ERR_INVALID_ARG_TYPE'
});
});

it('endpoint stats', () => {
const endpoint = new Endpoint({
const endpoint = new QuicEndpoint({
onsession() {},
session: {},
stream: {},
});

strictEqual(typeof endpoint.stats.isConnected, 'boolean');
strictEqual(typeof endpoint.stats.createdAt, 'bigint');
strictEqual(typeof endpoint.stats.destroyedAt, 'bigint');
strictEqual(typeof endpoint.stats.bytesReceived, 'bigint');
Expand All @@ -107,6 +112,7 @@ describe('quic internal endpoint stats and state', { skip: !hasQuic }, () => {
strictEqual(typeof endpoint.stats.immediateCloseCount, 'bigint');

deepStrictEqual(Object.keys(endpoint.stats.toJSON()), [
'connected',
'createdAt',
'destroyedAt',
'bytesReceived',
Expand All @@ -128,25 +134,26 @@ describe('quic internal endpoint stats and state', { skip: !hasQuic }, () => {
});

it('stats are still readble after close', () => {
const endpoint = new Endpoint({
const endpoint = new QuicEndpoint({
onsession() {},
session: {},
stream: {},
}, {});
strictEqual(typeof endpoint.stats.toJSON(), 'object');
endpoint.stats[kFinishClose]();
strictEqual(endpoint.stats.isConnected, false);
strictEqual(typeof endpoint.stats.destroyedAt, 'bigint');
strictEqual(typeof endpoint.stats.toJSON(), 'object');
});

it('stats constructor argument is ArrayBuffer', () => {
const endpoint = new Endpoint({
const endpoint = new QuicEndpoint({
onsession() {},
session: {},
stream: {},
}, {});
const Cons = endpoint.stats.constructor;
throws(() => new Cons(1), {
throws(() => new Cons(kPrivateConstructor, 1), {
code: 'ERR_INVALID_ARG_TYPE',
});
});
Expand All @@ -156,8 +163,8 @@ describe('quic internal endpoint stats and state', { skip: !hasQuic }, () => {
// temporarily while the rest of the functionality is being
// implemented.
it('stream and session states', () => {
const streamState = new QuicStreamState(new ArrayBuffer(1024));
const sessionState = new SessionState(new ArrayBuffer(1024));
const streamState = new QuicStreamState(kPrivateConstructor, new ArrayBuffer(1024));
const sessionState = new QuicSessionState(kPrivateConstructor, new ArrayBuffer(1024));

strictEqual(streamState.finSent, false);
strictEqual(streamState.finReceived, false);
Expand Down Expand Up @@ -195,8 +202,8 @@ describe('quic internal endpoint stats and state', { skip: !hasQuic }, () => {
});

it('stream and session stats', () => {
const streamStats = new QuicStreamStats(new ArrayBuffer(1024));
const sessionStats = new SessionStats(new ArrayBuffer(1024));
const streamStats = new QuicStreamStats(kPrivateConstructor, new ArrayBuffer(1024));
const sessionStats = new QuicSessionStats(kPrivateConstructor, new ArrayBuffer(1024));
strictEqual(streamStats.createdAt, undefined);
strictEqual(streamStats.receivedAt, undefined);
strictEqual(streamStats.ackedAt, undefined);
Expand Down

0 comments on commit 3511c5c

Please sign in to comment.