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