gfe-relnote: In QUIC, enable multiple packet number support in QuicConnection when using TLS as handshake protocol. Protected by existing flags quic_validate_packet_number_post_decryption, quic_deprecate_ack_bundling_mode, quic_rpm_decides_when_to_send_acks, quic_use_uber_received_packet_manager, quic_use_uber_loss_algorithm, quic_quic_enable_accept_random_ipn.
When multiple packet number spaces is supported, an ACK frame will be bundled with connection close only if the connection is not write blocked.
PiperOrigin-RevId: 239903685
Change-Id: Id10874e85109080a0f5554a68a909ccc789cc180
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 24cbb6d..cdfef6f 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -82,8 +82,12 @@
QuicConnection::ScopedPacketFlusher flusher(connection_,
QuicConnection::SEND_ACK);
if (connection_->packet_generator().deprecate_ack_bundling_mode()) {
- DCHECK(!connection_->GetUpdatedAckFrame().ack_frame->packets.Empty());
- connection_->SendAck();
+ if (connection_->SupportsMultiplePacketNumberSpaces()) {
+ connection_->SendAllPendingAcks();
+ } else {
+ DCHECK(!connection_->GetUpdatedAckFrame().ack_frame->packets.Empty());
+ connection_->SendAck();
+ }
}
}
@@ -414,6 +418,7 @@
received_packet_manager_.set_max_ack_ranges(255);
}
MaybeEnableSessionDecidesWhatToWrite();
+ MaybeEnableMultiplePacketNumberSpacesSupport();
DCHECK(!GetQuicRestartFlag(quic_no_server_conn_ver_negotiation2) ||
perspective_ == Perspective::IS_CLIENT ||
supported_versions.size() == 1);
@@ -1969,15 +1974,18 @@
if (received_packet_manager_.decide_when_to_send_acks()) {
const QuicTime ack_timeout =
use_uber_received_packet_manager_
- ? uber_received_packet_manager_.GetAckTimeout(
- QuicUtils::GetPacketNumberSpace(encryption_level_))
+ ? uber_received_packet_manager_.GetEarliestAckTimeout()
: received_packet_manager_.ack_timeout();
if (ack_timeout.IsInitialized() &&
ack_timeout <= clock_->ApproximateNow()) {
// Send an ACK now because either 1) we were write blocked when we last
// tried to send an ACK, or 2) both ack alarm and send alarm were set to
// go off together.
- SendAck();
+ if (SupportsMultiplePacketNumberSpaces()) {
+ SendAllPendingAcks();
+ } else {
+ SendAck();
+ }
}
} else if (send_ack_when_on_can_write_) {
// Send an ACK now because either 1) we were write blocked when we last
@@ -2110,6 +2118,11 @@
}
}
+ if (use_uber_received_packet_manager_) {
+ // When using uber_received_packet_manager, accept any packet numbers.
+ return true;
+ }
+
if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
QUIC_RESTART_FLAG_COUNT_N(quic_enable_accept_random_ipn, 2, 2);
// Configured to accept any packet number in range 1...0x7fffffff as initial
@@ -2131,18 +2144,17 @@
}
return true;
}
- const QuicPacketNumber peer_first_sending_packet_number =
- use_uber_received_packet_manager_
- ? uber_received_packet_manager_.PeerFirstSendingPacketNumber()
- : received_packet_manager_.PeerFirstSendingPacketNumber();
- if (packet_number > peer_first_sending_packet_number &&
+
+ if (packet_number > received_packet_manager_.PeerFirstSendingPacketNumber() &&
packet_number <= MaxRandomInitialPacketNumber()) {
QUIC_CODE_COUNT_N(had_possibly_random_ipn, 2, 2);
}
const bool out_of_bound =
last_header_.packet_number.IsInitialized()
? !Near(packet_number, last_header_.packet_number)
- : packet_number >= (peer_first_sending_packet_number + kMaxPacketGap);
+ : packet_number >=
+ (received_packet_manager_.PeerFirstSendingPacketNumber() +
+ kMaxPacketGap);
if (!out_of_bound) {
return true;
}
@@ -2725,6 +2737,7 @@
}
void QuicConnection::SendAck() {
+ DCHECK(!SupportsMultiplePacketNumberSpaces());
if (!received_packet_manager_.decide_when_to_send_acks()) {
// When received_packet_manager decides when to send ack, delaying
// ResetAckStates until ACK is successfully flushed.
@@ -2985,7 +2998,10 @@
}
ClearQueuedPackets();
ScopedPacketFlusher flusher(this, ack_mode);
- if (packet_generator_.deprecate_ack_bundling_mode() && ack_mode == SEND_ACK &&
+ // When multiple packet number spaces is supported, an ACK frame will be
+ // bundled when connection is not write blocked.
+ if (!SupportsMultiplePacketNumberSpaces() &&
+ packet_generator_.deprecate_ack_bundling_mode() && ack_mode == SEND_ACK &&
!GetUpdatedAckFrame().ack_frame->packets.Empty()) {
SendAck();
}
@@ -3283,9 +3299,8 @@
if (connection_->received_packet_manager_.decide_when_to_send_acks()) {
const QuicTime ack_timeout =
connection_->use_uber_received_packet_manager_
- ? connection_->uber_received_packet_manager_.GetAckTimeout(
- QuicUtils::GetPacketNumberSpace(
- connection_->encryption_level_))
+ ? connection_->uber_received_packet_manager_
+ .GetEarliestAckTimeout()
: connection_->received_packet_manager_.ack_timeout();
if (ack_timeout.IsInitialized()) {
if (ack_timeout <= connection_->clock_->ApproximateNow() &&
@@ -3313,6 +3328,8 @@
.decide_when_to_send_acks()) {
connection_->send_ack_when_on_can_write_ = true;
}
+ } else if (connection_->SupportsMultiplePacketNumberSpaces()) {
+ connection_->SendAllPendingAcks();
} else {
connection_->SendAck();
}
@@ -3901,20 +3918,110 @@
return ENCRYPTION_INITIAL;
}
+void QuicConnection::SendAllPendingAcks() {
+ DCHECK(SupportsMultiplePacketNumberSpaces());
+ QUIC_DVLOG(1) << ENDPOINT << "Trying to send all pending ACKs";
+ // Latches current encryption level.
+ const EncryptionLevel current_encryption_level = encryption_level_;
+ for (int8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
+ const QuicTime ack_timeout = uber_received_packet_manager_.GetAckTimeout(
+ static_cast<PacketNumberSpace>(i));
+ if (!ack_timeout.IsInitialized() ||
+ ack_timeout > clock_->ApproximateNow()) {
+ continue;
+ }
+ QUIC_DVLOG(1) << ENDPOINT << "Sending ACK of packet number space: "
+ << static_cast<uint32_t>(i);
+ // Switch to the appropriate encryption level.
+ SetDefaultEncryptionLevel(
+ QuicUtils::GetEncryptionLevel(static_cast<PacketNumberSpace>(i)));
+ QuicFrames frames;
+ frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
+ static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
+ const bool flushed = packet_generator_.FlushAckFrame(frames);
+ if (!flushed) {
+ // Connection is write blocked.
+ break;
+ }
+ ResetAckStates();
+ }
+ // Restores encryption level.
+ SetDefaultEncryptionLevel(current_encryption_level);
+
+ const QuicTime timeout =
+ uber_received_packet_manager_.GetEarliestAckTimeout();
+ if (timeout.IsInitialized()) {
+ // If there are ACKs pending, re-arm ack alarm.
+ ack_alarm_->Set(timeout);
+ }
+ // Only try to bundle retransmittable data with ACK frame if default
+ // encryption level is forward secure.
+ if (encryption_level_ != ENCRYPTION_FORWARD_SECURE ||
+ consecutive_num_packets_with_no_retransmittable_frames_ <
+ max_consecutive_num_packets_with_no_retransmittable_frames_) {
+ return;
+ }
+ consecutive_num_packets_with_no_retransmittable_frames_ = 0;
+ if (packet_generator_.HasRetransmittableFrames() ||
+ visitor_->WillingAndAbleToWrite()) {
+ // There are pending retransmittable frames.
+ return;
+ }
+
+ visitor_->OnAckNeedsRetransmittableFrame();
+}
+
+void QuicConnection::MaybeEnableMultiplePacketNumberSpacesSupport() {
+ const bool enable_multiple_packet_number_spaces =
+ version().handshake_protocol == PROTOCOL_TLS1_3 &&
+ use_uber_received_packet_manager_ &&
+ sent_packet_manager_.use_uber_loss_algorithm() &&
+ GetQuicRestartFlag(quic_enable_accept_random_ipn);
+ if (!enable_multiple_packet_number_spaces) {
+ return;
+ }
+ QUIC_DVLOG(1) << ENDPOINT << "connection " << connection_id()
+ << " supports multiple packet number spaces";
+ framer_.EnableMultiplePacketNumberSpacesSupport();
+ sent_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
+ uber_received_packet_manager_.EnableMultiplePacketNumberSpacesSupport();
+}
+
+bool QuicConnection::SupportsMultiplePacketNumberSpaces() const {
+ return sent_packet_manager_.supports_multiple_packet_number_spaces();
+}
+
void QuicConnection::SetLargestReceivedPacketWithAck(
QuicPacketNumber new_value) {
- largest_seen_packet_with_ack_ = new_value;
+ if (SupportsMultiplePacketNumberSpaces()) {
+ largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
+ last_decrypted_packet_level_)] = new_value;
+ } else {
+ largest_seen_packet_with_ack_ = new_value;
+ }
}
QuicPacketNumber QuicConnection::GetLargestReceivedPacketWithAck() const {
+ if (SupportsMultiplePacketNumberSpaces()) {
+ return largest_seen_packets_with_ack_[QuicUtils::GetPacketNumberSpace(
+ last_decrypted_packet_level_)];
+ }
return largest_seen_packet_with_ack_;
}
QuicPacketNumber QuicConnection::GetLargestSentPacket() const {
+ if (SupportsMultiplePacketNumberSpaces()) {
+ return sent_packet_manager_.GetLargestSentPacket(
+ last_decrypted_packet_level_);
+ }
return sent_packet_manager_.GetLargestSentPacket();
}
QuicPacketNumber QuicConnection::GetLargestAckedPacket() const {
+ if (SupportsMultiplePacketNumberSpaces()) {
+ return sent_packet_manager_.GetLargestAckedPacket(
+ last_decrypted_packet_level_);
+ }
return sent_packet_manager_.GetLargestObserved();
}