Remove support for ephemeral streams in QBONE. These have been unused for
months (since switching to message frames).
PiperOrigin-RevId: 330572491
Change-Id: I3023bd0b4311c5bae18684072ec97fc84322b318
diff --git a/quic/qbone/qbone_client.cc b/quic/qbone/qbone_client.cc
index a2ba117..c3d8f73 100644
--- a/quic/qbone/qbone_client.cc
+++ b/quic/qbone/qbone_client.cc
@@ -10,7 +10,6 @@
#include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h"
-#include "net/third_party/quiche/src/quic/qbone/qbone_stream.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
namespace quic {
diff --git a/quic/qbone/qbone_client_test.cc b/quic/qbone/qbone_client_test.cc
index cfe6c46..a9b9994 100644
--- a/quic/qbone/qbone_client_test.cc
+++ b/quic/qbone/qbone_client_test.cc
@@ -7,7 +7,6 @@
#include "net/third_party/quiche/src/quic/qbone/qbone_client.h"
#include "net/third_party/quiche/src/quic/core/quic_alarm_factory.h"
-#include "net/third_party/quiche/src/quic/core/quic_default_packet_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_dispatcher.h"
#include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h"
#include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
@@ -59,7 +58,7 @@
public:
void WritePacketToNetwork(const char* packet, size_t size) override {
QuicWriterMutexLock lock(&mu_);
- data_.push_back(std::string(packet, size));
+ data_.emplace_back(std::string(packet, size));
}
std::vector<std::string> data() {
diff --git a/quic/qbone/qbone_constants.h b/quic/qbone/qbone_constants.h
index eeb6171..9925952 100644
--- a/quic/qbone/qbone_constants.h
+++ b/quic/qbone/qbone_constants.h
@@ -16,7 +16,7 @@
// QBONE's ALPN
static constexpr char kQboneAlpn[] = "qbone";
// The maximum number of bytes allowed in a QBONE packet.
- static const QuicByteCount kMaxQbonePacketBytes = 2000;
+ static const QuicByteCount kMaxQbonePacketBytes = 1280;
// The table id for QBONE's routing table. 'bone' in ascii.
static const uint32_t kQboneRouteTableId = 0x626F6E65;
// The stream ID of the control channel.
diff --git a/quic/qbone/qbone_session_base.cc b/quic/qbone/qbone_session_base.cc
index e534398..1f8a512 100644
--- a/quic/qbone/qbone_session_base.cc
+++ b/quic/qbone/qbone_session_base.cc
@@ -10,7 +10,6 @@
#include <utility>
#include "net/third_party/quiche/src/quic/core/quic_buffer_allocator.h"
-#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_exported_stats.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
@@ -18,17 +17,8 @@
#include "net/third_party/quiche/src/quic/qbone/qbone_constants.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-ABSL_FLAG(
- bool,
- qbone_close_ephemeral_frames,
- true,
- "If true, we'll call CloseStream even when we receive ephemeral frames.");
-
namespace quic {
-#define ENDPOINT \
- (perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
-
QboneSessionBase::QboneSessionBase(
QuicConnection* connection,
Visitor* owner,
@@ -70,34 +60,14 @@
return crypto_stream_.get();
}
-QuicStream* QboneSessionBase::CreateOutgoingStream() {
- return ActivateDataStream(
- CreateDataStream(GetNextOutgoingUnidirectionalStreamId()));
-}
-
-void QboneSessionBase::OnStreamFrame(const QuicStreamFrame& frame) {
- if (frame.offset == 0 && frame.fin && frame.data_length > 0) {
- ++num_ephemeral_packets_;
- ProcessPacketFromPeer(
- quiche::QuicheStringPiece(frame.data_buffer, frame.data_length));
- flow_controller()->AddBytesConsumed(frame.data_length);
- // TODO(b/147817422): Add a counter for how many streams were actually
- // closed here.
- if (GetQuicFlag(FLAGS_qbone_close_ephemeral_frames)) {
- ResetStream(frame.stream_id, QUIC_STREAM_CANCELLED);
- }
- return;
- }
- QuicSession::OnStreamFrame(frame);
-}
-
void QboneSessionBase::OnMessageReceived(quiche::QuicheStringPiece message) {
++num_message_packets_;
ProcessPacketFromPeer(message);
}
QuicStream* QboneSessionBase::CreateIncomingStream(QuicStreamId id) {
- return ActivateDataStream(CreateDataStream(id));
+ QUIC_NOTREACHED();
+ return nullptr;
}
QuicStream* QboneSessionBase::CreateIncomingStream(PendingStream* /*pending*/) {
@@ -110,108 +80,60 @@
return true;
}
-std::unique_ptr<QuicStream> QboneSessionBase::CreateDataStream(
- QuicStreamId id) {
- if (crypto_stream_ == nullptr || !crypto_stream_->encryption_established()) {
- // Encryption not active so no stream created
- return nullptr;
- }
-
- if (IsIncomingStream(id)) {
- ++num_streamed_packets_;
- return std::make_unique<QboneReadOnlyStream>(id, this);
- }
-
- return std::make_unique<QboneWriteOnlyStream>(id, this);
-}
-
-QuicStream* QboneSessionBase::ActivateDataStream(
- std::unique_ptr<QuicStream> stream) {
- // Transfer ownership of the data stream to the session via ActivateStream().
- QuicStream* raw = stream.get();
- if (stream) {
- // Make QuicSession take ownership of the stream.
- ActivateStream(std::move(stream));
- }
- return raw;
-}
-
void QboneSessionBase::SendPacketToPeer(quiche::QuicheStringPiece packet) {
if (crypto_stream_ == nullptr) {
QUIC_BUG << "Attempting to send packet before encryption established";
return;
}
- if (send_packets_as_messages_) {
- QuicUniqueBufferPtr buffer = MakeUniqueBuffer(
- connection()->helper()->GetStreamSendBufferAllocator(), packet.size());
- memcpy(buffer.get(), packet.data(), packet.size());
- QuicMemSlice slice(std::move(buffer), packet.size());
- switch (SendMessage(QuicMemSliceSpan(&slice), /*flush=*/true).status) {
- case MESSAGE_STATUS_SUCCESS:
- break;
- case MESSAGE_STATUS_TOO_LARGE: {
- if (packet.size() < sizeof(ip6_hdr)) {
- QUIC_BUG << "Dropped malformed packet: IPv6 header too short";
- break;
- }
- auto* header = reinterpret_cast<const ip6_hdr*>(packet.begin());
- icmp6_hdr icmp_header{};
- icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
- icmp_header.icmp6_mtu =
- connection()->GetGuaranteedLargestMessagePayload();
-
- CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
- [this](quiche::QuicheStringPiece icmp_packet) {
- writer_->WritePacketToNetwork(icmp_packet.data(),
- icmp_packet.size());
- });
+ QuicUniqueBufferPtr buffer = MakeUniqueBuffer(
+ connection()->helper()->GetStreamSendBufferAllocator(), packet.size());
+ memcpy(buffer.get(), packet.data(), packet.size());
+ QuicMemSlice slice(std::move(buffer), packet.size());
+ switch (SendMessage(QuicMemSliceSpan(&slice), /*flush=*/true).status) {
+ case MESSAGE_STATUS_SUCCESS:
+ break;
+ case MESSAGE_STATUS_TOO_LARGE: {
+ if (packet.size() < sizeof(ip6_hdr)) {
+ QUIC_BUG << "Dropped malformed packet: IPv6 header too short";
break;
}
- case MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED:
- QUIC_BUG << "MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED";
- break;
- case MESSAGE_STATUS_UNSUPPORTED:
- QUIC_BUG << "MESSAGE_STATUS_UNSUPPORTED";
- break;
- case MESSAGE_STATUS_BLOCKED:
- QUIC_BUG << "MESSAGE_STATUS_BLOCKED";
- break;
- case MESSAGE_STATUS_INTERNAL_ERROR:
- QUIC_BUG << "MESSAGE_STATUS_INTERNAL_ERROR";
- break;
+ auto* header = reinterpret_cast<const ip6_hdr*>(packet.begin());
+ icmp6_hdr icmp_header{};
+ icmp_header.icmp6_type = ICMP6_PACKET_TOO_BIG;
+ icmp_header.icmp6_mtu =
+ connection()->GetGuaranteedLargestMessagePayload();
+
+ CreateIcmpPacket(header->ip6_dst, header->ip6_src, icmp_header, packet,
+ [this](quiche::QuicheStringPiece icmp_packet) {
+ writer_->WritePacketToNetwork(icmp_packet.data(),
+ icmp_packet.size());
+ });
+ break;
}
- return;
+ case MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED:
+ QUIC_BUG << "MESSAGE_STATUS_ENCRYPTION_NOT_ESTABLISHED";
+ break;
+ case MESSAGE_STATUS_UNSUPPORTED:
+ QUIC_BUG << "MESSAGE_STATUS_UNSUPPORTED";
+ break;
+ case MESSAGE_STATUS_BLOCKED:
+ QUIC_BUG << "MESSAGE_STATUS_BLOCKED";
+ break;
+ case MESSAGE_STATUS_INTERNAL_ERROR:
+ QUIC_BUG << "MESSAGE_STATUS_INTERNAL_ERROR";
+ break;
}
-
- // QBONE streams are ephemeral.
- QuicStream* stream = CreateOutgoingStream();
- if (!stream) {
- QUIC_BUG << "Failed to create an outgoing QBONE stream.";
- return;
- }
-
- QboneWriteOnlyStream* qbone_stream =
- static_cast<QboneWriteOnlyStream*>(stream);
- qbone_stream->WritePacketToQuicStream(packet);
}
uint64_t QboneSessionBase::GetNumEphemeralPackets() const {
return num_ephemeral_packets_;
}
-uint64_t QboneSessionBase::GetNumStreamedPackets() const {
- return num_streamed_packets_;
-}
-
uint64_t QboneSessionBase::GetNumMessagePackets() const {
return num_message_packets_;
}
-uint64_t QboneSessionBase::GetNumFallbackToStream() const {
- return num_fallback_to_stream_;
-}
-
void QboneSessionBase::set_writer(QbonePacketWriter* writer) {
writer_ = writer;
testing::testvalue::Adjust("quic_QbonePacketWriter", &writer_);
diff --git a/quic/qbone/qbone_session_base.h b/quic/qbone/qbone_session_base.h
index 4b95130..4160ef2 100644
--- a/quic/qbone/qbone_session_base.h
+++ b/quic/qbone/qbone_session_base.h
@@ -12,7 +12,6 @@
#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
#include "net/third_party/quiche/src/quic/qbone/qbone_packet_writer.h"
-#include "net/third_party/quiche/src/quic/qbone/qbone_stream.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
namespace quic {
@@ -31,8 +30,6 @@
// Overrides from QuicSession.
// This will ensure that the crypto session is created.
void Initialize() override;
- // This will check if the packet is wholly contained.
- void OnStreamFrame(const QuicStreamFrame& frame) override;
// Called whenever a MESSAGE frame is received.
void OnMessageReceived(quiche::QuicheStringPiece message) override;
@@ -44,22 +41,11 @@
// a QboneReadOnlyStream.
uint64_t GetNumEphemeralPackets() const;
- // Returns the number of QBONE network packets that were via
- // multiple packets, requiring the creation of a QboneReadOnlyStream.
- uint64_t GetNumStreamedPackets() const;
-
// Returns the number of QBONE network packets that were received using QUIC
// MESSAGE frame.
uint64_t GetNumMessagePackets() const;
- // Returns the number of times sending a MESSAGE frame failed, and the session
- // used an ephemeral stream instead.
- uint64_t GetNumFallbackToStream() const;
-
void set_writer(QbonePacketWriter* writer);
- void set_send_packets_as_messages(bool send_packets_as_messages) {
- send_packets_as_messages_ = send_packets_as_messages;
- }
protected:
virtual std::unique_ptr<QuicCryptoStream> CreateCryptoStream() = 0;
@@ -75,12 +61,6 @@
return true;
}
- QuicStream* CreateOutgoingStream();
- std::unique_ptr<QuicStream> CreateDataStream(QuicStreamId id);
- // Activates a QuicStream. The session takes ownership of the stream, but
- // returns an unowned pointer to the stream for convenience.
- QuicStream* ActivateDataStream(std::unique_ptr<QuicStream> stream);
-
// Accepts a given packet from the network and writes it out
// to the QUIC stream. This will create an ephemeral stream per
// packet. This function will return true if a stream was created
@@ -90,11 +70,6 @@
QbonePacketWriter* writer_;
- // If true, MESSAGE frames are used for short datagrams. If false, ephemeral
- // streams are used instead. Note that receiving MESSAGE frames is always
- // supported.
- bool send_packets_as_messages_ = false;
-
private:
// Used for the crypto handshake.
std::unique_ptr<QuicCryptoStream> crypto_stream_;
diff --git a/quic/qbone/qbone_session_test.cc b/quic/qbone/qbone_session_test.cc
index 243a5c5..493034f 100644
--- a/quic/qbone/qbone_session_test.cc
+++ b/quic/qbone/qbone_session_test.cc
@@ -190,7 +190,7 @@
class DataSavingQbonePacketWriter : public QbonePacketWriter {
public:
void WritePacketToNetwork(const char* packet, size_t size) override {
- data_.push_back(std::string(packet, size));
+ data_.emplace_back(std::string(packet, size));
}
const std::vector<std::string>& data() { return data_; }
@@ -425,7 +425,7 @@
// Test handshake establishment and sending/receiving of data for two
// directions.
- void TestStreamConnection(bool use_messages) {
+ void TestConnection() {
ASSERT_TRUE(server_peer_->OneRttKeysAvailable());
ASSERT_TRUE(client_peer_->OneRttKeysAvailable());
ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
@@ -457,22 +457,18 @@
EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
EXPECT_EQ(0u, client_peer_->GetNumActiveStreams());
- // Try to send long payloads that are larger than the QUIC MTU but
- // smaller than the QBONE max size.
- // This should trigger the non-ephemeral stream code path.
- std::string long_data(
- QboneConstants::kMaxQbonePacketBytes - sizeof(ip6_hdr) - 1, 'A');
+ const QuicPacketLength max_packet_length = std::max(
+ server_peer_->connection()->GetGuaranteedLargestMessagePayload(),
+ client_peer_->connection()->GetGuaranteedLargestMessagePayload());
+
+ std::string long_data(max_packet_length + 1, 'A');
QUIC_LOG(INFO) << "Sending server -> client long data";
server_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
runner_.Run();
- if (use_messages) {
- ExpectICMPTooBigResponse(
- server_writer_->data(),
- server_peer_->connection()->GetGuaranteedLargestMessagePayload(),
- TestPacketOut(long_data));
- } else {
- EXPECT_THAT(client_writer_->data(), Contains(TestPacketOut(long_data)));
- }
+ ExpectICMPTooBigResponse(
+ server_writer_->data(),
+ server_peer_->connection()->GetGuaranteedLargestMessagePayload(),
+ TestPacketOut(long_data));
EXPECT_THAT(server_writer_->data(),
Not(Contains(TestPacketOut(long_data))));
EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
@@ -481,34 +477,18 @@
QUIC_LOG(INFO) << "Sending client -> server long data";
client_peer_->ProcessPacketFromNetwork(TestPacketIn(long_data));
runner_.Run();
- if (use_messages) {
- ExpectICMPTooBigResponse(
- client_writer_->data(),
- client_peer_->connection()->GetGuaranteedLargestMessagePayload(),
- TestPacketIn(long_data));
- } else {
- EXPECT_THAT(server_writer_->data(), Contains(TestPacketOut(long_data)));
- }
+ ExpectICMPTooBigResponse(
+ client_writer_->data(),
+ client_peer_->connection()->GetGuaranteedLargestMessagePayload(),
+ TestPacketIn(long_data));
EXPECT_FALSE(client_peer_->EarlyDataAccepted());
EXPECT_FALSE(client_peer_->ReceivedInchoateReject());
EXPECT_THAT(client_peer_->GetNumReceivedServerConfigUpdates(), Eq(0));
- if (!use_messages) {
- EXPECT_THAT(client_peer_->GetNumStreamedPackets(), Eq(1));
- EXPECT_THAT(server_peer_->GetNumStreamedPackets(), Eq(1));
- }
-
- if (use_messages) {
- EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(0));
- EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(0));
- EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(2));
- EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(2));
- } else {
- EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(2));
- EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(2));
- EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(0));
- EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(0));
- }
+ EXPECT_THAT(client_peer_->GetNumEphemeralPackets(), Eq(0));
+ EXPECT_THAT(server_peer_->GetNumEphemeralPackets(), Eq(0));
+ EXPECT_THAT(client_peer_->GetNumMessagePackets(), Eq(2));
+ EXPECT_THAT(server_peer_->GetNumMessagePackets(), Eq(2));
// All streams are ephemeral and should be gone.
EXPECT_EQ(0u, server_peer_->GetNumActiveStreams());
@@ -552,20 +532,10 @@
::testing::ValuesIn(GetTestParams()),
::testing::PrintToStringParamName());
-TEST_P(QboneSessionTest, StreamConnection) {
- CreateClientAndServerSessions();
- client_peer_->set_send_packets_as_messages(false);
- server_peer_->set_send_packets_as_messages(false);
- StartHandshake();
- TestStreamConnection(false);
-}
-
TEST_P(QboneSessionTest, Messages) {
CreateClientAndServerSessions();
- client_peer_->set_send_packets_as_messages(true);
- server_peer_->set_send_packets_as_messages(true);
StartHandshake();
- TestStreamConnection(true);
+ TestConnection();
}
TEST_P(QboneSessionTest, ClientRejection) {
diff --git a/quic/qbone/qbone_stream.cc b/quic/qbone/qbone_stream.cc
deleted file mode 100644
index 4d18889..0000000
--- a/quic/qbone/qbone_stream.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2019 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.
-
-#include "net/third_party/quiche/src/quic/qbone/qbone_stream.h"
-
-#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
-#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
-#include "net/third_party/quiche/src/quic/core/quic_types.h"
-#include "net/third_party/quiche/src/quic/qbone/qbone_constants.h"
-#include "net/third_party/quiche/src/quic/qbone/qbone_session_base.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-ABSL_FLAG(int, qbone_stream_ttl_secs, 3, "The QBONE Stream TTL in seconds.");
-
-namespace quic {
-
-QboneWriteOnlyStream::QboneWriteOnlyStream(QuicStreamId id,
- QuicSession* session)
- : QuicStream(id, session, /*is_static=*/false, WRITE_UNIDIRECTIONAL) {
- // QBONE uses a LIFO queue to try to always make progress. An individual
- // packet may persist for upto to qbone_stream_ttl_secs seconds in memory.
- MaybeSetTtl(
- QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs)));
-}
-
-void QboneWriteOnlyStream::WritePacketToQuicStream(
- quiche::QuicheStringPiece packet) {
- // Streams are one way and ephemeral. This function should only be
- // called once.
- WriteOrBufferData(packet, /* fin= */ true, nullptr);
-}
-
-QboneReadOnlyStream::QboneReadOnlyStream(QuicStreamId id,
- QboneSessionBase* session)
- : QuicStream(id,
- session,
- /*is_static=*/false,
- READ_UNIDIRECTIONAL),
- session_(session) {
- // QBONE uses a LIFO queue to try to always make progress. An individual
- // packet may persist for upto to qbone_stream_ttl_secs seconds in memory.
- MaybeSetTtl(
- QuicTime::Delta::FromSeconds(GetQuicFlag(FLAGS_qbone_stream_ttl_secs)));
-}
-
-void QboneReadOnlyStream::OnDataAvailable() {
- // Read in data and buffer it, attempt to frame to see if there's a packet.
- sequencer()->Read(&buffer_);
- if (sequencer()->IsClosed()) {
- session_->ProcessPacketFromPeer(buffer_);
- OnFinRead();
- return;
- }
- if (buffer_.size() > QboneConstants::kMaxQbonePacketBytes) {
- if (!rst_sent()) {
- Reset(QUIC_BAD_APPLICATION_PAYLOAD);
- }
- StopReading();
- }
-}
-
-} // namespace quic
diff --git a/quic/qbone/qbone_stream.h b/quic/qbone/qbone_stream.h
deleted file mode 100644
index 8a6313b..0000000
--- a/quic/qbone/qbone_stream.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2019 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.
-
-#ifndef QUICHE_QUIC_QBONE_QBONE_STREAM_H_
-#define QUICHE_QUIC_QBONE_QBONE_STREAM_H_
-
-#include "net/third_party/quiche/src/quic/core/quic_session.h"
-#include "net/third_party/quiche/src/quic/core/quic_stream.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-
-namespace quic {
-
-class QboneSessionBase;
-
-// QboneWriteOnlyStream is responsible for sending data for a single
-// packet to the other side.
-// Note that the stream will be created HalfClosed (reads will be closed).
-class QUIC_EXPORT_PRIVATE QboneWriteOnlyStream : public QuicStream {
- public:
- QboneWriteOnlyStream(QuicStreamId id, QuicSession* session);
-
- // QuicStream implementation. QBONE writers are ephemeral and don't
- // read any data.
- void OnDataAvailable() override {}
-
- // Write a network packet over the quic stream.
- void WritePacketToQuicStream(quiche::QuicheStringPiece packet);
-};
-
-// QboneReadOnlyStream will be used if we find an incoming stream that
-// isn't fully contained. It will buffer the data when available and
-// attempt to parse it as a packet to send to the network when a FIN
-// is found.
-// Note that the stream will be created HalfClosed (writes will be closed).
-class QUIC_EXPORT_PRIVATE QboneReadOnlyStream : public QuicStream {
- public:
- QboneReadOnlyStream(QuicStreamId id, QboneSessionBase* session);
-
- ~QboneReadOnlyStream() override = default;
-
- // QuicStream overrides.
- // OnDataAvailable is called when there is data in the quic stream buffer.
- // This will copy the buffer locally and attempt to parse it to write out
- // packets to the network.
- void OnDataAvailable() override;
-
- private:
- std::string buffer_;
- QboneSessionBase* session_;
-};
-
-} // namespace quic
-
-#endif // QUICHE_QUIC_QBONE_QBONE_STREAM_H_
diff --git a/quic/qbone/qbone_stream_test.cc b/quic/qbone/qbone_stream_test.cc
deleted file mode 100644
index cfe9645..0000000
--- a/quic/qbone/qbone_stream_test.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright (c) 2019 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.
-
-#include "net/third_party/quiche/src/quic/qbone/qbone_stream.h"
-
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
-#include "net/third_party/quiche/src/quic/core/quic_session.h"
-#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h"
-#include "net/third_party/quiche/src/quic/core/quic_utils.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_test_loopback.h"
-#include "net/third_party/quiche/src/quic/qbone/qbone_constants.h"
-#include "net/third_party/quiche/src/quic/qbone/qbone_session_base.h"
-#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-
-namespace quic {
-
-namespace {
-
-using ::testing::_;
-using ::testing::StrictMock;
-
-// MockQuicSession that does not create streams and writes data from
-// QuicStream to a string.
-class MockQuicSession : public QboneSessionBase {
- public:
- MockQuicSession(QuicConnection* connection, const QuicConfig& config)
- : QboneSessionBase(connection,
- nullptr /*visitor*/,
- config,
- CurrentSupportedVersions(),
- nullptr /*writer*/) {}
-
- ~MockQuicSession() override {}
-
- // Writes outgoing data from QuicStream to a string.
- QuicConsumedData WritevData(
- QuicStreamId id,
- size_t write_length,
- QuicStreamOffset offset,
- StreamSendingState state,
- TransmissionType type,
- quiche::QuicheOptional<EncryptionLevel> level) override {
- if (!writable_) {
- return QuicConsumedData(0, false);
- }
-
- return QuicConsumedData(write_length, state != StreamSendingState::NO_FIN);
- }
-
- QboneReadOnlyStream* CreateIncomingStream(QuicStreamId id) override {
- return nullptr;
- }
-
- const QuicCryptoStream* GetCryptoStream() const override { return nullptr; }
- QuicCryptoStream* GetMutableCryptoStream() override { return nullptr; }
-
- // Called by QuicStream when they want to close stream.
- MOCK_METHOD(void,
- SendRstStream,
- (QuicStreamId, QuicRstStreamErrorCode, QuicStreamOffset, bool),
- (override));
-
- // Sets whether data is written to buffer, or else if this is write blocked.
- void set_writable(bool writable) { writable_ = writable; }
-
- // Tracks whether the stream is write blocked and its priority.
- void RegisterReliableStream(QuicStreamId stream_id) {
- // The priority effectively does not matter. Put all streams on the same
- // priority.
- write_blocked_streams()->RegisterStream(
- stream_id,
- /*is_static_stream=*/false,
- /* precedence= */ spdy::SpdyStreamPrecedence(3));
- }
-
- // The session take ownership of the stream.
- void ActivateReliableStream(std::unique_ptr<QuicStream> stream) {
- ActivateStream(std::move(stream));
- }
-
- std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override {
- return nullptr;
- }
-
- MOCK_METHOD(void,
- ProcessPacketFromPeer,
- (quiche::QuicheStringPiece),
- (override));
- MOCK_METHOD(void,
- ProcessPacketFromNetwork,
- (quiche::QuicheStringPiece),
- (override));
-
- private:
- // Whether data is written to write_buffer_.
- bool writable_ = true;
-};
-
-// Packet writer that does nothing. This is required for QuicConnection but
-// isn't used for writing data.
-class DummyPacketWriter : public QuicPacketWriter {
- public:
- DummyPacketWriter() {}
-
- // QuicPacketWriter overrides.
- WriteResult WritePacket(const char* buffer,
- size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
- return WriteResult(WRITE_STATUS_ERROR, 0);
- }
-
- bool IsWriteBlocked() const override { return false; };
-
- void SetWritable() override {}
-
- QuicByteCount GetMaxPacketSize(
- const QuicSocketAddress& peer_address) const override {
- return 0;
- }
-
- bool SupportsReleaseTime() const override { return false; }
-
- bool IsBatchMode() const override { return false; }
-
- QuicPacketBuffer GetNextWriteLocation(
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address) override {
- return {nullptr, nullptr};
- }
-
- WriteResult Flush() override { return WriteResult(WRITE_STATUS_OK, 0); }
-};
-
-class QboneReadOnlyStreamTest : public ::testing::Test,
- public QuicConnectionHelperInterface {
- public:
- void CreateReliableQuicStream() {
- // Arbitrary values for QuicConnection.
- Perspective perspective = Perspective::IS_SERVER;
- bool owns_writer = true;
-
- alarm_factory_ = std::make_unique<test::MockAlarmFactory>();
-
- connection_.reset(new QuicConnection(
- test::TestConnectionId(0), QuicSocketAddress(TestLoopback(), 0),
- this /*QuicConnectionHelperInterface*/, alarm_factory_.get(),
- new DummyPacketWriter(), owns_writer, perspective,
- ParsedVersionOfIndex(CurrentSupportedVersions(), 0)));
- clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
- session_ = std::make_unique<StrictMock<MockQuicSession>>(connection_.get(),
- QuicConfig());
- stream_ = new QboneReadOnlyStream(kStreamId, session_.get());
- session_->ActivateReliableStream(
- std::unique_ptr<QboneReadOnlyStream>(stream_));
- }
-
- ~QboneReadOnlyStreamTest() override {}
-
- const QuicClock* GetClock() const override { return &clock_; }
-
- QuicRandom* GetRandomGenerator() override {
- return QuicRandom::GetInstance();
- }
-
- QuicBufferAllocator* GetStreamSendBufferAllocator() override {
- return &buffer_allocator_;
- }
-
- protected:
- // The QuicSession will take the ownership.
- QboneReadOnlyStream* stream_;
- std::unique_ptr<StrictMock<MockQuicSession>> session_;
- std::unique_ptr<QuicAlarmFactory> alarm_factory_;
- std::unique_ptr<QuicConnection> connection_;
- // Used to implement the QuicConnectionHelperInterface.
- SimpleBufferAllocator buffer_allocator_;
- MockClock clock_;
- const QuicStreamId kStreamId = QuicUtils::GetFirstUnidirectionalStreamId(
- CurrentSupportedVersions()[0].transport_version,
- Perspective::IS_CLIENT);
-};
-
-// Read an entire string.
-TEST_F(QboneReadOnlyStreamTest, ReadDataWhole) {
- std::string packet = "Stuff";
- CreateReliableQuicStream();
- QuicStreamFrame frame(kStreamId, true, 0, packet);
- EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
- stream_->OnStreamFrame(frame);
-}
-
-// Test buffering.
-TEST_F(QboneReadOnlyStreamTest, ReadBuffered) {
- CreateReliableQuicStream();
- std::string packet = "Stuf";
- {
- QuicStreamFrame frame(kStreamId, false, 0, packet);
- stream_->OnStreamFrame(frame);
- }
- // We didn't write 5 bytes yet...
-
- packet = "f";
- EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
- {
- QuicStreamFrame frame(kStreamId, true, 4, packet);
- stream_->OnStreamFrame(frame);
- }
-}
-
-TEST_F(QboneReadOnlyStreamTest, ReadOutOfOrder) {
- CreateReliableQuicStream();
- std::string packet = "f";
- {
- QuicStreamFrame frame(kStreamId, true, 4, packet);
- stream_->OnStreamFrame(frame);
- }
-
- packet = "S";
- {
- QuicStreamFrame frame(kStreamId, false, 0, packet);
- stream_->OnStreamFrame(frame);
- }
-
- packet = "tuf";
- EXPECT_CALL(*session_, ProcessPacketFromPeer("Stuff"));
- {
- QuicStreamFrame frame(kStreamId, false, 1, packet);
- stream_->OnStreamFrame(frame);
- }
-}
-
-// Test buffering too many bytes.
-TEST_F(QboneReadOnlyStreamTest, ReadBufferedTooLarge) {
- CreateReliableQuicStream();
- std::string packet = "0123456789";
- int iterations = (QboneConstants::kMaxQbonePacketBytes / packet.size()) + 2;
- EXPECT_CALL(*session_,
- SendRstStream(kStreamId, QUIC_BAD_APPLICATION_PAYLOAD, _, _));
- for (int i = 0; i < iterations; ++i) {
- QuicStreamFrame frame(kStreamId, i == (iterations - 1), i * packet.size(),
- packet);
- if (!stream_->reading_stopped()) {
- stream_->OnStreamFrame(frame);
- }
- }
- // We should have nothing written to the network and the stream
- // should have stopped reading.
- EXPECT_TRUE(stream_->reading_stopped());
-}
-
-} // namespace
-
-} // namespace quic