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