Abstract away the interface of QuicTransport into WebTransportStream and WebTransportSession.
PiperOrigin-RevId: 361909959
Change-Id: I2b3307e6662c4b048224b09a9cb0ec6de1fb039b
diff --git a/quic/core/web_transport_interface.h b/quic/core/web_transport_interface.h
new file mode 100644
index 0000000..a458e65
--- /dev/null
+++ b/quic/core/web_transport_interface.h
@@ -0,0 +1,107 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This header contains interfaces that abstract away different backing
+// protocols for WebTransport.
+
+#ifndef QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
+#define QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
+
+#include <cstddef>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quic/core/quic_datagram_queue.h"
+#include "quic/core/quic_types.h"
+#include "quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Visitor that gets notified about events related to a WebTransport stream.
+class QUIC_EXPORT_PRIVATE WebTransportStreamVisitor {
+ public:
+ virtual ~WebTransportStreamVisitor() {}
+
+ // Called whenever the stream has readable data available.
+ virtual void OnCanRead() = 0;
+ // Called when all the data on the stream has been consumed and a FIN has been
+ // received.
+ virtual void OnFinRead() = 0;
+ // Called whenever the stream is not write-blocked and can accept new data.
+ virtual void OnCanWrite() = 0;
+};
+
+// A stream (either bidirectional or unidirectional) that is contained within a
+// WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportStream {
+ public:
+ virtual ~WebTransportStream() {}
+
+ // Reads at most |buffer_size| bytes into |buffer| and returns the number of
+ // bytes actually read.
+ virtual size_t Read(char* buffer, size_t buffer_size) = 0;
+ // Reads all available data and appends it to the end of |output|.
+ virtual size_t Read(std::string* output) = 0;
+ // Writes |data| into the stream. Returns true on success.
+ virtual ABSL_MUST_USE_RESULT bool Write(absl::string_view data) = 0;
+ // Sends the FIN on the stream. Returns true on success.
+ virtual ABSL_MUST_USE_RESULT bool SendFin() = 0;
+
+ // Indicates whether it is possible to write into stream right now.
+ virtual bool CanWrite() const = 0;
+ // Indicates the number of bytes that can be read from the stream.
+ virtual size_t ReadableBytes() const = 0;
+};
+
+// Visitor that gets notified about events related to a WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportVisitor {
+ public:
+ virtual ~WebTransportVisitor() {}
+
+ // Notifies the visitor when the session is ready to exchange application
+ // data.
+ virtual void OnSessionReady() = 0;
+
+ // Notifies the visitor when a new stream has been received. The stream in
+ // question can be retrieved using AcceptIncomingBidirectionalStream() or
+ // AcceptIncomingUnidirectionalStream().
+ virtual void OnIncomingBidirectionalStreamAvailable() = 0;
+ virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
+
+ // Notifies the visitor when a new datagram has been received.
+ virtual void OnDatagramReceived(absl::string_view datagram) = 0;
+
+ // Notifies the visitor that a new outgoing stream can now be created.
+ virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
+ virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
+};
+
+// An abstract interface for a WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportSession {
+ public:
+ virtual ~WebTransportSession() {}
+
+ // Return the earliest incoming stream that has been received by the session
+ // but has not been accepted. Returns nullptr if there are no incoming
+ // streams.
+ virtual WebTransportStream* AcceptIncomingBidirectionalStream() = 0;
+ virtual WebTransportStream* AcceptIncomingUnidirectionalStream() = 0;
+
+ // Returns true if flow control allows opening a new stream.
+ virtual bool CanOpenNextOutgoingBidirectionalStream() = 0;
+ virtual bool CanOpenNextOutgoingUnidirectionalStream() = 0;
+ // Opens a new WebTransport stream, or returns nullptr if that is not possible
+ // due to flow control.
+ virtual WebTransportStream* OpenOutgoingBidirectionalStream() = 0;
+ virtual WebTransportStream* OpenOutgoingUnidirectionalStream() = 0;
+
+ virtual MessageStatus SendOrQueueDatagram(QuicMemSlice datagram) = 0;
+ // Sets the largest duration that a datagram can spend in the queue before
+ // being silently dropped.
+ virtual void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) = 0;
+};
+
+} // namespace quic
+
+#endif // QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
diff --git a/quic/quic_transport/quic_transport_client_session.cc b/quic/quic_transport/quic_transport_client_session.cc
index 7b81f51..6838c4c 100644
--- a/quic/quic_transport/quic_transport_client_session.cc
+++ b/quic/quic_transport/quic_transport_client_session.cc
@@ -34,7 +34,7 @@
const GURL& url,
QuicCryptoClientConfig* crypto_config,
url::Origin origin,
- ClientVisitor* visitor,
+ WebTransportVisitor* visitor,
std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
: QuicSession(connection,
owner,
diff --git a/quic/quic_transport/quic_transport_client_session.h b/quic/quic_transport/quic_transport_client_session.h
index 686e5b3..6406bd5 100644
--- a/quic/quic_transport/quic_transport_client_session.h
+++ b/quic/quic_transport/quic_transport_client_session.h
@@ -21,6 +21,7 @@
#include "quic/core/quic_session.h"
#include "quic/core/quic_stream.h"
#include "quic/core/quic_versions.h"
+#include "quic/core/web_transport_interface.h"
#include "quic/platform/api/quic_bug_tracker.h"
#include "quic/platform/api/quic_containers.h"
#include "quic/quic_transport/quic_transport_protocol.h"
@@ -32,31 +33,10 @@
// A client session for the QuicTransport protocol.
class QUIC_EXPORT_PRIVATE QuicTransportClientSession
: public QuicSession,
+ public WebTransportSession,
public QuicTransportSessionInterface,
public QuicCryptoClientStream::ProofHandler {
public:
- class QUIC_EXPORT_PRIVATE ClientVisitor {
- public:
- virtual ~ClientVisitor() {}
-
- // Notifies the visitor when the client indication has been sent and the
- // connection is ready to exchange application data.
- virtual void OnSessionReady() = 0;
-
- // Notifies the visitor when a new stream has been received. The stream in
- // question can be retrieved using AcceptIncomingBidirectionalStream() or
- // AcceptIncomingUnidirectionalStream().
- virtual void OnIncomingBidirectionalStreamAvailable() = 0;
- virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
-
- // Notifies the visitor when a new datagram has been received.
- virtual void OnDatagramReceived(absl::string_view datagram) = 0;
-
- // Notifies the visitor that a new outgoing stream can now be created.
- virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
- virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
- };
-
QuicTransportClientSession(
QuicConnection* connection,
Visitor* owner,
@@ -65,7 +45,7 @@
const GURL& url,
QuicCryptoClientConfig* crypto_config,
url::Origin origin,
- ClientVisitor* visitor,
+ WebTransportVisitor* visitor,
std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
std::vector<std::string> GetAlpnsToOffer() const override {
@@ -106,14 +86,26 @@
// Return the earliest incoming stream that has been received by the session
// but has not been accepted. Returns nullptr if there are no incoming
// streams.
- QuicTransportStream* AcceptIncomingBidirectionalStream();
- QuicTransportStream* AcceptIncomingUnidirectionalStream();
+ QuicTransportStream* AcceptIncomingBidirectionalStream() override;
+ QuicTransportStream* AcceptIncomingUnidirectionalStream() override;
- using QuicSession::CanOpenNextOutgoingBidirectionalStream;
- using QuicSession::CanOpenNextOutgoingUnidirectionalStream;
- QuicTransportStream* OpenOutgoingBidirectionalStream();
- QuicTransportStream* OpenOutgoingUnidirectionalStream();
+ bool CanOpenNextOutgoingBidirectionalStream() override {
+ return QuicSession::CanOpenNextOutgoingBidirectionalStream();
+ }
+ bool CanOpenNextOutgoingUnidirectionalStream() override {
+ return QuicSession::CanOpenNextOutgoingUnidirectionalStream();
+ }
+ QuicTransportStream* OpenOutgoingBidirectionalStream() override;
+ QuicTransportStream* OpenOutgoingUnidirectionalStream() override;
+ MessageStatus SendOrQueueDatagram(QuicMemSlice datagram) override {
+ return datagram_queue()->SendOrQueueDatagram(std::move(datagram));
+ }
+ void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override {
+ datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
+ }
+
+ // For unit tests.
using QuicSession::datagram_queue;
// QuicCryptoClientStream::ProofHandler implementation.
@@ -147,7 +139,7 @@
std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
GURL url_;
url::Origin origin_;
- ClientVisitor* visitor_; // not owned
+ WebTransportVisitor* visitor_; // not owned
bool client_indication_sent_ = false;
bool alpn_received_ = false;
bool ready_ = false;
diff --git a/quic/quic_transport/quic_transport_integration_test.cc b/quic/quic_transport/quic_transport_integration_test.cc
index 1b42020..4e237c7 100644
--- a/quic/quic_transport/quic_transport_integration_test.cc
+++ b/quic/quic_transport/quic_transport_integration_test.cc
@@ -349,8 +349,7 @@
WireUpEndpoints();
RunHandshake();
- client_->session()->datagram_queue()->SendOrQueueDatagram(
- MemSliceFromString("test"));
+ client_->session()->SendOrQueueDatagram(MemSliceFromString("test"));
bool datagram_received = false;
EXPECT_CALL(*client_->visitor(), OnDatagramReceived(Eq("test")))
@@ -368,11 +367,10 @@
RunHandshake();
// Set the datagrams to effectively never expire.
- client_->session()->datagram_queue()->SetMaxTimeInQueue(10000 * kRtt);
+ client_->session()->SetDatagramMaxTimeInQueue(10000 * kRtt);
for (int i = 0; i < 1000; i++) {
- client_->session()->datagram_queue()->SendOrQueueDatagram(
- MemSliceFromString(std::string(
- client_->session()->GetGuaranteedLargestMessagePayload(), 'a')));
+ client_->session()->SendOrQueueDatagram(MemSliceFromString(std::string(
+ client_->session()->GetGuaranteedLargestMessagePayload(), 'a')));
}
size_t received = 0;
diff --git a/quic/quic_transport/quic_transport_stream.h b/quic/quic_transport/quic_transport_stream.h
index 70f947c..776b07f 100644
--- a/quic/quic_transport/quic_transport_stream.h
+++ b/quic/quic_transport/quic_transport_stream.h
@@ -13,6 +13,7 @@
#include "quic/core/quic_session.h"
#include "quic/core/quic_stream.h"
#include "quic/core/quic_types.h"
+#include "quic/core/web_transport_interface.h"
#include "quic/quic_transport/quic_transport_session_interface.h"
namespace quic {
@@ -20,41 +21,34 @@
// QuicTransportStream is an extension of QuicStream that provides I/O interface
// that is safe to use in the QuicTransport context. The interface ensures no
// application data is processed before the client indication is processed.
-class QUIC_EXPORT_PRIVATE QuicTransportStream : public QuicStream {
+class QUIC_EXPORT_PRIVATE QuicTransportStream : public QuicStream,
+ public WebTransportStream {
public:
- class QUIC_EXPORT_PRIVATE Visitor {
- public:
- virtual ~Visitor() {}
- virtual void OnCanRead() = 0;
- virtual void OnFinRead() = 0;
- virtual void OnCanWrite() = 0;
- };
-
QuicTransportStream(QuicStreamId id,
QuicSession* session,
QuicTransportSessionInterface* session_interface);
// Reads at most |buffer_size| bytes into |buffer| and returns the number of
// bytes actually read.
- size_t Read(char* buffer, size_t buffer_size);
+ size_t Read(char* buffer, size_t buffer_size) override;
// Reads all available data and appends it to the end of |output|.
- size_t Read(std::string* output);
+ size_t Read(std::string* output) override;
// Writes |data| into the stream. Returns true on success.
- ABSL_MUST_USE_RESULT bool Write(absl::string_view data);
+ ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
// Sends the FIN on the stream. Returns true on success.
- ABSL_MUST_USE_RESULT bool SendFin();
+ ABSL_MUST_USE_RESULT bool SendFin() override;
// Indicates whether it is possible to write into stream right now.
- bool CanWrite() const;
+ bool CanWrite() const override;
// Indicates the number of bytes that can be read from the stream.
- size_t ReadableBytes() const;
+ size_t ReadableBytes() const override;
// QuicSession method implementations.
void OnDataAvailable() override;
void OnCanWriteNewData() override;
- Visitor* visitor() { return visitor_.get(); }
- void set_visitor(std::unique_ptr<Visitor> visitor) {
+ WebTransportStreamVisitor* visitor() { return visitor_.get(); }
+ void set_visitor(std::unique_ptr<WebTransportStreamVisitor> visitor) {
visitor_ = std::move(visitor);
}
@@ -66,7 +60,7 @@
void MaybeNotifyFinRead();
QuicTransportSessionInterface* session_interface_;
- std::unique_ptr<Visitor> visitor_ = nullptr;
+ std::unique_ptr<WebTransportStreamVisitor> visitor_ = nullptr;
bool fin_read_notified_ = false;
};
diff --git a/quic/test_tools/quic_transport_test_tools.h b/quic/test_tools/quic_transport_test_tools.h
index e0fcebc..0a3b52d 100644
--- a/quic/test_tools/quic_transport_test_tools.h
+++ b/quic/test_tools/quic_transport_test_tools.h
@@ -5,14 +5,14 @@
#ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
#define QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
+#include "quic/core/web_transport_interface.h"
#include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_client_session.h"
#include "quic/quic_transport/quic_transport_server_session.h"
namespace quic {
namespace test {
-class MockClientVisitor : public QuicTransportClientSession::ClientVisitor {
+class MockClientVisitor : public WebTransportVisitor {
public:
MOCK_METHOD(void, OnSessionReady, (), (override));
MOCK_METHOD(void, OnIncomingBidirectionalStreamAvailable, (), (override));
@@ -28,7 +28,7 @@
MOCK_METHOD(bool, ProcessPath, (const GURL&), (override));
};
-class MockStreamVisitor : public QuicTransportStream::Visitor {
+class MockStreamVisitor : public WebTransportStreamVisitor {
public:
MOCK_METHOD(void, OnCanRead, (), (override));
MOCK_METHOD(void, OnFinRead, (), (override));
diff --git a/quic/tools/quic_transport_simple_server_session.cc b/quic/tools/quic_transport_simple_server_session.cc
index ad93115..9acf502 100644
--- a/quic/tools/quic_transport_simple_server_session.cc
+++ b/quic/tools/quic_transport_simple_server_session.cc
@@ -21,7 +21,7 @@
namespace {
// Discards any incoming data.
-class DiscardVisitor : public QuicTransportStream::Visitor {
+class DiscardVisitor : public WebTransportStreamVisitor {
public:
DiscardVisitor(QuicTransportStream* stream) : stream_(stream) {}
@@ -40,7 +40,7 @@
};
// Echoes any incoming data back on the same stream.
-class BidirectionalEchoVisitor : public QuicTransportStream::Visitor {
+class BidirectionalEchoVisitor : public WebTransportStreamVisitor {
public:
BidirectionalEchoVisitor(QuicTransportStream* stream) : stream_(stream) {}
@@ -71,7 +71,7 @@
};
// Buffers all of the data and calls EchoStreamBack() on the parent session.
-class UnidirectionalEchoReadVisitor : public QuicTransportStream::Visitor {
+class UnidirectionalEchoReadVisitor : public WebTransportStreamVisitor {
public:
UnidirectionalEchoReadVisitor(QuicTransportSimpleServerSession* session,
QuicTransportStream* stream)
@@ -97,7 +97,7 @@
};
// Sends supplied data.
-class UnidirectionalEchoWriteVisitor : public QuicTransportStream::Visitor {
+class UnidirectionalEchoWriteVisitor : public WebTransportStreamVisitor {
public:
UnidirectionalEchoWriteVisitor(QuicTransportStream* stream,
const std::string& data)