Add connection option kRVCM to enable reverse path validation upon new client address on server side. Replace gfe2_reloadable_flag_quic_server_reverse_validate_new_path2 with gfe2_reloadable_flag_quic_server_reverse_validate_new_path3. IETF QUIC server will validate new client address if kRVCM is present AND all path validation flags are true. Protected by FLAGS_quic_reloadable_flag_quic_server_reverse_validate_new_path3. PiperOrigin-RevId: 365133871 Change-Id: I86f40688c2e34995a5738b3f174f5f3014f54337
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h index 99f5372..e08d90b 100644 --- a/quic/core/crypto/crypto_protocol.h +++ b/quic/core/crypto/crypto_protocol.h
@@ -267,6 +267,9 @@ const QuicTag kELDT = TAG('E', 'L', 'D', 'T'); // Enable Loss Detection Tuning +const QuicTag kRVCM = TAG('R', 'V', 'C', 'M'); // Validate the new address + // upon client address change. + // Optional support of truncated Connection IDs. If sent by a peer, the value // is the minimum number of bytes allowed for the connection ID sent to the // peer.
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc index 585aab7..48ed82d 100644 --- a/quic/core/http/end_to_end_test.cc +++ b/quic/core/http/end_to_end_test.cc
@@ -376,6 +376,7 @@ copt.push_back(kILD0); } copt.push_back(kPLE1); + copt.push_back(kRVCM); client_config_.SetConnectionOptionsToSend(copt); // Start the server first, because CreateQuicClient() attempts
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc index 8510737..c53ceea 100644 --- a/quic/core/quic_connection.cc +++ b/quic/core/quic_connection.cc
@@ -371,11 +371,7 @@ GetQuicReloadableFlag(quic_use_encryption_level_context)), path_validator_(alarm_factory_, &arena_, this, random_generator_), alternative_path_(QuicSocketAddress(), QuicSocketAddress()), - most_recent_frame_type_(NUM_FRAME_TYPES), - validate_client_addresses_( - framer_.version().HasIetfQuicFrames() && use_path_validator_ && - count_bytes_on_alternative_path_separately_ && - GetQuicReloadableFlag(quic_server_reverse_validate_new_path2)) { + most_recent_frame_type_(NUM_FRAME_TYPES) { QUIC_BUG_IF(quic_bug_12714_1, !start_peer_migration_earlier_ && send_path_response_); @@ -701,6 +697,13 @@ if (config.HasClientSentConnectionOption(kDFER, perspective_)) { defer_send_in_response_to_packets_ = false; } + if (framer_.version().HasIetfQuicFrames() && use_path_validator_ && + count_bytes_on_alternative_path_separately_ && + GetQuicReloadableFlag(quic_server_reverse_validate_new_path3) && + config.HasClientSentConnectionOption(kRVCM, perspective_)) { + QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 6, 6); + validate_client_addresses_ = true; + } if (config.HasReceivedMaxPacketSize()) { peer_max_packet_size_ = config.ReceivedMaxPacketSize(); MaybeUpdatePacketCreatorMaxPacketLengthAndPadding(); @@ -1674,7 +1677,7 @@ if (!validate_client_addresses_) { return OnPathChallengeFrameInternal(frame); } - QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path2, 1, 5); + QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 1, 6); { // UpdatePacketStateAndReplyPathChallenge() may start reverse path // validation, if so bundle the PATH_CHALLENGE together with the @@ -4968,7 +4971,7 @@ if (!validate_client_addresses_) { return; } - QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path2, 2, 5); + QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 2, 6); if (debug_visitor_ != nullptr) { const QuicTime now = clock_->ApproximateNow(); if (now >= stats_.handshake_completion_time) { @@ -4998,11 +5001,12 @@ << "EffectivePeerMigration started without address change."; return; } - QUIC_DLOG(INFO) << ENDPOINT << "Effective peer's ip:port changed from " - << default_path_.peer_address.ToString() << " to " - << GetEffectivePeerAddressFromCurrentPacket().ToString() - << ", address change type is " << type - << ", migrating connection."; + QUIC_DLOG(INFO) + << ENDPOINT << "Effective peer's ip:port changed from " + << default_path_.peer_address.ToString() << " to " + << GetEffectivePeerAddressFromCurrentPacket().ToString() + << ", address change type is " << type + << ", migrating connection without validating new client address."; highest_packet_sent_before_effective_peer_migration_ = sent_packet_manager_.GetLargestSentPacket(); @@ -5013,7 +5017,7 @@ return; } - QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path2, 3, 5); + QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 3, 6); if (type == NO_CHANGE) { UpdatePeerAddress(last_packet_source_address_); QUIC_BUG(quic_bug_10511_36) @@ -5293,7 +5297,7 @@ alternative_path_ = PathState(last_packet_destination_address_, current_effective_peer_address); } else if (!default_path_.validated) { - QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path2, 4, 5); + QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 4, 6); // Skip reverse path validation because either handshake hasn't // completed or the connection is validating the default path. Using // PATH_CHALLENGE to validate alternative client address before @@ -5307,7 +5311,7 @@ IsHandshakeConfirmed() && !alternative_path_.validated) << "No validated peer address to send after handshake comfirmed."; } else if (!IsReceivedPeerAddressValidated()) { - QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path2, 5, 5); + QUIC_CODE_COUNT_N(quic_server_reverse_validate_new_path3, 5, 6); // Only override alternative path state upon receiving a PATH_CHALLENGE // from an unvalidated peer address, and the connection isn't validating // a recent peer migration.
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h index a6dc7f5..2c70c04 100644 --- a/quic/core/quic_connection.h +++ b/quic/core/quic_connection.h
@@ -2157,7 +2157,7 @@ GetQuicReloadableFlag(quic_count_bytes_on_alternative_path_seperately); // If true, upon seeing a new client address, validate the client address. - const bool validate_client_addresses_; + bool validate_client_addresses_ = false; bool support_multiple_connection_ids_ = false; };
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc index 6b34ece..efeb53b 100644 --- a/quic/core/quic_connection_test.cc +++ b/quic/core/quic_connection_test.cc
@@ -1322,6 +1322,13 @@ void set_perspective(Perspective perspective) { connection_.set_perspective(perspective); if (perspective == Perspective::IS_SERVER) { + QuicConfig config; + QuicTagVector connection_options; + connection_options.push_back(kRVCM); + config.SetInitialReceivedConnectionOptions(connection_options); + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + connection_.SetFromConfig(config); + connection_.set_can_truncate_connection_ids(true); QuicConnectionPeer::SetNegotiatedVersion(&connection_); connection_.OnSuccessfulVersionNegotiation();
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h index 1ba0aa9..44e3e56 100644 --- a/quic/core/quic_flags_list.h +++ b/quic/core/quic_flags_list.h
@@ -56,7 +56,7 @@ QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_path_response2, true) QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_timestamps, false) QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_send_tls_crypto_error_code, true) -QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_server_reverse_validate_new_path2, false) +QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_server_reverse_validate_new_path3, false) QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_single_ack_in_packet2, false) QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_start_peer_migration_earlier, true) QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_stateless_reset_faster_random, true)