Notify debug_visitor once any 0-RTT packet gets acknowledged. Client only (server + TLS does not send 0-RTT packets).
PiperOrigin-RevId: 333813151
Change-Id: I468d0da1bd9df984bc7c3f836dcff58e5329e547
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 15298fe..642ebc7 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1319,6 +1319,8 @@
}
const bool one_rtt_packet_was_acked =
sent_packet_manager_.one_rtt_packet_acked();
+ const bool zero_rtt_packet_was_acked =
+ sent_packet_manager_.zero_rtt_packet_acked();
const AckResult ack_result = sent_packet_manager_.OnAckFrameEnd(
idle_network_detector_.time_of_last_received_packet(),
last_header_.packet_number, last_decrypted_packet_level_);
@@ -1335,6 +1337,11 @@
sent_packet_manager_.one_rtt_packet_acked()) {
visitor_->OnOneRttPacketAcknowledged();
}
+ if (debug_visitor_ != nullptr && version().UsesTls() &&
+ !zero_rtt_packet_was_acked &&
+ sent_packet_manager_.zero_rtt_packet_acked()) {
+ debug_visitor_->OnZeroRttPacketAcked();
+ }
// Cancel the send alarm because new packets likely have been acked, which
// may change the congestion window and/or pacing rate. Canceling the alarm
// causes CanWrite to recalculate the next send time.
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index c9d903e..e72ffb8 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -377,6 +377,9 @@
// Called for QUIC+TLS versions when 0-RTT is rejected.
virtual void OnZeroRttRejected(int /*reject_reason*/) {}
+ // Called for QUIC+TLS versions when 0-RTT packet gets acked.
+ virtual void OnZeroRttPacketAcked() {}
+
// Called on peer address change.
virtual void OnPeerAddressChange(AddressChangeType /*type*/,
QuicTime::Delta /*connection_time*/) {}
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index c26cdc8..ea73382 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -12174,6 +12174,53 @@
{{2, frames1, ENCRYPTION_INITIAL}, {3, frames2, ENCRYPTION_HANDSHAKE}});
}
+TEST_P(QuicConnectionTest, OnZeroRttPacketAcked) {
+ if (!connection_.version().UsesTls()) {
+ return;
+ }
+ MockQuicConnectionDebugVisitor debug_visitor;
+ connection_.set_debug_visitor(&debug_visitor);
+ use_tagging_decrypter();
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ std::make_unique<TaggingEncrypter>(0x01));
+ connection_.SendCryptoStreamData();
+ // Send 0-RTT packet.
+ connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
+ std::make_unique<TaggingEncrypter>(0x02));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
+ connection_.SendStreamDataWithString(2, "foo", 0, NO_FIN);
+ connection_.SendStreamDataWithString(4, "bar", 0, NO_FIN);
+ // Received ACK for packet 1, HANDSHAKE packet and 1-RTT ACK.
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _, _))
+ .Times(AnyNumber());
+ QuicFrames frames1;
+ QuicAckFrame ack_frame1 = InitAckFrame(1);
+ frames1.push_back(QuicFrame(&ack_frame1));
+
+ QuicFrames frames2;
+ QuicCryptoFrame crypto_frame(ENCRYPTION_HANDSHAKE, 0,
+ quiche::QuicheStringPiece(data1));
+ frames2.push_back(QuicFrame(&crypto_frame));
+ EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+ ProcessCoalescedPacket(
+ {{1, frames1, ENCRYPTION_INITIAL}, {2, frames2, ENCRYPTION_HANDSHAKE}});
+
+ QuicFrames frames3;
+ QuicAckFrame ack_frame2 =
+ InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
+ frames3.push_back(QuicFrame(&ack_frame2));
+ EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(1);
+ ProcessCoalescedPacket({{3, frames3, ENCRYPTION_FORWARD_SECURE}});
+
+ QuicFrames frames4;
+ QuicAckFrame ack_frame3 =
+ InitAckFrame({{QuicPacketNumber(3), QuicPacketNumber(4)}});
+ frames4.push_back(QuicFrame(&ack_frame3));
+ EXPECT_CALL(debug_visitor, OnZeroRttPacketAcked()).Times(0);
+ ProcessCoalescedPacket({{4, frames4, ENCRYPTION_FORWARD_SECURE}});
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc
index f453619..4dc2582 100644
--- a/quic/core/quic_sent_packet_manager.cc
+++ b/quic/core/quic_sent_packet_manager.cc
@@ -105,6 +105,7 @@
pto_rttvar_multiplier_(4),
num_tlp_timeout_ptos_(0),
handshake_packet_acked_(false),
+ zero_rtt_packet_acked_(false),
one_rtt_packet_acked_(false),
one_rtt_packet_sent_(false),
first_pto_srtt_multiplier_(0),
@@ -1475,8 +1476,9 @@
last_ack_frame_.packets.Add(acked_packet.packet_number);
if (info->encryption_level == ENCRYPTION_HANDSHAKE) {
handshake_packet_acked_ = true;
- }
- if (info->encryption_level == ENCRYPTION_FORWARD_SECURE) {
+ } else if (info->encryption_level == ENCRYPTION_ZERO_RTT) {
+ zero_rtt_packet_acked_ = true;
+ } else if (info->encryption_level == ENCRYPTION_FORWARD_SECURE) {
one_rtt_packet_acked_ = true;
}
largest_packet_peer_knows_is_acked_.UpdateMax(info->largest_acked);
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h
index 3420140..6e36da9 100644
--- a/quic/core/quic_sent_packet_manager.h
+++ b/quic/core/quic_sent_packet_manager.h
@@ -436,6 +436,8 @@
return skip_packet_number_for_pto_;
}
+ bool zero_rtt_packet_acked() const { return zero_rtt_packet_acked_; }
+
bool one_rtt_packet_acked() const { return one_rtt_packet_acked_; }
void OnUserAgentIdKnown() { loss_algorithm_->OnUserAgentIdKnown(); }
@@ -697,6 +699,9 @@
// True if any ENCRYPTION_HANDSHAKE packet gets acknowledged.
bool handshake_packet_acked_;
+ // True if any 0-RTT packet gets acknowledged.
+ bool zero_rtt_packet_acked_;
+
// True if any 1-RTT packet gets acknowledged.
bool one_rtt_packet_acked_;
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
index a47bdd1..cd87b5b 100644
--- a/quic/test_tools/quic_test_utils.h
+++ b/quic/test_tools/quic_test_utils.h
@@ -1482,6 +1482,7 @@
(override));
MOCK_METHOD(void, OnZeroRttRejected, (int), (override));
+ MOCK_METHOD(void, OnZeroRttPacketAcked, (), (override));
};
class MockReceivedPacketManager : public QuicReceivedPacketManager {