blob: e0d98ff81515afdbc0da675fdaa76def18e78116 [file] [log] [blame]
// 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 "quic/qbone/qbone_control_stream.h"
#include "absl/strings/string_view.h"
#include "quic/core/quic_session.h"
#include "quic/platform/api/quic_bug_tracker.h"
#include "quic/qbone/qbone_constants.h"
namespace quic {
namespace {
static constexpr size_t kRequestSizeBytes = sizeof(uint16_t);
} // namespace
QboneControlStreamBase::QboneControlStreamBase(QuicSession* session)
: QuicStream(
QboneConstants::GetControlStreamId(session->transport_version()),
session,
/*is_static=*/true,
BIDIRECTIONAL),
pending_message_size_(0) {}
void QboneControlStreamBase::OnDataAvailable() {
sequencer()->Read(&buffer_);
while (true) {
if (pending_message_size_ == 0) {
// Start of a message.
if (buffer_.size() < kRequestSizeBytes) {
return;
}
memcpy(&pending_message_size_, buffer_.data(), kRequestSizeBytes);
buffer_.erase(0, kRequestSizeBytes);
}
// Continuation of a message.
if (buffer_.size() < pending_message_size_) {
return;
}
std::string tmp = buffer_.substr(0, pending_message_size_);
buffer_.erase(0, pending_message_size_);
pending_message_size_ = 0;
OnMessage(tmp);
}
}
bool QboneControlStreamBase::SendMessage(const proto2::Message& proto) {
std::string tmp;
if (!proto.SerializeToString(&tmp)) {
QUIC_BUG_V2(quic_bug_11023_1) << "Failed to serialize QboneControlRequest";
return false;
}
if (tmp.size() > kuint16max) {
QUIC_BUG_V2(quic_bug_11023_2)
<< "QboneControlRequest too large: " << tmp.size() << " > "
<< kuint16max;
return false;
}
uint16_t size = tmp.size();
char size_str[kRequestSizeBytes];
memcpy(size_str, &size, kRequestSizeBytes);
WriteOrBufferData(absl::string_view(size_str, kRequestSizeBytes), false,
nullptr);
WriteOrBufferData(tmp, false, nullptr);
return true;
}
void QboneControlStreamBase::OnStreamReset(
const QuicRstStreamFrame& /*frame*/) {
stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
"Attempt to reset control stream");
}
} // namespace quic