Make GfeQboneServerSession buffer STREAM_FRAME (with pending stream) and drop MESSAGE_FRAME before LOAS authentication completes.
Other stream related frames on the server side:
STREAM_RESET_FRAME -> connection close
STOP_SENDING_FRAME -> connection close
WINDOW_UPDATE_FRAME is handled by pending stream before LOAS authentication completes.
Other stream related frames on the client side:
STREAM_RESET_FRAME -> connection close
STOP_SENDING_FRAME -> connection close
WINDOW_UPDATE_FRAME received before LOAS authentication -> connection close
Protected by FLAGS_qbone_server_support_h3_loas.
PiperOrigin-RevId: 421072604
diff --git a/quic/qbone/qbone_control_stream.cc b/quic/qbone/qbone_control_stream.cc
index 7303b06..61a9afe 100644
--- a/quic/qbone/qbone_control_stream.cc
+++ b/quic/qbone/qbone_control_stream.cc
@@ -6,6 +6,7 @@
#include <cstdint>
#include <limits>
+
#include "absl/strings/string_view.h"
#include "quic/core/quic_session.h"
#include "quic/platform/api/quic_bug_tracker.h"
@@ -25,6 +26,14 @@
BIDIRECTIONAL),
pending_message_size_(0) {}
+QboneControlStreamBase::QboneControlStreamBase(quic::PendingStream* pending,
+ QuicSession* session)
+ : QuicStream(pending, session, /*is_static=*/true),
+ pending_message_size_(0) {
+ QUICHE_DCHECK_EQ(pending->id(), QboneConstants::GetControlStreamId(
+ session->transport_version()));
+}
+
void QboneControlStreamBase::OnDataAvailable() {
sequencer()->Read(&buffer_);
while (true) {
diff --git a/quic/qbone/qbone_control_stream.h b/quic/qbone/qbone_control_stream.h
index d0c2b1a..c38697d 100644
--- a/quic/qbone/qbone_control_stream.h
+++ b/quic/qbone/qbone_control_stream.h
@@ -16,6 +16,7 @@
class QUIC_EXPORT_PRIVATE QboneControlStreamBase : public QuicStream {
public:
explicit QboneControlStreamBase(QuicSession* session);
+ QboneControlStreamBase(quic::PendingStream* pending, QuicSession* session);
void OnDataAvailable() override;
@@ -46,6 +47,9 @@
QboneControlStream(QuicSession* session, Handler* handler)
: QboneControlStreamBase(session), handler_(handler) {}
+ QboneControlStream(quic::PendingStream* pending, QuicSession* session,
+ Handler* handler)
+ : QboneControlStreamBase(pending, session), handler_(handler) {}
bool SendRequest(const Outgoing& request) { return SendMessage(request); }
diff --git a/quic/qbone/qbone_server_session.cc b/quic/qbone/qbone_server_session.cc
index 2ddb8e4..1fc0842 100644
--- a/quic/qbone/qbone_server_session.cc
+++ b/quic/qbone/qbone_server_session.cc
@@ -72,6 +72,17 @@
ActivateStream(std::move(control_stream));
}
+QuicStream* QboneServerSession::CreateControlStreamFromPendingStream(
+ PendingStream* pending) {
+ QUICHE_DCHECK(control_stream_ == nullptr);
+ // Register the reserved control stream.
+ auto control_stream =
+ std::make_unique<QboneServerControlStream>(pending, this, handler_);
+ control_stream_ = control_stream.get();
+ ActivateStream(std::move(control_stream));
+ return control_stream_;
+}
+
void QboneServerSession::Initialize() {
QboneSessionBase::Initialize();
if (!GetQuicFlag(FLAGS_qbone_server_defer_control_stream_creation)) {
diff --git a/quic/qbone/qbone_server_session.h b/quic/qbone/qbone_server_session.h
index f398f06..d206e4d 100644
--- a/quic/qbone/qbone_server_session.h
+++ b/quic/qbone/qbone_server_session.h
@@ -76,9 +76,13 @@
// QboneSessionBase interface implementation.
std::unique_ptr<QuicCryptoStream> CreateCryptoStream() override;
- // Instantiate QboneServerControlStream.
+ // Instantiates QboneServerControlStream.
void CreateControlStream();
+ // Instantiates QboneServerControlStream from the pending stream and returns a
+ // pointer to it.
+ QuicStream* CreateControlStreamFromPendingStream(PendingStream* pending);
+
// The packet processor.
QbonePacketProcessor processor_;