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

Commit 1f049e0

Browse files
committed
quic: fix up early QuicSession destroy
Send a stateless connection close if destroying while still in initial crypto level (there are no encryption keys at this point so we can't send a regular connection close)
1 parent abe9767 commit 1f049e0

File tree

5 files changed

+43
-16
lines changed

5 files changed

+43
-16
lines changed

src/quic/node_quic_session.cc

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,22 @@ bool QuicSession::SendConnectionClose() {
19971997
// serialize the connection close once but may end up transmitting
19981998
// it multiple times; whereas for clients, we will serialize it
19991999
// once and send once only.
2000+
QuicError error = last_error();
2001+
2002+
// If initial keys have not yet been installed, use the alternative
2003+
// ImmediateConnectionClose to send a stateless connection close to
2004+
// the peer.
2005+
if (crypto_context()->write_crypto_level() ==
2006+
NGTCP2_CRYPTO_LEVEL_INITIAL) {
2007+
socket()->ImmediateConnectionClose(
2008+
dcid(),
2009+
scid_,
2010+
local_address_,
2011+
remote_address_,
2012+
error.code);
2013+
return true;
2014+
}
2015+
20002016
switch (crypto_context_->side()) {
20012017
case NGTCP2_CRYPTO_SIDE_SERVER: {
20022018
// If we're not already in the closing period,
@@ -2005,7 +2021,7 @@ bool QuicSession::SendConnectionClose() {
20052021
// already started, skip this.
20062022
if (!is_in_closing_period() &&
20072023
(!WritePackets("server connection close - write packets") ||
2008-
!StartClosingPeriod())) {
2024+
!StartClosingPeriod())) {
20092025
return false;
20102026
}
20112027

@@ -2016,18 +2032,16 @@ bool QuicSession::SendConnectionClose() {
20162032
}
20172033
case NGTCP2_CRYPTO_SIDE_CLIENT: {
20182034
UpdateIdleTimer();
2019-
auto packet = QuicPacket::Create(
2020-
"client connection close");
2021-
QuicError error = last_error();
2035+
auto packet = QuicPacket::Create("client connection close");
20222036

20232037
// If we're not already in the closing period,
20242038
// first attempt to write any pending packets, then
20252039
// start the closing period. Note that the behavior
20262040
// here is different than the server
20272041
if (!is_in_closing_period() &&
2028-
!WritePackets("client connection close - write packets"))
2042+
!WritePackets("client connection close - write packets")) {
20292043
return false;
2030-
2044+
}
20312045
ssize_t nwrite =
20322046
SelectCloseFn(error.family)(
20332047
connection(),

src/quic/node_quic_socket.cc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -693,16 +693,18 @@ bool QuicSocket::SendRetry(
693693

694694
// Shutdown a connection prematurely, before a QuicSession is created.
695695
void QuicSocket::ImmediateConnectionClose(
696-
const ngtcp2_pkt_hd& hd,
696+
const QuicCID& scid,
697+
const QuicCID& dcid,
697698
const SocketAddress& local_addr,
698699
const SocketAddress& remote_addr,
699700
int32_t reason) {
701+
Debug(this, "Sending stateless connection close to %s", scid);
700702
auto packet = QuicPacket::Create("immediate connection close");
701703
ssize_t nwrite = ngtcp2_crypto_write_connection_close(
702704
packet->data(),
703705
packet->length(),
704-
&hd.scid,
705-
&hd.dcid,
706+
scid.cid(),
707+
dcid.cid(),
706708
reason);
707709
if (nwrite > 0) {
708710
packet->set_length(nwrite);
@@ -760,7 +762,12 @@ BaseObjectPtr<QuicSession> QuicSocket::AcceptInitialPacket(
760762
max_connections_per_host_) {
761763
Debug(this, "QuicSocket is busy or connection count exceeded");
762764
IncrementStat(&QuicSocketStats::server_busy_count);
763-
ImmediateConnectionClose(hd, local_addr, remote_addr, NGTCP2_SERVER_BUSY);
765+
ImmediateConnectionClose(
766+
QuicCID(hd.scid),
767+
QuicCID(hd.dcid),
768+
local_addr,
769+
remote_addr,
770+
NGTCP2_SERVER_BUSY);
764771
return {};
765772
}
766773

@@ -789,7 +796,11 @@ BaseObjectPtr<QuicSession> QuicSocket::AcceptInitialPacket(
789796
token_secret_,
790797
retry_token_expiration_)) {
791798
Debug(this, "Invalid retry token was detected. Failing.");
792-
ImmediateConnectionClose(hd, local_addr, remote_addr);
799+
ImmediateConnectionClose(
800+
QuicCID(hd.scid),
801+
QuicCID(hd.dcid),
802+
local_addr,
803+
remote_addr);
793804
return {};
794805
}
795806
}

src/quic/node_quic_socket.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,13 @@ class QuicSocket : public AsyncWrap,
386386

387387
inline void AddEndpoint(QuicEndpoint* endpoint, bool preferred = false);
388388

389+
void ImmediateConnectionClose(
390+
const QuicCID& scid,
391+
const QuicCID& dcid,
392+
const SocketAddress& local_addr,
393+
const SocketAddress& remote_addr,
394+
int32_t reason = NGTCP2_INVALID_TOKEN);
395+
389396
private:
390397
static void OnAlloc(
391398
uv_handle_t* handle,
@@ -405,11 +412,6 @@ class QuicSocket : public AsyncWrap,
405412
const SocketAddress& local_addr,
406413
const SocketAddress& remote_addr,
407414
unsigned int flags);
408-
void ImmediateConnectionClose(
409-
const ngtcp2_pkt_hd& hd,
410-
const SocketAddress& local_addr,
411-
const SocketAddress& remote_addr,
412-
int32_t reason = NGTCP2_INVALID_TOKEN);
413415

414416
BaseObjectPtr<QuicSession> AcceptInitialPacket(
415417
uint32_t version,
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)