Flush frames in QUIC packet creator when destination connection ID length changes. And do not flush if ID changes but ID length is unchanged.
Protected by FLAGS_quic_reloadable_flag_quic_connection_migration_use_new_cid_v2.
PiperOrigin-RevId: 373812559
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index f0795cd..027f587 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -722,7 +722,7 @@
use_connection_id_on_default_path_ &&
group_path_response_and_challenge_sending_closer_ &&
GetQuicReloadableFlag(quic_drop_unsent_path_response) &&
- GetQuicReloadableFlag(quic_connection_migration_use_new_cid);
+ GetQuicReloadableFlag(quic_connection_migration_use_new_cid_v2);
if (config.HasReceivedMaxPacketSize()) {
peer_max_packet_size_ = config.ReceivedMaxPacketSize();
MaybeUpdatePacketCreatorMaxPacketLengthAndPadding();
@@ -2017,7 +2017,7 @@
}
void QuicConnection::OnClientConnectionIdAvailable() {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid, 3, 5);
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 3, 5);
QUICHE_DCHECK(perspective_ == Perspective::IS_SERVER);
if (!peer_issued_cid_manager_->HasUnusedConnectionId()) {
return;
@@ -6732,18 +6732,12 @@
QUICHE_DCHECK(perspective_ == Perspective::IS_CLIENT);
if (IsAlternativePath(self_address, peer_address)) {
// Client migration is after path validation.
- if (peer_issued_cid_manager_ != nullptr) {
- QUICHE_DCHECK(!default_path_.server_connection_id.IsEmpty());
- packet_creator_.FlushCurrentPacket();
- }
default_path_.client_connection_id = alternative_path_.client_connection_id;
default_path_.server_connection_id = alternative_path_.server_connection_id;
default_path_.stateless_reset_token =
alternative_path_.stateless_reset_token;
default_path_.stateless_reset_token_received =
alternative_path_.stateless_reset_token_received;
- packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
- packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
return true;
}
// Client migration is without path validation.
@@ -6771,13 +6765,11 @@
default_path_.stateless_reset_token =
connection_id_data->stateless_reset_token;
}
- packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
- packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
return true;
}
void QuicConnection::RetirePeerIssuedConnectionIdsNoLongerOnPath() {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid, 4, 5);
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 4, 5);
if (!connection_migration_use_new_cid_ ||
peer_issued_cid_manager_ == nullptr) {
return;
@@ -6800,10 +6792,18 @@
if (!connected_) {
return false;
}
+ QUICHE_DCHECK(!version().UsesHttp3() || IsHandshakeConfirmed());
- if (connection_migration_use_new_cid_ &&
- !UpdateConnectionIdsOnClientMigration(self_address, peer_address)) {
- return false;
+ if (connection_migration_use_new_cid_) {
+ if (!UpdateConnectionIdsOnClientMigration(self_address, peer_address)) {
+ return false;
+ }
+ if (packet_creator_.GetServerConnectionId().length() !=
+ default_path_.server_connection_id.length()) {
+ packet_creator_.FlushCurrentPacket();
+ }
+ packet_creator_.SetClientConnectionId(default_path_.client_connection_id);
+ packet_creator_.SetServerConnectionId(default_path_.server_connection_id);
}
const auto self_address_change_type = QuicUtils::DetermineAddressChangeType(
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 33ab3b3..bf61b34 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -13575,6 +13575,9 @@
}
TEST_P(QuicConnectionTest, MigratePath) {
+ EXPECT_CALL(visitor_, GetHandshakeState())
+ .Times(testing::AtMost(1))
+ .WillOnce(Return(HANDSHAKE_CONFIRMED));
EXPECT_CALL(visitor_, OnPathDegrading());
connection_.OnPathDegradingDetected();
const QuicSocketAddress kNewSelfAddress(QuicIpAddress::Any4(), 12345);
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index d17c8bd..810cb88 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -1015,7 +1015,7 @@
<< server_connection_id << " new_connection_id: " << new_connection_id;
return;
}
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid, 5, 5);
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 5, 5);
auto insertion_result = reference_counted_session_map_.insert(
std::make_pair(new_connection_id, it->second));
QUICHE_DCHECK(insertion_result.second);
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 1ccad10..899c868 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -114,7 +114,7 @@
// If true, use WriteOrBufferDataAtLevel to send crypto data. Existing WriteOrBufferData is used to send application data.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_write_or_buffer_data_at_level, false)
// If true, use new connection ID in connection migration.
-QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_connection_migration_use_new_cid, false)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_connection_migration_use_new_cid_v2, false)
// If true, use the connection ID and stateless reset token on default PathState.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_use_connection_id_on_default_path_v2, false)
// If true, uses conservative cwnd gain and pacing gain when cwnd gets bootstrapped.
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index 6674ef4..cbca89d 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -2124,10 +2124,12 @@
"initialized.";
creator_->SetDefaultPeerAddress(address);
if (update_connection_id_) {
- // Flush current packet if connection ID changes.
+ // Flush current packet if connection ID length changes.
if (address == old_peer_address_ &&
- ((client_connection_id != old_client_connection_id_) ||
- (server_connection_id != old_server_connection_id_))) {
+ ((client_connection_id.length() !=
+ old_client_connection_id_.length()) ||
+ (server_connection_id.length() !=
+ old_server_connection_id_.length()))) {
creator_->FlushCurrentPacket();
}
creator_->SetClientConnectionId(client_connection_id);
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 1d4f697..9d4a5d1 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -2092,14 +2092,14 @@
}
void QuicSession::SendNewConnectionId(const QuicNewConnectionIdFrame& frame) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid, 1, 5);
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 1, 5);
control_frame_manager_.WriteOrBufferNewConnectionId(
frame.connection_id, frame.sequence_number, frame.retire_prior_to,
frame.stateless_reset_token);
}
void QuicSession::SendRetireConnectionId(uint64_t sequence_number) {
- QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid, 2, 5);
+ QUIC_RELOADABLE_FLAG_COUNT_N(quic_connection_migration_use_new_cid_v2, 2, 5);
control_frame_manager_.WriteOrBufferRetireConnectionId(sequence_number);
}