Skip to content

Commit 679d5c8

Browse files
committed
quic: use the SocketAddressLRU to track validation status
1 parent 35475e7 commit 679d5c8

File tree

7 files changed

+19
-37
lines changed

7 files changed

+19
-37
lines changed

doc/api/quic.md

-5
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,6 @@ added: REPLACEME
288288
* `validateAddress` {boolean} When `true`, the `QuicSocket` will use explicit
289289
address validation using a QUIC `RETRY` frame when listening for new server
290290
sessions. Default: `false`.
291-
* `validateAddressLRU` {boolean} When `true`, validation will be skipped if
292-
the address has been recently validated. Currently, only the 10 most
293-
recently validated addresses are remembered. Setting `validateAddressLRU`
294-
to `true`, will enable the `validateAddress` option as well. Default:
295-
`false`.
296291

297292
The `net.createQuicSocket()` function is used to create new `QuicSocket`
298293
instances associated with a local UDP address.

lib/internal/quic/core.js

-6
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ const {
179179
QUICCLIENTSESSION_OPTION_REQUEST_OCSP,
180180
QUICCLIENTSESSION_OPTION_VERIFY_HOSTNAME_IDENTITY,
181181
QUICSOCKET_OPTIONS_VALIDATE_ADDRESS,
182-
QUICSOCKET_OPTIONS_VALIDATE_ADDRESS_LRU,
183182
QUICSTREAM_HEADERS_KIND_NONE,
184183
QUICSTREAM_HEADERS_KIND_INFORMATIONAL,
185184
QUICSTREAM_HEADERS_KIND_INITIAL,
@@ -941,9 +940,6 @@ class QuicSocket extends EventEmitter {
941940
// True if address verification should be used.
942941
validateAddress,
943942

944-
// True if an LRU should be used for add validation
945-
validateAddressLRU,
946-
947943
// Whether qlog should be enabled for sessions
948944
qlog,
949945

@@ -964,8 +960,6 @@ class QuicSocket extends EventEmitter {
964960
let socketOptions = 0;
965961
if (validateAddress)
966962
socketOptions |= (1 << QUICSOCKET_OPTIONS_VALIDATE_ADDRESS);
967-
if (validateAddressLRU)
968-
socketOptions |= (1 << QUICSOCKET_OPTIONS_VALIDATE_ADDRESS_LRU);
969963

970964
this[kSetHandle](
971965
new QuicSocketHandle(

lib/internal/quic/util.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,6 @@ function validateQuicSocketOptions(options = {}) {
539539
retryTokenTimeout = DEFAULT_RETRYTOKEN_EXPIRATION,
540540
server = {},
541541
statelessResetSecret,
542-
validateAddressLRU = false,
543542
validateAddress = false,
544543
} = options;
545544

@@ -548,7 +547,6 @@ function validateQuicSocketOptions(options = {}) {
548547
validateObject(server, 'options.server');
549548
validateLookup(lookup);
550549
validateBoolean(validateAddress, 'options.validateAddress');
551-
validateBoolean(validateAddressLRU, 'options.validateAddressLRU');
552550
validateBoolean(qlog, 'options.qlog');
553551
validateBoolean(disableStatelessReset, 'options.disableStatelessReset');
554552

@@ -597,8 +595,7 @@ function validateQuicSocketOptions(options = {}) {
597595
retryTokenTimeout,
598596
server,
599597
type,
600-
validateAddress: validateAddress || validateAddressLRU,
601-
validateAddressLRU,
598+
validateAddress,
602599
qlog,
603600
statelessResetSecret,
604601
disableStatelessReset,

src/quic/node_quic.cc

-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ void Initialize(Local<Object> target,
189189
V(QUICSERVERSESSION_OPTION_REJECT_UNAUTHORIZED) \
190190
V(QUICSERVERSESSION_OPTION_REQUEST_CERT) \
191191
V(QUICSOCKET_OPTIONS_VALIDATE_ADDRESS) \
192-
V(QUICSOCKET_OPTIONS_VALIDATE_ADDRESS_LRU) \
193192
V(QUICSTREAM_HEADER_FLAGS_NONE) \
194193
V(QUICSTREAM_HEADER_FLAGS_TERMINAL) \
195194
V(QUICSTREAM_HEADERS_KIND_NONE) \

src/quic/node_quic_socket.cc

+16-12
Original file line numberDiff line numberDiff line change
@@ -676,23 +676,27 @@ bool QuicSocket::SendStatelessReset(
676676
// peer must termination it's initial attempt to
677677
// establish a connection and start a new attempt.
678678
//
679-
// TODO(@jasnell): Retry packets will only ever be
680-
// generated by QUIC servers, and only if the QuicSocket
681-
// is configured for explicit path validation. There is
682-
// no way for a client to force a retry packet to be created.
683-
// However, once a client determines that explicit
684-
// path validation is enabled, it could attempt to
685-
// DOS by sending a large number of malicious
686-
// initial packets to intentionally ellicit retry
687-
// packets (It can do so by intentionally sending
688-
// initial packets that ignore the retry token).
689-
// To help mitigate that risk, we should limit the number
690-
// of retries we send to a given remote endpoint.
679+
// Retry packets will only ever be generated by QUIC servers,
680+
// and only if the QuicSocket is configured for explicit path
681+
// validation. There is no way for a client to force a retry
682+
// packet to be created. However, once a client determines that
683+
// explicit path validation is enabled, it could attempt to
684+
// DOS by sending a large number of malicious initial packets
685+
// to intentionally ellicit retry packets (It can do so by
686+
// intentionally sending initial packets that ignore the retry
687+
// token). To help mitigate that risk, we limit the number of
688+
// retries we send to a given remote endpoint.
691689
bool QuicSocket::SendRetry(
692690
const QuicCID& dcid,
693691
const QuicCID& scid,
694692
const SocketAddress& local_addr,
695693
const SocketAddress& remote_addr) {
694+
auto info = addrLRU_.Upsert(remote_addr);
695+
// Do not send a retry if the retry count is greater
696+
// than the retry limit.
697+
// TODO(@jasnell): Make the retry limit configurable.
698+
if (++(info->retry_count) > DEFAULT_MAX_RETRY_LIMIT)
699+
return true;
696700
std::unique_ptr<QuicPacket> packet =
697701
GenerateRetryPacket(token_secret_, dcid, scid, local_addr, remote_addr);
698702
return packet ?

src/quic/node_quic_socket.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ class QuicSocket;
3838
class QuicEndpoint;
3939

4040
constexpr size_t DEFAULT_MAX_SOCKETADDRESS_LRU_SIZE = 1000;
41+
constexpr size_t DEFAULT_MAX_RETRY_LIMIT = 10;
4142

4243
#define QUICSOCKET_OPTIONS(V) \
43-
V(VALIDATE_ADDRESS, validate_address) \
44-
V(VALIDATE_ADDRESS_LRU, validate_address_lru)
44+
V(VALIDATE_ADDRESS, validate_address)
4545

4646
#define V(id, _) QUICSOCKET_OPTIONS_##id,
4747
enum QuicSocketOptions : uint32_t {

test/parallel/test-quic-errors-quicsocket-create.js

-7
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,6 @@ const { createQuicSocket } = require('net');
6868
});
6969
});
7070

71-
// Test invalid QuicSocket validateAddressLRU argument option
72-
[1, NaN, 1n, null, {}, []].forEach((validateAddressLRU) => {
73-
assert.throws(() => createQuicSocket({ validateAddressLRU }), {
74-
code: 'ERR_INVALID_ARG_TYPE'
75-
});
76-
});
77-
7871
// Test invalid QuicSocket qlog argument option
7972
[1, NaN, 1n, null, {}, []].forEach((qlog) => {
8073
assert.throws(() => createQuicSocket({ qlog }), {

0 commit comments

Comments
 (0)