Skip to content
This repository was archived by the owner on Aug 11, 2020. It is now read-only.

Commit 3982f88

Browse files
committed
quic: unify stateless reset handling
PR-URL: #294 Reviewed-By: Anna Henningsen <[email protected]>
1 parent 29f0ee3 commit 3982f88

File tree

6 files changed

+41
-76
lines changed

6 files changed

+41
-76
lines changed

src/quic/node_quic_session-inl.h

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,26 @@ using crypto::SecureContext;
2121
namespace quic {
2222

2323
void QuicSessionConfig::GenerateStatelessResetToken(
24-
StatelessResetTokenStrategy strategy,
2524
QuicSession* session,
2625
const QuicCID& cid) {
2726
transport_params.stateless_reset_token_present = 1;
28-
strategy(
29-
session,
30-
cid,
31-
transport_params.stateless_reset_token,
32-
NGTCP2_STATELESS_RESET_TOKENLEN);
27+
StatelessResetToken(
28+
transport_params.stateless_reset_token,
29+
session->socket()->session_reset_secret(),
30+
cid);
3331
}
3432

3533
void QuicSessionConfig::GeneratePreferredAddressToken(
3634
ConnectionIDStrategy connection_id_strategy,
37-
StatelessResetTokenStrategy stateless_reset_strategy,
3835
QuicSession* session,
3936
QuicCID* pscid) {
40-
4137
connection_id_strategy(session, pscid->cid(), kScidLen);
42-
stateless_reset_strategy(
43-
session,
44-
*pscid,
45-
transport_params.preferred_address.stateless_reset_token,
46-
NGTCP2_STATELESS_RESET_TOKENLEN);
4738
transport_params.preferred_address.cid = **pscid;
39+
40+
StatelessResetToken(
41+
transport_params.preferred_address.stateless_reset_token,
42+
session->socket()->session_reset_secret(),
43+
*pscid);
4844
}
4945

5046
void QuicSessionConfig::set_original_connection_id(const QuicCID& ocid) {
@@ -376,15 +372,6 @@ void QuicSession::set_connection_id_strategy(ConnectionIDStrategy strategy) {
376372
connection_id_strategy_ = strategy;
377373
}
378374

379-
// The stateless reset token strategy is a function that generates
380-
// stateless reset tokens. By default these are cryptographically
381-
// derived by the CID.
382-
void QuicSession::set_stateless_reset_token_strategy(
383-
StatelessResetTokenStrategy strategy) {
384-
CHECK_NOT_NULL(strategy);
385-
stateless_reset_strategy_ = strategy;
386-
}
387-
388375
void QuicSession::set_preferred_address_strategy(
389376
PreferredAddressStrategy strategy) {
390377
preferred_address_strategy_ = strategy;

src/quic/node_quic_session.cc

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -709,26 +709,6 @@ void QuicSession::RandomConnectionIDStrategy(
709709
EntropySource(cid->data, cidlen);
710710
}
711711

712-
// Generates a stateless reset token as a function of the reset
713-
// secret (generated randomly by default or set by config option)
714-
// and the provided cid. The stateless reset is generated
715-
// cryptographically and can be recreated later without storing
716-
// additional state.
717-
void QuicSession::CryptoStatelessResetTokenStrategy(
718-
QuicSession* session,
719-
const QuicCID& cid,
720-
uint8_t* token,
721-
size_t tokenlen) {
722-
// For the current time, we limit stateless reset token lengths to
723-
// NGTCP2_STATELESS_RESET_TOKENLEN. The tokenlen argument is largely
724-
// for future proofing in case that restriction changes.
725-
CHECK_EQ(tokenlen, NGTCP2_STATELESS_RESET_TOKENLEN);
726-
CHECK(GenerateResetToken(
727-
token,
728-
session->socket()->session_reset_secret(),
729-
cid));
730-
}
731-
732712
// Check required capabilities were not excluded from the OpenSSL build:
733713
// - OPENSSL_NO_SSL_TRACE excludes SSL_trace()
734714
// - OPENSSL_NO_STDIO excludes BIO_new_fp()
@@ -1352,7 +1332,6 @@ QuicSession::QuicSession(
13521332
state_(env()->isolate(), IDX_QUIC_SESSION_STATE_COUNT) {
13531333
PushListener(&default_listener_);
13541334
set_connection_id_strategy(RandomConnectionIDStrategy);
1355-
set_stateless_reset_token_strategy(CryptoStatelessResetTokenStrategy);
13561335
set_preferred_address_strategy(preferred_address_strategy);
13571336
crypto_context_.reset(new QuicCryptoContext(this, ctx, side, options));
13581337
application_.reset(SelectApplication(this));
@@ -1630,7 +1609,7 @@ int QuicSession::GetNewConnectionID(
16301609
CHECK_NOT_NULL(connection_id_strategy_);
16311610
connection_id_strategy_(this, cid, cidlen);
16321611
QuicCID cid_(cid);
1633-
stateless_reset_strategy_(this, cid_, token, NGTCP2_STATELESS_RESET_TOKENLEN);
1612+
StatelessResetToken(token, socket()->session_reset_secret(), cid_);
16341613
AssociateCID(cid_);
16351614
return 0;
16361615
}
@@ -2629,16 +2608,8 @@ void QuicSession::InitServer(
26292608

26302609
connection_id_strategy_(this, scid_.cid(), kScidLen);
26312610

2632-
config.GenerateStatelessResetToken(
2633-
stateless_reset_strategy_,
2634-
this,
2635-
scid_);
2636-
2637-
config.GeneratePreferredAddressToken(
2638-
connection_id_strategy_,
2639-
stateless_reset_strategy_,
2640-
this,
2641-
&pscid_);
2611+
config.GenerateStatelessResetToken(this, scid_);
2612+
config.GeneratePreferredAddressToken(connection_id_strategy_, this, &pscid_);
26422613

26432614
QuicPath path(local_addr, remote_address_);
26442615

src/quic/node_quic_session.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ typedef void(*ConnectionIDStrategy)(
4646
ngtcp2_cid* cid,
4747
size_t cidlen);
4848

49-
typedef void(*StatelessResetTokenStrategy)(
50-
QuicSession* session,
51-
const QuicCID& cid,
52-
uint8_t* token,
53-
size_t tokenlen);
54-
5549
typedef void(*PreferredAddressStrategy)(
5650
QuicSession* session,
5751
const QuicPreferredAddress& preferred_address);
@@ -91,14 +85,12 @@ class QuicSessionConfig : public ngtcp2_settings {
9185

9286
// Generates the stateless reset token for the settings_
9387
inline void GenerateStatelessResetToken(
94-
StatelessResetTokenStrategy strategy,
9588
QuicSession* session,
9689
const QuicCID& cid);
9790

9891
// If the preferred address is set, generates the associated tokens
9992
inline void GeneratePreferredAddressToken(
10093
ConnectionIDStrategy connection_id_strategy,
101-
StatelessResetTokenStrategy stateless_reset_strategy,
10294
QuicSession* session,
10395
QuicCID* pscid);
10496

@@ -1015,8 +1007,6 @@ class QuicSession : public AsyncWrap,
10151007

10161008
inline void set_connection_id_strategy(
10171009
ConnectionIDStrategy strategy);
1018-
inline void set_stateless_reset_token_strategy(
1019-
StatelessResetTokenStrategy strategy);
10201010
inline void set_preferred_address_strategy(
10211011
PreferredAddressStrategy strategy);
10221012

@@ -1078,12 +1068,6 @@ class QuicSession : public AsyncWrap,
10781068
ngtcp2_cid* cid,
10791069
size_t cidlen);
10801070

1081-
static void CryptoStatelessResetTokenStrategy(
1082-
QuicSession* session,
1083-
const QuicCID& cid,
1084-
uint8_t* token,
1085-
size_t tokenlen);
1086-
10871071
// Initialize the QuicSession as a server
10881072
void InitServer(
10891073
QuicSessionConfig config,
@@ -1415,7 +1399,6 @@ class QuicSession : public AsyncWrap,
14151399
size_t connection_close_limit_ = 1;
14161400

14171401
ConnectionIDStrategy connection_id_strategy_ = nullptr;
1418-
StatelessResetTokenStrategy stateless_reset_strategy_ = nullptr;
14191402
PreferredAddressStrategy preferred_address_strategy_ = nullptr;
14201403

14211404
QuicSessionListener* listener_ = nullptr;

src/quic/node_quic_socket.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,6 @@ bool QuicSocket::SendStatelessReset(
636636
return false;
637637
constexpr static size_t kRandlen = NGTCP2_MIN_STATELESS_RESET_RANDLEN * 5;
638638
constexpr static size_t kMinStatelessResetLen = 41;
639-
uint8_t token[NGTCP2_STATELESS_RESET_TOKENLEN];
640639
uint8_t random[kRandlen];
641640

642641
// Per the QUIC spec, we need to protect against sending too
@@ -658,15 +657,15 @@ bool QuicSocket::SendStatelessReset(
658657
if (pktlen < kMinStatelessResetLen)
659658
return false;
660659

661-
GenerateResetToken(token, reset_token_secret_, cid);
660+
StatelessResetToken token(reset_token_secret_, cid);
662661
EntropySource(random, kRandlen);
663662

664663
auto packet = QuicPacket::Create("stateless reset", pktlen);
665664
ssize_t nwrite =
666665
ngtcp2_pkt_write_stateless_reset(
667666
reinterpret_cast<uint8_t*>(packet->data()),
668667
NGTCP2_MAX_PKTLEN_IPV4,
669-
token,
668+
const_cast<uint8_t*>(token.data()),
670669
random,
671670
kRandlen);
672671
if (nwrite < static_cast<ssize_t>(kMinStatelessResetLen))

src/quic/node_quic_util-inl.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,20 @@ bool QuicPreferredAddress::ResolvePreferredAddress(
274274
req->addrinfo != nullptr;
275275
}
276276

277+
StatelessResetToken::StatelessResetToken(
278+
uint8_t* token,
279+
const uint8_t* secret,
280+
const QuicCID& cid) : token_(token) {
281+
GenerateResetToken(token, secret, cid);
282+
}
283+
284+
StatelessResetToken::StatelessResetToken(
285+
const uint8_t* secret,
286+
const QuicCID& cid)
287+
: token_(buf_) {
288+
GenerateResetToken(buf_, secret, cid);
289+
}
290+
277291
std::string StatelessResetToken::ToHex() const {
278292
std::vector<char> dest(NGTCP2_STATELESS_RESET_TOKENLEN * 2 + 1);
279293
dest[dest.size() - 1] = '\0';

src/quic/node_quic_util.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,21 @@ class Timer final : public MemoryRetainer {
294294

295295
using TimerPointer = DeleteFnPtr<Timer, Timer::Free>;
296296

297-
class StatelessResetToken : public MemoryRetainer{
297+
class StatelessResetToken : public MemoryRetainer {
298298
public:
299-
explicit StatelessResetToken(const uint8_t* token) : token_(token) {}
299+
inline StatelessResetToken(
300+
uint8_t* token,
301+
const uint8_t* secret,
302+
const QuicCID& cid);
303+
inline StatelessResetToken(
304+
const uint8_t* secret,
305+
const QuicCID& cid);
306+
explicit StatelessResetToken(
307+
const uint8_t* token)
308+
: token_(token) {}
300309

301310
inline std::string ToHex() const;
311+
const uint8_t* data() const { return token_; }
302312

303313
struct Hash {
304314
inline size_t operator()(const StatelessResetToken& token) const;
@@ -315,6 +325,7 @@ class StatelessResetToken : public MemoryRetainer{
315325
SET_SELF_SIZE(StatelessResetToken)
316326

317327
private:
328+
uint8_t buf_[NGTCP2_STATELESS_RESET_TOKENLEN];
318329
const uint8_t* token_;
319330
};
320331

0 commit comments

Comments
 (0)