Move HTTP/3 Datagram Flow ID Allocation Service to QuicSpdySession This CL is part of a chain of refactors of the CONNECT-UDP code aimed at allowing code reuse between MASQUE and WebTransport. The modified code is not used in production. PiperOrigin-RevId: 359618731 Change-Id: Ia97597e31a28ff602ee3910fb9b5667b9ac82924
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc index 91530d3..346add8 100644 --- a/quic/core/http/quic_spdy_session.cc +++ b/quic/core/http/quic_spdy_session.cc
@@ -509,7 +509,10 @@ GetQuicFlag(FLAGS_quic_enable_http3_server_push)), http3_max_push_id_sent_(false), goaway_with_max_stream_id_( - GetQuicReloadableFlag(quic_goaway_with_max_stream_id)) { + GetQuicReloadableFlag(quic_goaway_with_max_stream_id)), + next_available_datagram_flow_id_(perspective() == Perspective::IS_SERVER + ? kFirstDatagramFlowIdServer + : kFirstDatagramFlowIdClient) { if (goaway_with_max_stream_id_) { QUIC_RELOADABLE_FLAG_COUNT_N(quic_goaway_with_max_stream_id, 1, 2); } @@ -1703,6 +1706,12 @@ } } +QuicDatagramFlowId QuicSpdySession::GetNextDatagramFlowId() { + QuicDatagramFlowId result = next_available_datagram_flow_id_; + next_available_datagram_flow_id_ += kDatagramFlowIdIncrement; + return result; +} + #undef ENDPOINT // undef for jumbo builds } // namespace quic
diff --git a/quic/core/http/quic_spdy_session.h b/quic/core/http/quic_spdy_session.h index 3c3d558..ad5fa02 100644 --- a/quic/core/http/quic_spdy_session.h +++ b/quic/core/http/quic_spdy_session.h
@@ -417,6 +417,9 @@ // extension. virtual void OnAcceptChFrameReceivedViaAlps(const AcceptChFrame& /*frame*/); + // Generates a new HTTP/3 datagram flow ID. + QuicDatagramFlowId GetNextDatagramFlowId(); + protected: // Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to @@ -622,6 +625,10 @@ // Latched value of reloadable flag quic_goaway_with_max_stream_id. const bool goaway_with_max_stream_id_; + + // Value of the smallest unused HTTP/3 datagram flow ID that this endpoint's + // datagram flow ID allocation service will use next. + QuicDatagramFlowId next_available_datagram_flow_id_; }; } // namespace quic
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc index c2ab731..d173917 100644 --- a/quic/core/http/quic_spdy_session_test.cc +++ b/quic/core/http/quic_spdy_session_test.cc
@@ -442,6 +442,8 @@ closed_streams_.insert(id); } + ParsedQuicVersion version() const { return connection_->version(); } + QuicTransportVersion transport_version() const { return connection_->transport_version(); } @@ -3375,6 +3377,26 @@ EXPECT_EQ("incomplete HTTP/3 frame", error.value()); } +TEST_P(QuicSpdySessionTestClient, GetNextDatagramFlowId) { + if (!version().UsesHttp3()) { + return; + } + EXPECT_EQ(session_.GetNextDatagramFlowId(), 0u); + EXPECT_EQ(session_.GetNextDatagramFlowId(), 2u); + EXPECT_EQ(session_.GetNextDatagramFlowId(), 4u); + EXPECT_EQ(session_.GetNextDatagramFlowId(), 6u); +} + +TEST_P(QuicSpdySessionTestServer, GetNextDatagramFlowId) { + if (!version().UsesHttp3()) { + return; + } + EXPECT_EQ(session_.GetNextDatagramFlowId(), 1u); + EXPECT_EQ(session_.GetNextDatagramFlowId(), 3u); + EXPECT_EQ(session_.GetNextDatagramFlowId(), 5u); + EXPECT_EQ(session_.GetNextDatagramFlowId(), 7u); +} + } // namespace } // namespace test } // namespace quic
diff --git a/quic/core/quic_constants.h b/quic/core/quic_constants.h index 2de827f..fcfec62 100644 --- a/quic/core/quic_constants.h +++ b/quic/core/quic_constants.h
@@ -291,6 +291,13 @@ QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd; QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd0; +// HTTP/3 Datagrams. +enum : QuicDatagramFlowId { + kFirstDatagramFlowIdClient = 0, + kFirstDatagramFlowIdServer = 1, + kDatagramFlowIdIncrement = 2, +}; + } // namespace quic #endif // QUICHE_QUIC_CORE_QUIC_CONSTANTS_H_
diff --git a/quic/masque/masque_client_session.cc b/quic/masque/masque_client_session.cc index 5663c4a..6c7859e 100644 --- a/quic/masque/masque_client_session.cc +++ b/quic/masque/masque_client_session.cc
@@ -114,7 +114,7 @@ return nullptr; } - QuicDatagramFlowId flow_id = compression_engine_.GetNextFlowId(); + QuicDatagramFlowId flow_id = GetNextDatagramFlowId(); // Send the request. spdy::Http2HeaderBlock headers;
diff --git a/quic/masque/masque_compression_engine.cc b/quic/masque/masque_compression_engine.cc index af6758a..2867b3d 100644 --- a/quic/masque/masque_compression_engine.cc +++ b/quic/masque/masque_compression_engine.cc
@@ -30,14 +30,9 @@ } // namespace -MasqueCompressionEngine::MasqueCompressionEngine(QuicSession* masque_session) - : masque_session_(masque_session) { - if (masque_session_->perspective() == Perspective::IS_SERVER) { - next_flow_id_ = 1; - } else { - next_flow_id_ = 2; - } -} +MasqueCompressionEngine::MasqueCompressionEngine( + QuicSpdySession* masque_session) + : masque_session_(masque_session) {} QuicDatagramFlowId MasqueCompressionEngine::FindOrCreateCompressionContext( QuicConnectionId client_connection_id, @@ -79,7 +74,11 @@ } // Create new compression context. - flow_id = GetNextFlowId(); + flow_id = masque_session_->GetNextDatagramFlowId(); + if (flow_id == kFlowId0) { + // Do not use value zero which is reserved in this mode. + flow_id = masque_session_->GetNextDatagramFlowId(); + } QUIC_DVLOG(1) << "Compression assigning new flow_id " << flow_id << " to " << server_address << " client " << client_connection_id << " server " << server_connection_id; @@ -520,12 +519,6 @@ return true; } -QuicDatagramFlowId MasqueCompressionEngine::GetNextFlowId() { - const QuicDatagramFlowId next_flow_id = next_flow_id_; - next_flow_id_ += 2; - return next_flow_id; -} - void MasqueCompressionEngine::UnregisterClientConnectionId( QuicConnectionId client_connection_id) { std::vector<QuicDatagramFlowId> flow_ids_to_remove;
diff --git a/quic/masque/masque_compression_engine.h b/quic/masque/masque_compression_engine.h index 16b4549..9bea618 100644 --- a/quic/masque/masque_compression_engine.h +++ b/quic/masque/masque_compression_engine.h
@@ -7,8 +7,8 @@ #include "absl/container/flat_hash_map.h" #include "absl/strings/string_view.h" +#include "quic/core/http/quic_spdy_session.h" #include "quic/core/quic_connection_id.h" -#include "quic/core/quic_session.h" #include "quic/core/quic_types.h" #include "quic/platform/api/quic_containers.h" #include "quic/platform/api/quic_export.h" @@ -35,7 +35,7 @@ public: // Caller must ensure that |masque_session| has a lifetime longer than the // newly constructed MasqueCompressionEngine. - explicit MasqueCompressionEngine(QuicSession* masque_session); + explicit MasqueCompressionEngine(QuicSpdySession* masque_session); // Disallow copy and assign. MasqueCompressionEngine(const MasqueCompressionEngine&) = delete; @@ -70,9 +70,6 @@ // compression table. void UnregisterClientConnectionId(QuicConnectionId client_connection_id); - // Generates a new datagram flow ID. - QuicDatagramFlowId GetNextFlowId(); - private: struct QUIC_NO_EXPORT MasqueCompressionContext { QuicConnectionId client_connection_id; @@ -117,9 +114,8 @@ std::vector<char>* packet, bool* version_present); - QuicSession* masque_session_; // Unowned. + QuicSpdySession* masque_session_; // Unowned. absl::flat_hash_map<QuicDatagramFlowId, MasqueCompressionContext> contexts_; - QuicDatagramFlowId next_flow_id_; }; } // namespace quic