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";
}