| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 "remoting/protocol/quic_channel.h" | |
| 6 | |
| 7 #include "base/callback_helpers.h" | |
| 8 #include "net/base/io_buffer.h" | |
| 9 #include "net/base/net_errors.h" | |
| 10 | |
| 11 namespace remoting { | |
| 12 namespace protocol { | |
| 13 | |
| 14 static const size_t kNamePrefixLength = 1; | |
| 15 static const size_t kMaxNameLength = 255; | |
| 16 | |
| 17 QuicChannel::QuicChannel(net::QuicP2PStream* stream, | |
| 18 const base::Closure& on_destroyed_callback) | |
| 19 : stream_(stream), on_destroyed_callback_(on_destroyed_callback) { | |
| 20 DCHECK(stream_); | |
| 21 stream_->SetDelegate(this); | |
| 22 } | |
| 23 | |
| 24 QuicChannel::~QuicChannel() { | |
| 25 // Don't call the read callback when destroying the stream. | |
| 26 read_callback_.Reset(); | |
| 27 | |
| 28 on_destroyed_callback_.Run(); | |
| 29 | |
| 30 // The callback must destroy the stream which must result in OnClose(). | |
| 31 DCHECK(!stream_); | |
| 32 } | |
| 33 | |
| 34 int QuicChannel::Read(const scoped_refptr<net::IOBuffer>& buffer, | |
| 35 int buffer_len, | |
| 36 const net::CompletionCallback& callback) { | |
| 37 DCHECK(read_callback_.is_null()); | |
| 38 | |
| 39 if (error_ != net::OK) | |
| 40 return error_; | |
| 41 | |
| 42 if (data_received_.total_bytes() == 0) { | |
| 43 read_buffer_ = buffer; | |
| 44 read_buffer_size_ = buffer_len; | |
| 45 read_callback_ = callback; | |
| 46 return net::ERR_IO_PENDING; | |
| 47 } | |
| 48 | |
| 49 int result = std::min(buffer_len, data_received_.total_bytes()); | |
| 50 data_received_.CopyTo(buffer->data(), result); | |
| 51 data_received_.CropFront(result); | |
| 52 return result; | |
| 53 } | |
| 54 | |
| 55 int QuicChannel::Write(const scoped_refptr<net::IOBuffer>& buffer, | |
| 56 int buffer_len, | |
| 57 const net::CompletionCallback& callback) { | |
| 58 if (error_ != net::OK) | |
| 59 return error_; | |
| 60 | |
| 61 return stream_->Write(base::StringPiece(buffer->data(), buffer_len), | |
| 62 callback); | |
| 63 } | |
| 64 | |
| 65 void QuicChannel::SetName(const std::string& name) { | |
| 66 DCHECK(name_.empty()); | |
| 67 | |
| 68 name_ = name; | |
| 69 } | |
| 70 | |
| 71 void QuicChannel::OnDataReceived(const char* data, int length) { | |
| 72 if (read_callback_.is_null()) { | |
| 73 data_received_.AppendCopyOf(data, length); | |
| 74 return; | |
| 75 } | |
| 76 | |
| 77 DCHECK_EQ(data_received_.total_bytes(), 0); | |
| 78 int bytes_to_read = std::min(length, read_buffer_size_); | |
| 79 memcpy(read_buffer_->data(), data, bytes_to_read); | |
| 80 read_buffer_ = nullptr; | |
| 81 | |
| 82 // Copy leftover data to |data_received_|. | |
| 83 if (length > bytes_to_read) | |
| 84 data_received_.AppendCopyOf(data + bytes_to_read, length - bytes_to_read); | |
| 85 | |
| 86 base::ResetAndReturn(&read_callback_).Run(bytes_to_read); | |
| 87 } | |
| 88 | |
| 89 void QuicChannel::OnClose(net::QuicErrorCode error) { | |
| 90 error_ = (error == net::QUIC_NO_ERROR) ? net::ERR_CONNECTION_CLOSED | |
| 91 : net::ERR_QUIC_PROTOCOL_ERROR; | |
| 92 stream_ = nullptr; | |
| 93 if (!read_callback_.is_null()) { | |
| 94 base::ResetAndReturn(&read_callback_).Run(error_); | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 QuicClientChannel::QuicClientChannel(net::QuicP2PStream* stream, | |
| 99 const base::Closure& on_destroyed_callback, | |
| 100 const std::string& name) | |
| 101 : QuicChannel(stream, on_destroyed_callback) { | |
| 102 CHECK_LE(name.size(), kMaxNameLength); | |
| 103 | |
| 104 SetName(name); | |
| 105 | |
| 106 // Send the name to the host. | |
| 107 stream_->WriteHeader( | |
| 108 std::string(kNamePrefixLength, static_cast<char>(name.size())) + name); | |
| 109 } | |
| 110 | |
| 111 QuicClientChannel::~QuicClientChannel() {} | |
| 112 | |
| 113 QuicServerChannel::QuicServerChannel( | |
| 114 net::QuicP2PStream* stream, | |
| 115 const base::Closure& on_destroyed_callback) | |
| 116 : QuicChannel(stream, on_destroyed_callback) {} | |
| 117 | |
| 118 void QuicServerChannel::ReceiveName( | |
| 119 const base::Closure& name_received_callback) { | |
| 120 name_received_callback_ = name_received_callback; | |
| 121 | |
| 122 // First read 1 byte containing name length. | |
| 123 name_read_buffer_ = new net::DrainableIOBuffer( | |
| 124 new net::IOBuffer(kNamePrefixLength), kNamePrefixLength); | |
| 125 int result = Read(name_read_buffer_, kNamePrefixLength, | |
| 126 base::Bind(&QuicServerChannel::OnNameSizeReadResult, | |
| 127 base::Unretained(this))); | |
| 128 if (result != net::ERR_IO_PENDING) | |
| 129 OnNameSizeReadResult(result); | |
| 130 } | |
| 131 | |
| 132 QuicServerChannel::~QuicServerChannel() {} | |
| 133 | |
| 134 void QuicServerChannel::OnNameSizeReadResult(int result) { | |
| 135 if (result < 0) { | |
| 136 base::ResetAndReturn(&name_received_callback_).Run(); | |
| 137 return; | |
| 138 } | |
| 139 | |
| 140 DCHECK_EQ(result, static_cast<int>(kNamePrefixLength)); | |
| 141 name_length_ = *reinterpret_cast<uint8_t*>(name_read_buffer_->data()); | |
| 142 name_read_buffer_ = | |
| 143 new net::DrainableIOBuffer(new net::IOBuffer(name_length_), name_length_); | |
| 144 ReadNameLoop(0); | |
| 145 } | |
| 146 | |
| 147 void QuicServerChannel::ReadNameLoop(int result) { | |
| 148 while (result >= 0 && name_read_buffer_->BytesRemaining() > 0) { | |
| 149 result = Read(name_read_buffer_, name_read_buffer_->BytesRemaining(), | |
| 150 base::Bind(&QuicServerChannel::OnNameReadResult, | |
| 151 base::Unretained(this))); | |
| 152 if (result >= 0) { | |
| 153 name_read_buffer_->DidConsume(result); | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 if (result < 0 && result != net::ERR_IO_PENDING) { | |
| 158 // Failed to read name for the stream. | |
| 159 base::ResetAndReturn(&name_received_callback_).Run(); | |
| 160 return; | |
| 161 } | |
| 162 | |
| 163 if (name_read_buffer_->BytesRemaining() == 0) { | |
| 164 name_read_buffer_->SetOffset(0); | |
| 165 SetName(std::string(name_read_buffer_->data(), | |
| 166 name_read_buffer_->data() + name_length_)); | |
| 167 base::ResetAndReturn(&name_received_callback_).Run(); | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 void QuicServerChannel::OnNameReadResult(int result) { | |
| 172 if (result > 0) | |
| 173 name_read_buffer_->DidConsume(result); | |
| 174 | |
| 175 ReadNameLoop(result); | |
| 176 } | |
| 177 | |
| 178 } // namespace protocol | |
| 179 } // namespace remoting | |
| OLD | NEW |