Do not SendInResponseToPacket or return true in CanWrite when connection ID is required but missing in the packet creator. Protected by FLAGS_quic_reloadable_flag_quic_do_not_write_when_no_client_cid_available. PiperOrigin-RevId: 533120959
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc index b68aad0..adb6e87 100644 --- a/quiche/quic/core/quic_connection.cc +++ b/quiche/quic/core/quic_connection.cc
@@ -47,6 +47,7 @@ #include "quiche/quic/platform/api/quic_logging.h" #include "quiche/quic/platform/api/quic_socket_address.h" #include "quiche/common/platform/api/quiche_flag_utils.h" +#include "quiche/common/platform/api/quiche_testvalue.h" #include "quiche/common/quiche_text_utils.h" namespace quic { @@ -2455,6 +2456,16 @@ return; } + if (GetQuicReloadableFlag(quic_do_not_write_when_no_client_cid_available)) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_do_not_write_when_no_client_cid_available, + 1, 3); + if (IsMissingDestinationConnectionID()) { + QUICHE_RELOADABLE_FLAG_COUNT_N( + quic_do_not_write_when_no_client_cid_available, 2, 3); + return; + } + } + // If the writer is blocked, don't attempt to send packets now or in the send // alarm. When the writer unblocks, OnCanWrite() will be called for this // connection to send. @@ -3186,14 +3197,18 @@ } } +bool QuicConnection::IsMissingDestinationConnectionID() const { + return peer_issued_cid_manager_ != nullptr && + packet_creator_.GetDestinationConnectionId().IsEmpty(); +} + bool QuicConnection::ShouldGeneratePacket( HasRetransmittableData retransmittable, IsHandshake handshake) { QUICHE_DCHECK(handshake != IS_HANDSHAKE || QuicVersionUsesCryptoFrames(transport_version())) << ENDPOINT << "Handshake in STREAM frames should not check ShouldGeneratePacket"; - if (peer_issued_cid_manager_ != nullptr && - packet_creator_.GetDestinationConnectionId().IsEmpty()) { + if (IsMissingDestinationConnectionID()) { QUICHE_DCHECK(version().HasIetfQuicFrames()); QUIC_CODE_COUNT(quic_generate_packet_blocked_by_no_connection_id); QUIC_BUG_IF(quic_bug_90265_1, perspective_ == Perspective::IS_CLIENT); @@ -3256,6 +3271,14 @@ return false; } + if (GetQuicReloadableFlag(quic_do_not_write_when_no_client_cid_available)) { + if (IsMissingDestinationConnectionID()) { + QUIC_RELOADABLE_FLAG_COUNT_N( + quic_do_not_write_when_no_client_cid_available, 3, 3); + return false; + } + } + if (version().CanSendCoalescedPackets() && framer_.HasEncrypterOfEncryptionLevel(ENCRYPTION_INITIAL) && framer_.is_processing_packet()) { @@ -6282,9 +6305,15 @@ kMinNumOfActiveConnectionIds, client_connection_id, clock_, alarm_factory_, this, context()); } else { + bool create_client_self_issued_cid_manager = true; + quiche::AdjustTestValue( + "quic::QuicConnection::create_cid_manager_when_set_client_cid", + &create_client_self_issued_cid_manager); // Note in Chromium client, set_client_connection_id is not called and // thus self_issued_cid_manager_ should be null. - self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager(); + if (create_client_self_issued_cid_manager) { + self_issued_cid_manager_ = MakeSelfIssuedConnectionIdManager(); + } } } QUIC_DLOG(INFO) << ENDPOINT << "setting client connection ID to "
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h index fbfd952..f739644 100644 --- a/quiche/quic/core/quic_connection.h +++ b/quiche/quic/core/quic_connection.h
@@ -725,6 +725,9 @@ override; std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override; + // Whether destination connection ID is required but missing in the packet + // creator. + bool IsMissingDestinationConnectionID() const; // QuicPacketCreator::DelegateInterface bool ShouldGeneratePacket(HasRetransmittableData retransmittable, IsHandshake handshake) override;
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h index 5023083..7f6ba62 100644 --- a/quiche/quic/core/quic_flags_list.h +++ b/quiche/quic/core/quic_flags_list.h
@@ -47,6 +47,8 @@ QUIC_FLAG(quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true) // If true, do not issue a new connection ID that has been claimed by another connection. QUIC_FLAG(quic_reloadable_flag_quic_check_cid_collision_when_issue_new_cid, true) +// If true, do not write when client CID is requried but missing in the packet creator. +QUIC_FLAG(quic_reloadable_flag_quic_do_not_write_when_no_client_cid_available, true) // If true, enable server retransmittable on wire PING. QUIC_FLAG(quic_reloadable_flag_quic_enable_server_on_wire_ping, true) // If true, flush pending frames as well as pending padding bytes on connection migration.