Always send the HTTP/3 setting indicating support for RFC 9297 (HTTP Datagrams) Support for HTTP Datagrams was initially disabled by default because it was an evolving specification. Now that RFC 9297 has been published, we can simplify our codebase by default-enabling them. This matches what we did for the QUIC DATAGRAM transport parameter after RFC 9221 was published. For use cases that need HTTP Datagram support (such as WebTransport), this change is a no-op because they were already overriding this configuration. For other use cases, the only behavior change is that we now send the setting. We will still silently ignore datagrams when received, as we did before. This CL also minorly refactors a test to make it easier to debug. Protected by FLAGS_quic_reloadable_flag_quic_enable_h3_datagrams. PiperOrigin-RevId: 569300393
diff --git a/quiche/quic/core/http/quic_send_control_stream_test.cc b/quiche/quic/core/http/quic_send_control_stream_test.cc index bf4746e..9698a37 100644 --- a/quiche/quic/core/http/quic_send_control_stream_test.cc +++ b/quiche/quic/core/http/quic_send_control_stream_test.cc
@@ -131,25 +131,25 @@ "01" // 1 byte frame length "61"); // payload "a" if (perspective() == Perspective::IS_CLIENT && - QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) == - HttpDatagramSupport::kDraft04) { + QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) != + HttpDatagramSupport::kNone) { expected_write_data = absl::HexStringToBytes( - "00" // stream type: control stream - "04" // frame type: SETTINGS frame - "0b" // frame length - "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY - "40ff" // 255 - "06" // SETTINGS_MAX_HEADER_LIST_SIZE - "4400" // 1024 - "07" // SETTINGS_QPACK_BLOCKED_STREAMS - "10" // 16 - "4040" // 0x40 as the reserved settings id - "14" // 20 - "800ffd277" // SETTINGS_H3_DATAGRAM_DRAFT04 - "01" // 1 - "4040" // 0x40 as the reserved frame type - "01" // 1 byte frame length - "61"); // payload "a" + "00" // stream type: control stream + "04" // frame type: SETTINGS frame + "0d" // frame length + "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY + "40ff" // 255 + "06" // SETTINGS_MAX_HEADER_LIST_SIZE + "4400" // 1024 + "07" // SETTINGS_QPACK_BLOCKED_STREAMS + "10" // 16 + "33" // SETTINGS_H3_DATAGRAM + "01" // 1 + "4040" // 0x40 as the reserved settings id + "14" // 20 + "4040" // 0x40 as the reserved frame type + "01" // 1 byte frame length + "61"); // payload "a" } if (perspective() == Perspective::IS_SERVER && QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) == @@ -176,28 +176,29 @@ QuicSpdySessionPeer::LocalHttpDatagramSupport(&session_) != HttpDatagramSupport::kNone) { expected_write_data = absl::HexStringToBytes( - "00" // stream type: control stream - "04" // frame type: SETTINGS frame - "0e" // frame length - "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY - "40ff" // 255 - "06" // SETTINGS_MAX_HEADER_LIST_SIZE - "4400" // 1024 - "07" // SETTINGS_QPACK_BLOCKED_STREAMS - "10" // 16 - "08" // SETTINGS_ENABLE_CONNECT_PROTOCOL - "01" // 1 - "4040" // 0x40 as the reserved settings id - "14" // 20 - "800ffd277" // SETTINGS_H3_DATAGRAM_DRAFT04 - "01" // 1 - "4040" // 0x40 as the reserved frame type - "01" // 1 byte frame length - "61"); // payload "a" + "00" // stream type: control stream + "04" // frame type: SETTINGS frame + "0f" // frame length + "01" // SETTINGS_QPACK_MAX_TABLE_CAPACITY + "40ff" // 255 + "06" // SETTINGS_MAX_HEADER_LIST_SIZE + "4400" // 1024 + "07" // SETTINGS_QPACK_BLOCKED_STREAMS + "10" // 16 + "08" // SETTINGS_ENABLE_CONNECT_PROTOCOL + "01" // 1 + "33" // SETTINGS_H3_DATAGRAM + "01" // 1 + "4040" // 0x40 as the reserved settings id + "14" // 20 + "4040" // 0x40 as the reserved frame type + "01" // 1 byte frame length + "61"); // payload "a" } - auto buffer = std::make_unique<char[]>(expected_write_data.size()); - QuicDataWriter writer(expected_write_data.size(), buffer.get()); + char buffer[1000] = {}; + QuicDataWriter writer(sizeof(buffer), buffer); + ASSERT_GE(sizeof(buffer), expected_write_data.size()); // A lambda to save and consume stream data when QuicSession::WritevData() is // called. @@ -211,13 +212,8 @@ /* fin_consumed = */ false); }; - EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 1, _, _, _, _)) - .WillOnce(Invoke(save_write_data)); - EXPECT_CALL(session_, WritevData(send_control_stream_->id(), - expected_write_data.size() - 5, _, _, _, _)) - .WillOnce(Invoke(save_write_data)); - EXPECT_CALL(session_, WritevData(send_control_stream_->id(), 4, _, _, _, _)) - .WillOnce(Invoke(save_write_data)); + EXPECT_CALL(session_, WritevData(send_control_stream_->id(), _, _, _, _, _)) + .WillRepeatedly(Invoke(save_write_data)); send_control_stream_->MaybeSendSettingsFrame(); quiche::test::CompareCharArraysWithHexError(
diff --git a/quiche/quic/core/http/quic_spdy_session.cc b/quiche/quic/core/http/quic_spdy_session.cc index 0e92248..3d7c8dd 100644 --- a/quiche/quic/core/http/quic_spdy_session.cc +++ b/quiche/quic/core/http/quic_spdy_session.cc
@@ -471,7 +471,9 @@ destruction_indicator_(123456789), allow_extended_connect_(perspective() == Perspective::IS_SERVER && VersionUsesHttp3(transport_version())), - force_buffer_requests_until_settings_(false) { + force_buffer_requests_until_settings_(false), + quic_enable_h3_datagrams_flag_( + GetQuicReloadableFlag(quic_enable_h3_datagrams)) { h2_deframer_.set_visitor(spdy_framer_visitor_.get()); h2_deframer_.set_debug_visitor(spdy_framer_visitor_.get()); spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get()); @@ -533,6 +535,7 @@ settings_.values[SETTINGS_H3_DATAGRAM_DRAFT04] = 1; break; case HttpDatagramSupport::kRfc: + QUIC_RELOADABLE_FLAG_COUNT(quic_enable_h3_datagrams); settings_.values[SETTINGS_H3_DATAGRAM] = 1; break; case HttpDatagramSupport::kRfcAndDraft04: @@ -1941,6 +1944,9 @@ } HttpDatagramSupport QuicSpdySession::LocalHttpDatagramSupport() { + if (quic_enable_h3_datagrams_flag_) { + return HttpDatagramSupport::kRfc; + } return HttpDatagramSupport::kNone; }
diff --git a/quiche/quic/core/http/quic_spdy_session.h b/quiche/quic/core/http/quic_spdy_session.h index 9863e46..07b9644 100644 --- a/quiche/quic/core/http/quic_spdy_session.h +++ b/quiche/quic/core/http/quic_spdy_session.h
@@ -716,6 +716,9 @@ // Allows forcing ShouldBufferRequestsUntilSettings() to true via // a connection option. bool force_buffer_requests_until_settings_; + + // Latched value of quic_enable_h3_datagrams reloadable flag. + bool quic_enable_h3_datagrams_flag_; }; } // namespace quic
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h index 87b37ef..5f3b46b 100644 --- a/quiche/quic/core/quic_flags_list.h +++ b/quiche/quic/core/quic_flags_list.h
@@ -101,6 +101,8 @@ QUIC_FLAG(quic_reloadable_flag_quic_bbr2_simplify_inflight_hi, true) // When true, the BBR4 copt sets the extra_acked window to 20 RTTs and BBR5 sets it to 40 RTTs. QUIC_FLAG(quic_reloadable_flag_quic_bbr2_extra_acked_window, true) +// When true, we will send HTTP/3 setting 0x33 to indicate that we support RFC 9297. +QUIC_FLAG(quic_reloadable_flag_quic_enable_h3_datagrams, false) #endif