Skip to content

Commit 6b45201

Browse files
authored
Don't send client CONNECTION_CLOSE on 1-RTT before handshake completion. (#4145)
1 parent c66e7fe commit 6b45201

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

src/core/packet_builder.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,8 +479,22 @@ QuicPacketBuilderGetPacketTypeAndKeyForControlFrames(
479479
CXPLAT_DBG_ASSERT(SendFlags != 0);
480480
QuicSendValidate(&Builder->Connection->Send);
481481

482+
QUIC_PACKET_KEY_TYPE MaxKeyType = Connection->Crypto.TlsState.WriteKey;
483+
484+
if (QuicConnIsClient(Connection) &&
485+
!Connection->State.HandshakeConfirmed &&
486+
MaxKeyType == QUIC_PACKET_KEY_1_RTT &&
487+
(SendFlags & QUIC_CONN_SEND_FLAG_CONNECTION_CLOSE)) {
488+
//
489+
// Server is not allowed to process 1-RTT packets until the handshake is confirmed and since we are
490+
// closing the connection, the handshake is unlikely to complete. Ensure the CONNECTION_CLOSE is sent
491+
// in a packet which server can process.
492+
//
493+
MaxKeyType = QUIC_PACKET_KEY_HANDSHAKE;
494+
}
495+
482496
for (QUIC_PACKET_KEY_TYPE KeyType = 0;
483-
KeyType <= Connection->Crypto.TlsState.WriteKey;
497+
KeyType <= MaxKeyType;
484498
++KeyType) {
485499

486500
if (KeyType == QUIC_PACKET_KEY_0_RTT) {
@@ -538,7 +552,7 @@ QuicPacketBuilderGetPacketTypeAndKeyForControlFrames(
538552
if (Connection->Crypto.TlsState.WriteKey == QUIC_PACKET_KEY_0_RTT) {
539553
*PacketKeyType = QUIC_PACKET_KEY_INITIAL;
540554
} else {
541-
*PacketKeyType = Connection->Crypto.TlsState.WriteKey;
555+
*PacketKeyType = MaxKeyType;
542556
}
543557
return TRUE;
544558
}

src/test/lib/HandshakeTest.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -885,13 +885,11 @@ QuicTestCustomServerCertificateValidation(
885885
}
886886
TEST_EQUAL(AcceptCert, Client.GetIsConnected());
887887

888-
if (AcceptCert) { // Server will be deleted on reject case, so can't validate.
889-
TEST_NOT_EQUAL(nullptr, Server);
890-
if (!Server->WaitForConnectionComplete()) {
891-
return;
892-
}
893-
TEST_TRUE(Server->GetIsConnected());
888+
TEST_NOT_EQUAL(nullptr, Server);
889+
if (!Server->WaitForConnectionComplete()) {
890+
return;
894891
}
892+
TEST_EQUAL(AcceptCert, Server->GetIsConnected());
895893
}
896894
}
897895
}
@@ -998,16 +996,15 @@ QuicTestCustomClientCertificateValidation(
998996
if (!Client.WaitForConnectionComplete()) {
999997
return;
1000998
}
1001-
1002-
if (AcceptCert) { // Server will be deleted on reject case, so can't validate.
1003-
TEST_NOT_EQUAL(nullptr, Server);
1004-
if (!Server->WaitForConnectionComplete()) {
1005-
return;
1006-
}
1007-
TEST_TRUE(Server->GetIsConnected());
1008-
}
1009999
// In all cases, the client "connects", but in the rejection case, it gets disconnected.
10101000
TEST_TRUE(Client.GetIsConnected());
1001+
1002+
TEST_NOT_EQUAL(nullptr, Server);
1003+
if (!Server->WaitForConnectionComplete()) {
1004+
return;
1005+
}
1006+
1007+
TEST_EQUAL(AcceptCert, Server->GetIsConnected());
10111008
}
10121009
}
10131010
}

0 commit comments

Comments
 (0)