blob: 31a5070960f5530a3cfbc6406fad8e0b06ca5ddd [file] [log] [blame]
wubf975eac2019-08-19 19:41:01 -07001// Copyright (c) 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/qbone/qbone_control_stream.h"
6
7#include "net/third_party/quiche/src/quic/core/quic_session.h"
8#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
9#include "net/third_party/quiche/src/quic/qbone/qbone_constants.h"
dmcardled70b99e2019-12-12 09:52:39 -080010#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
wubf975eac2019-08-19 19:41:01 -070011
12namespace quic {
13
14namespace {
15static constexpr size_t kRequestSizeBytes = sizeof(uint16_t);
16} // namespace
17
18QboneControlStreamBase::QboneControlStreamBase(QuicSession* session)
renjietangd1d00852019-09-06 10:43:12 -070019 : QuicStream(
20 QboneConstants::GetControlStreamId(session->transport_version()),
21 session,
22 /*is_static=*/true,
23 BIDIRECTIONAL),
wubf975eac2019-08-19 19:41:01 -070024 pending_message_size_(0) {}
25
26void QboneControlStreamBase::OnDataAvailable() {
27 sequencer()->Read(&buffer_);
28 while (true) {
29 if (pending_message_size_ == 0) {
30 // Start of a message.
31 if (buffer_.size() < kRequestSizeBytes) {
32 return;
33 }
34 memcpy(&pending_message_size_, buffer_.data(), kRequestSizeBytes);
35 buffer_.erase(0, kRequestSizeBytes);
36 }
37 // Continuation of a message.
38 if (buffer_.size() < pending_message_size_) {
39 return;
40 }
QUICHE teamb80d7c32020-02-23 23:44:20 -080041 std::string tmp = buffer_.substr(0, pending_message_size_);
wubf975eac2019-08-19 19:41:01 -070042 buffer_.erase(0, pending_message_size_);
43 pending_message_size_ = 0;
44 OnMessage(tmp);
45 }
46}
47
48bool QboneControlStreamBase::SendMessage(const proto2::Message& proto) {
QUICHE teamb80d7c32020-02-23 23:44:20 -080049 std::string tmp;
wubf975eac2019-08-19 19:41:01 -070050 if (!proto.SerializeToString(&tmp)) {
51 QUIC_BUG << "Failed to serialize QboneControlRequest";
52 return false;
53 }
54 if (tmp.size() > kuint16max) {
55 QUIC_BUG << "QboneControlRequest too large: " << tmp.size() << " > "
56 << kuint16max;
57 return false;
58 }
59 uint16_t size = tmp.size();
60 char size_str[kRequestSizeBytes];
61 memcpy(size_str, &size, kRequestSizeBytes);
dmcardled70b99e2019-12-12 09:52:39 -080062 WriteOrBufferData(quiche::QuicheStringPiece(size_str, kRequestSizeBytes),
63 false, nullptr);
wubf975eac2019-08-19 19:41:01 -070064 WriteOrBufferData(tmp, false, nullptr);
65 return true;
66}
67
68} // namespace quic