Add KeyUpdateReason enum to KeyUpdate call & OnKeyUpdate callbacks. PiperOrigin-RevId: 337886250 Change-Id: I1a8ebf0212f8c3b9a80d47bc93c243f6cd2c128c
diff --git a/quic/core/chlo_extractor.cc b/quic/core/chlo_extractor.cc index 33f6c0e..e469e0d 100644 --- a/quic/core/chlo_extractor.cc +++ b/quic/core/chlo_extractor.cc
@@ -82,7 +82,7 @@ bool IsValidStatelessResetToken(QuicUint128 token) const override; void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& /*packet*/) override {} - void OnKeyUpdate() override; + void OnKeyUpdate(KeyUpdateReason /*reason*/) override; void OnDecryptedFirstPacketInKeyPhase() override; std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() override; @@ -315,7 +315,7 @@ return true; } -void ChloFramerVisitor::OnKeyUpdate() {} +void ChloFramerVisitor::OnKeyUpdate(KeyUpdateReason /*reason*/) {} void ChloFramerVisitor::OnDecryptedFirstPacketInKeyPhase() {}
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc index 025e257..fe58711 100644 --- a/quic/core/http/end_to_end_test.cc +++ b/quic/core/http/end_to_end_test.cc
@@ -4833,14 +4833,16 @@ ASSERT_TRUE(client_connection); EXPECT_EQ(0u, client_connection->GetStats().key_update_count); - EXPECT_TRUE(client_connection->InitiateKeyUpdate()); + EXPECT_TRUE( + client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); SendSynchronousFooRequestAndCheckResponse(); EXPECT_EQ(1u, client_connection->GetStats().key_update_count); SendSynchronousFooRequestAndCheckResponse(); EXPECT_EQ(1u, client_connection->GetStats().key_update_count); - EXPECT_TRUE(client_connection->InitiateKeyUpdate()); + EXPECT_TRUE( + client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); SendSynchronousFooRequestAndCheckResponse(); EXPECT_EQ(2u, client_connection->GetStats().key_update_count); @@ -4883,7 +4885,8 @@ // key phase, wait a bit and try again. return false; } - EXPECT_TRUE(server_connection->InitiateKeyUpdate()); + EXPECT_TRUE(server_connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForTests)); } else { ADD_FAILURE() << "Missing server connection"; } @@ -4904,7 +4907,8 @@ if (!server_connection->IsKeyUpdateAllowed()) { return false; } - EXPECT_TRUE(server_connection->InitiateKeyUpdate()); + EXPECT_TRUE(server_connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForTests)); } else { ADD_FAILURE() << "Missing server connection"; } @@ -4956,7 +4960,8 @@ // key phase, wait a bit and try again. return false; } - EXPECT_TRUE(server_connection->InitiateKeyUpdate()); + EXPECT_TRUE(server_connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForTests)); } else { ADD_FAILURE() << "Missing server connection"; } @@ -4965,7 +4970,8 @@ QuicTime::Delta::FromSeconds(5)); QuicConnection* client_connection = GetClientConnection(); ASSERT_TRUE(client_connection); - EXPECT_TRUE(client_connection->InitiateKeyUpdate()); + EXPECT_TRUE( + client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); SendSynchronousFooRequestAndCheckResponse(); EXPECT_EQ(1u, client_connection->GetStats().key_update_count); @@ -4980,14 +4986,16 @@ if (!server_connection->IsKeyUpdateAllowed()) { return false; } - EXPECT_TRUE(server_connection->InitiateKeyUpdate()); + EXPECT_TRUE(server_connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForTests)); } else { ADD_FAILURE() << "Missing server connection"; } return true; }, QuicTime::Delta::FromSeconds(5)); - EXPECT_TRUE(client_connection->InitiateKeyUpdate()); + EXPECT_TRUE( + client_connection->InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); SendSynchronousFooRequestAndCheckResponse(); EXPECT_EQ(2u, client_connection->GetStats().key_update_count);
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index e9fd55e..0aa7a4d 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -1932,9 +1932,9 @@ ConnectionCloseSource::FROM_PEER); } -void QuicConnection::OnKeyUpdate() { +void QuicConnection::OnKeyUpdate(KeyUpdateReason reason) { DCHECK(support_key_update_for_connection_); - QUIC_DLOG(INFO) << ENDPOINT << "Key phase updated"; + QUIC_DLOG(INFO) << ENDPOINT << "Key phase updated for " << reason; lowest_packet_sent_in_current_key_phase_.Clear(); stats_.key_update_count++; @@ -3189,6 +3189,7 @@ // Approaching the confidentiality limit, initiate key update so that // the next set of keys will be ready for the next packet before the // limit is reached. + KeyUpdateReason reason = KeyUpdateReason::kLocalAeadConfidentialityLimit; if (key_update_limit_override) { QUIC_DLOG(INFO) << ENDPOINT << "reached FLAGS_quic_key_update_confidentiality_limit, " @@ -3197,6 +3198,7 @@ << num_packets_encrypted_in_current_key_phase << " key_update_limit=" << key_update_limit << " confidentiality_limit=" << confidentiality_limit; + reason = KeyUpdateReason::kLocalKeyUpdateLimitOverride; } else { QUIC_DLOG(INFO) << ENDPOINT << "approaching AEAD confidentiality limit, " @@ -3206,7 +3208,7 @@ << " key_update_limit=" << key_update_limit << " confidentiality_limit=" << confidentiality_limit; } - InitiateKeyUpdate(); + InitiateKeyUpdate(reason); } return false; @@ -3683,13 +3685,13 @@ GetLargestAckedPacket() >= lowest_packet_sent_in_current_key_phase_; } -bool QuicConnection::InitiateKeyUpdate() { +bool QuicConnection::InitiateKeyUpdate(KeyUpdateReason reason) { QUIC_DLOG(INFO) << ENDPOINT << "InitiateKeyUpdate"; if (!IsKeyUpdateAllowed()) { QUIC_BUG << "key update not allowed"; return false; } - return framer_.DoKeyUpdate(); + return framer_.DoKeyUpdate(reason); } const QuicDecrypter* QuicConnection::decrypter() const {
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h index 2932584..2fc8c8a 100644 --- a/quic/core/quic_connection.h +++ b/quic/core/quic_connection.h
@@ -646,7 +646,7 @@ bool IsValidStatelessResetToken(QuicUint128 token) const override; void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& packet) override; - void OnKeyUpdate() override; + void OnKeyUpdate(KeyUpdateReason reason) override; void OnDecryptedFirstPacketInKeyPhase() override; std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() override; @@ -819,7 +819,7 @@ // Increment the key phase. It is a bug to call this when IsKeyUpdateAllowed() // is false. Returns false on error. - bool InitiateKeyUpdate(); + bool InitiateKeyUpdate(KeyUpdateReason reason); const QuicDecrypter* decrypter() const; const QuicDecrypter* alternative_decrypter() const;
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index 42d19e2..483ddb1 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -12096,7 +12096,7 @@ EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); }); - EXPECT_TRUE(connection_.InitiateKeyUpdate()); + EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); // discard_previous_keys_alarm_ should not be set until a packet from the new // key phase has been received. (The alarm that was set above should be // cleared if it hasn't fired before the next key update happened.) @@ -12110,7 +12110,7 @@ EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter()) .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x02); }); peer_framer_.SetKeyUpdateSupportForConnection(true); - peer_framer_.DoKeyUpdate(); + peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote); // Another key update should not be allowed yet. EXPECT_FALSE(connection_.IsKeyUpdateAllowed()); @@ -12132,7 +12132,7 @@ EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x03); }); - EXPECT_TRUE(connection_.InitiateKeyUpdate()); + EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); // Pretend that peer accepts the key update. EXPECT_CALL(peer_framer_visitor_, @@ -12141,7 +12141,7 @@ []() { return std::make_unique<StrictTaggingDecrypter>(0x03); }); EXPECT_CALL(peer_framer_visitor_, CreateCurrentOneRttEncrypter()) .WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x03); }); - peer_framer_.DoKeyUpdate(); + peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote); // Another key update should not be allowed yet. EXPECT_FALSE(connection_.IsKeyUpdateAllowed()); @@ -12166,7 +12166,7 @@ EXPECT_CALL(visitor_, CreateCurrentOneRttEncrypter()).WillOnce([]() { return std::make_unique<TaggingEncrypter>(0x04); }); - EXPECT_TRUE(connection_.InitiateKeyUpdate()); + EXPECT_TRUE(connection_.InitiateKeyUpdate(KeyUpdateReason::kLocalForTests)); EXPECT_FALSE(connection_.GetDiscardPreviousOneRttKeysAlarm()->IsSet()); } @@ -12254,7 +12254,7 @@ .WillOnce([current_tag]() { return std::make_unique<TaggingEncrypter>(current_tag); }); - peer_framer_.DoKeyUpdate(); + peer_framer_.DoKeyUpdate(KeyUpdateReason::kRemote); } // Receive ack for packet. EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc index f775afb..a5cc8bd 100644 --- a/quic/core/quic_framer.cc +++ b/quic/core/quic_framer.cc
@@ -4255,7 +4255,7 @@ previous_decrypter_ = nullptr; } -bool QuicFramer::DoKeyUpdate() { +bool QuicFramer::DoKeyUpdate(KeyUpdateReason reason) { DCHECK(support_key_update_for_connection_); if (!next_decrypter_) { // If key update is locally initiated, next decrypter might not be created @@ -4275,7 +4275,7 @@ previous_decrypter_ = std::move(decrypter_[ENCRYPTION_FORWARD_SECURE]); decrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_decrypter_); encrypter_[ENCRYPTION_FORWARD_SECURE] = std::move(next_encrypter); - visitor_->OnKeyUpdate(); + visitor_->OnKeyUpdate(reason); return true; } @@ -4750,7 +4750,7 @@ visitor_->OnDecryptedPacket(level); *decrypted_level = level; if (attempt_key_update) { - if (!DoKeyUpdate()) { + if (!DoKeyUpdate(KeyUpdateReason::kRemote)) { set_detailed_error("Key update failed due to internal error"); return RaiseError(QUIC_INTERNAL_ERROR); }
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h index f029dd1..5d9bf46 100644 --- a/quic/core/quic_framer.h +++ b/quic/core/quic_framer.h
@@ -241,7 +241,7 @@ // Called when a Key Phase Update has been initiated. This is called for both // locally and peer initiated key updates. If the key update was locally // initiated, this does not indicate the peer has received the key update yet. - virtual void OnKeyUpdate() = 0; + virtual void OnKeyUpdate(KeyUpdateReason reason) = 0; // Called on the first decrypted packet in each key phase (including the // first key phase.) @@ -546,7 +546,7 @@ // Discard the decrypter for the previous key phase. void DiscardPreviousOneRttKeys(); // Update the key phase. - bool DoKeyUpdate(); + bool DoKeyUpdate(KeyUpdateReason reason); const QuicDecrypter* GetDecrypter(EncryptionLevel level) const; const QuicDecrypter* decrypter() const;
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc index e21b2ef..949d246 100644 --- a/quic/core/quic_framer_test.cc +++ b/quic/core/quic_framer_test.cc
@@ -221,7 +221,6 @@ packet_count_(0), frame_count_(0), complete_packets_(0), - key_update_count_(0), derive_next_key_count_(0), decrypted_first_packet_in_key_phase_count_(0), accept_packet_(true), @@ -578,7 +577,9 @@ EXPECT_EQ(0u, framer_->current_received_frame_type()); } - void OnKeyUpdate() override { key_update_count_++; } + void OnKeyUpdate(KeyUpdateReason reason) override { + key_update_reasons_.push_back(reason); + } void OnDecryptedFirstPacketInKeyPhase() override { decrypted_first_packet_in_key_phase_count_++; @@ -598,13 +599,15 @@ transport_version_ = framer->transport_version(); } + size_t key_update_count() const { return key_update_reasons_.size(); } + // Counters from the visitor_ callbacks. int error_count_; int version_mismatch_; int packet_count_; int frame_count_; int complete_packets_; - int key_update_count_; + std::vector<KeyUpdateReason> key_update_reasons_; int derive_next_key_count_; int decrypted_first_packet_in_key_phase_count_; bool accept_packet_; @@ -14838,7 +14841,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); // Processed valid packet with phase=0, key=1: no key update. - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(0, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -14852,7 +14855,8 @@ EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); // Processed valid packet with phase=1, key=2: key update should have // occurred. - EXPECT_EQ(1, visitor_.key_update_count_); + ASSERT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[0]); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -14865,7 +14869,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); // Processed another valid packet with phase=1, key=2: no key update. - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -14878,7 +14882,8 @@ ASSERT_TRUE(encrypted); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(2, visitor_.key_update_count_); + ASSERT_EQ(2u, visitor_.key_update_count()); + EXPECT_EQ(KeyUpdateReason::kRemote, visitor_.key_update_reasons_[1]); EXPECT_EQ(2, visitor_.derive_next_key_count_); EXPECT_EQ(3, visitor_.decrypted_first_packet_in_key_phase_count_); } @@ -14912,7 +14917,7 @@ ASSERT_TRUE(encrypted); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(0, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -14925,7 +14930,7 @@ ASSERT_TRUE(encrypted); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -14940,7 +14945,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); // Packet should decrypt and key update count should not change. EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); } @@ -14974,7 +14979,7 @@ ASSERT_TRUE(encrypted); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(0, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -14987,7 +14992,7 @@ ASSERT_TRUE(encrypted); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15005,7 +15010,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); // Packet should not decrypt and key update count should not change. EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); } @@ -15039,7 +15044,7 @@ ASSERT_TRUE(encrypted); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(0, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15052,7 +15057,7 @@ ASSERT_TRUE(encrypted); QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15067,7 +15072,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); // Packet should decrypt and key update count should not change. EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(2, visitor_.decrypted_first_packet_in_key_phase_count_); } @@ -15102,7 +15107,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); // Processed valid packet with phase=0, key=1: no key update. - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(0, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15117,7 +15122,7 @@ // update, but next decrypter key should have been created to attempt to // decode it. EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15131,7 +15136,7 @@ // Packet with phase=1 but key=1, should not process and should not cause key // update. EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15145,7 +15150,7 @@ // Packet with phase=0 but key=2, should not process and should not cause key // update. EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); } @@ -15181,7 +15186,7 @@ // update enabled (SetNextOneRttCrypters never called). Should fail to // process. EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(0, visitor_.key_update_count_); + EXPECT_EQ(0u, visitor_.key_update_count()); EXPECT_EQ(0, visitor_.derive_next_key_count_); EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_); } @@ -15198,10 +15203,11 @@ std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); framer_.SetKeyUpdateSupportForConnection(true); - EXPECT_TRUE(framer_.DoKeyUpdate()); + EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests)); // Key update count should be updated, but haven't received packet from peer // with new key phase. - EXPECT_EQ(1, visitor_.key_update_count_); + ASSERT_EQ(1u, visitor_.key_update_count()); + EXPECT_EQ(KeyUpdateReason::kLocalForTests, visitor_.key_update_reasons_[0]); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15225,7 +15231,7 @@ // Packet should decrypt and key update count should not change and // OnDecryptedFirstPacketInKeyPhase should have been called. EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15240,7 +15246,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); // Packet should decrypt and key update count should not change. EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15256,7 +15262,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); // Packet should not decrypt and key update count should not change. EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(2, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); } @@ -15273,10 +15279,10 @@ std::make_unique<StrictTaggingDecrypter>(/*key=*/0)); framer_.SetKeyUpdateSupportForConnection(true); - EXPECT_TRUE(framer_.DoKeyUpdate()); + EXPECT_TRUE(framer_.DoKeyUpdate(KeyUpdateReason::kLocalForTests)); // Key update count should be updated, but haven't received packet // from peer with new key phase. - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15302,7 +15308,7 @@ // OnDecryptedFirstPacketInKeyPhase should not have been called since the // packet was from the previous key phase. EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(0, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15317,7 +15323,7 @@ // Packet should decrypt and key update count should not change, but // OnDecryptedFirstPacketInKeyPhase should have been called. EXPECT_TRUE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(1, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); @@ -15333,7 +15339,7 @@ QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER); // Packet should not decrypt and key update count should not change. EXPECT_FALSE(framer_.ProcessPacket(*encrypted)); - EXPECT_EQ(1, visitor_.key_update_count_); + EXPECT_EQ(1u, visitor_.key_update_count()); EXPECT_EQ(2, visitor_.derive_next_key_count_); EXPECT_EQ(1, visitor_.decrypted_first_packet_in_key_phase_count_); }
diff --git a/quic/core/quic_types.cc b/quic/core/quic_types.cc index 4027ffa..9eb0a27 100644 --- a/quic/core/quic_types.cc +++ b/quic/core/quic_types.cc
@@ -363,6 +363,29 @@ return os; } +std::string KeyUpdateReasonString(KeyUpdateReason reason) { +#define RETURN_REASON_LITERAL(x) \ + case KeyUpdateReason::x: \ + return #x + switch (reason) { + RETURN_REASON_LITERAL(kInvalid); + RETURN_REASON_LITERAL(kRemote); + RETURN_REASON_LITERAL(kLocalForTests); + RETURN_REASON_LITERAL(kLocalForInteropRunner); + RETURN_REASON_LITERAL(kLocalAeadConfidentialityLimit); + RETURN_REASON_LITERAL(kLocalKeyUpdateLimitOverride); + default: + return quiche::QuicheStrCat("Unknown(", static_cast<int>(reason), ")"); + break; + } +#undef RETURN_REASON_LITERAL +} + +std::ostream& operator<<(std::ostream& os, const KeyUpdateReason reason) { + os << KeyUpdateReasonString(reason); + return os; +} + #undef RETURN_STRING_LITERAL // undef for jumbo builds } // namespace quic
diff --git a/quic/core/quic_types.h b/quic/core/quic_types.h index 4a896a0..514c91f 100644 --- a/quic/core/quic_types.h +++ b/quic/core/quic_types.h
@@ -798,6 +798,21 @@ } }; +// These values must remain stable as they are uploaded to UMA histograms. +enum class KeyUpdateReason { + kInvalid = 0, + kRemote = 1, + kLocalForTests = 2, + kLocalForInteropRunner = 3, + kLocalAeadConfidentialityLimit = 4, + kLocalKeyUpdateLimitOverride = 5, +}; + +QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, + const KeyUpdateReason reason); + +QUIC_EXPORT_PRIVATE std::string KeyUpdateReasonString(KeyUpdateReason reason); + } // namespace quic #endif // QUICHE_QUIC_CORE_QUIC_TYPES_H_
diff --git a/quic/core/tls_chlo_extractor.h b/quic/core/tls_chlo_extractor.h index 6d2f254..718e5fa 100644 --- a/quic/core/tls_chlo_extractor.h +++ b/quic/core/tls_chlo_extractor.h
@@ -160,7 +160,7 @@ } void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& /*packet*/) override {} - void OnKeyUpdate() override {} + void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} void OnDecryptedFirstPacketInKeyPhase() override {} std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() override {
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h index a46a11b..e577174 100644 --- a/quic/test_tools/quic_test_utils.h +++ b/quic/test_tools/quic_test_utils.h
@@ -424,7 +424,7 @@ OnAuthenticatedIetfStatelessResetPacket, (const QuicIetfStatelessResetPacket&), (override)); - MOCK_METHOD(void, OnKeyUpdate, (), (override)); + MOCK_METHOD(void, OnKeyUpdate, (KeyUpdateReason), (override)); MOCK_METHOD(void, OnDecryptedFirstPacketInKeyPhase, (), (override)); MOCK_METHOD(std::unique_ptr<QuicDecrypter>, AdvanceKeysAndCreateCurrentOneRttDecrypter, @@ -493,7 +493,7 @@ bool IsValidStatelessResetToken(QuicUint128 token) const override; void OnAuthenticatedIetfStatelessResetPacket( const QuicIetfStatelessResetPacket& /*packet*/) override {} - void OnKeyUpdate() override {} + void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} void OnDecryptedFirstPacketInKeyPhase() override {} std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() override {
diff --git a/quic/test_tools/simple_quic_framer.cc b/quic/test_tools/simple_quic_framer.cc index 4a77331..ccce52b 100644 --- a/quic/test_tools/simple_quic_framer.cc +++ b/quic/test_tools/simple_quic_framer.cc
@@ -220,7 +220,7 @@ std::make_unique<QuicIetfStatelessResetPacket>(packet); } - void OnKeyUpdate() override {} + void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} void OnDecryptedFirstPacketInKeyPhase() override {} std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() override {
diff --git a/quic/tools/quic_client_interop_test_bin.cc b/quic/tools/quic_client_interop_test_bin.cc index 15871d8..6f9f685 100644 --- a/quic/tools/quic_client_interop_test_bin.cc +++ b/quic/tools/quic_client_interop_test_bin.cc
@@ -299,7 +299,8 @@ if (attempt_key_update) { if (connection->IsKeyUpdateAllowed()) { - if (connection->InitiateKeyUpdate()) { + if (connection->InitiateKeyUpdate( + KeyUpdateReason::kLocalForInteropRunner)) { client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true); if (!client->connected()) { // Key update does not work, retry without attempting it.
diff --git a/quic/tools/quic_packet_printer_bin.cc b/quic/tools/quic_packet_printer_bin.cc index e64e1ac..6f9a658 100644 --- a/quic/tools/quic_packet_printer_bin.cc +++ b/quic/tools/quic_packet_printer_bin.cc
@@ -220,7 +220,9 @@ const QuicIetfStatelessResetPacket& /*packet*/) override { std::cerr << "OnAuthenticatedIetfStatelessResetPacket\n"; } - void OnKeyUpdate() override { std::cerr << "OnKeyUpdate\n"; } + void OnKeyUpdate(KeyUpdateReason reason) override { + std::cerr << "OnKeyUpdate: " << reason << "\n"; + } void OnDecryptedFirstPacketInKeyPhase() override { std::cerr << "OnDecryptedFirstPacketInKeyPhase\n"; }