Implement HTTP/3 datagrams within WebTransport

The version of HTTP/3 datagrams here uses the "Datagram-Flow-Id = sf-integer" header definition; however, since the HTTP/3 datagram is currently highly in flux, this is very likely to be not a final version of this.

PiperOrigin-RevId: 367157595
Change-Id: I2f0a6c077c5cf91435809969d98b0fd0e418f0ec
diff --git a/quic/core/http/web_transport_http3.cc b/quic/core/http/web_transport_http3.cc
index 3d1812e..2a105c2 100644
--- a/quic/core/http/web_transport_http3.cc
+++ b/quic/core/http/web_transport_http3.cc
@@ -36,14 +36,17 @@
 
 WebTransportHttp3::WebTransportHttp3(QuicSpdySession* session,
                                      QuicSpdyStream* connect_stream,
-                                     WebTransportSessionId id)
+                                     WebTransportSessionId id,
+                                     QuicDatagramFlowId flow_id)
     : session_(session),
       connect_stream_(connect_stream),
       id_(id),
+      flow_id_(flow_id),
       visitor_(std::make_unique<NoopWebTransportVisitor>()) {
   QUICHE_DCHECK(session_->SupportsWebTransport());
   QUICHE_DCHECK(IsValidWebTransportSessionId(id, session_->version()));
   QUICHE_DCHECK_EQ(connect_stream_->id(), id);
+  session_->RegisterHttp3FlowId(flow_id, this);
 }
 
 void WebTransportHttp3::AssociateStream(QuicStreamId stream_id) {
@@ -71,6 +74,7 @@
   for (QuicStreamId id : streams) {
     session_->ResetStream(id, QUIC_STREAM_WEBTRANSPORT_SESSION_GONE);
   }
+  session_->UnregisterHttp3FlowId(flow_id_);
 }
 
 void WebTransportHttp3::HeadersReceived(const spdy::SpdyHeaderBlock& headers) {
@@ -148,14 +152,20 @@
   return stream->interface();
 }
 
-MessageStatus WebTransportHttp3::SendOrQueueDatagram(
-    QuicMemSlice /*datagram*/) {
-  // TODO(vasilvv): implement this.
-  return MessageStatus::MESSAGE_STATUS_UNSUPPORTED;
+MessageStatus WebTransportHttp3::SendOrQueueDatagram(QuicMemSlice datagram) {
+  return session_->SendHttp3Datagram(
+      flow_id_, absl::string_view(datagram.data(), datagram.length()));
 }
+
 void WebTransportHttp3::SetDatagramMaxTimeInQueue(
-    QuicTime::Delta /*max_time_in_queue*/) {
-  // TODO(vasilvv): implement this.
+    QuicTime::Delta max_time_in_queue) {
+  session_->SetMaxTimeInQueueForFlowId(flow_id_, max_time_in_queue);
+}
+
+void WebTransportHttp3::OnHttp3Datagram(QuicDatagramFlowId flow_id,
+                                        absl::string_view payload) {
+  QUICHE_DCHECK_EQ(flow_id, flow_id_);
+  visitor_->OnDatagramReceived(payload);
 }
 
 WebTransportHttp3UnidirectionalStream::WebTransportHttp3UnidirectionalStream(