blob: f948e64c9f7d494ce88c648988f017813886793e [file] [log] [blame]
Avi Drissmand6cdf9b2022-09-15 19:52:531// Copyright 2015 The Chromium Authors
[email protected]2fc3b422010-09-28 20:59:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
sergeyu031ce3b32015-07-06 19:00:465#include "remoting/protocol/channel_socket_adapter.h"
[email protected]2fc3b422010-09-28 20:59:566
7#include <limits>
8
[email protected]ad48b7f2012-02-21 21:20:029#include "base/callback.h"
[email protected]2fc3b422010-09-28 20:59:5610#include "base/logging.h"
[email protected]2fc3b422010-09-28 20:59:5611#include "net/base/io_buffer.h"
12#include "net/base/net_errors.h"
[email protected]2fc3b422010-09-28 20:59:5613
Joe Downing39d710e2022-08-25 20:11:4514namespace remoting::protocol {
[email protected]2fc3b422010-09-28 20:59:5615
16TransportChannelSocketAdapter::TransportChannelSocketAdapter(
zhihuang1aa292f32017-01-03 19:37:5117 cricket::IceTransportInternal* ice_transport)
Joe Downing39d710e2022-08-25 20:11:4518 : channel_(ice_transport) {
[email protected]2fc3b422010-09-28 20:59:5619 DCHECK(channel_);
20
21 channel_->SignalReadPacket.connect(
22 this, &TransportChannelSocketAdapter::OnNewPacket);
23 channel_->SignalWritableState.connect(
24 this, &TransportChannelSocketAdapter::OnWritableState);
25 channel_->SignalDestroyed.connect(
26 this, &TransportChannelSocketAdapter::OnChannelDestroyed);
27}
28
29TransportChannelSocketAdapter::~TransportChannelSocketAdapter() {
Joe Downing39d710e2022-08-25 20:11:4530 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
Joe Downing353ba2c72023-01-11 22:37:3431 if (destruction_callback_) {
Evan Stade86dadf152020-03-16 20:06:3332 std::move(destruction_callback_).Run();
Joe Downing353ba2c72023-01-11 22:37:3433 }
[email protected]ad48b7f2012-02-21 21:20:0234}
35
36void TransportChannelSocketAdapter::SetOnDestroyedCallback(
Evan Stade86dadf152020-03-16 20:06:3337 base::OnceClosure callback) {
38 destruction_callback_ = std::move(callback);
[email protected]2fc3b422010-09-28 20:59:5639}
40
sergeyuaa22c082015-07-20 19:41:1341int TransportChannelSocketAdapter::Recv(
Mario Sanchez Prada670d2822019-03-18 21:52:4142 const scoped_refptr<net::IOBuffer>& buf,
43 int buffer_size,
44 const net::CompletionRepeatingCallback& callback) {
Joe Downing39d710e2022-08-25 20:11:4545 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]3f55aa12011-12-07 02:03:3346 DCHECK(buf);
47 DCHECK(!callback.is_null());
[email protected]83039bb2011-12-09 18:43:5548 CHECK(read_callback_.is_null());
[email protected]2fc3b422010-09-28 20:59:5649
50 if (!channel_) {
51 DCHECK(closed_error_code_ != net::OK);
52 return closed_error_code_;
53 }
54
55 read_callback_ = callback;
56 read_buffer_ = buf;
57 read_buffer_size_ = buffer_size;
[email protected]2fc3b422010-09-28 20:59:5658
59 return net::ERR_IO_PENDING;
60}
61
sergeyuaa22c082015-07-20 19:41:1362int TransportChannelSocketAdapter::Send(
Mario Sanchez Prada670d2822019-03-18 21:52:4163 const scoped_refptr<net::IOBuffer>& buffer,
64 int buffer_size,
65 const net::CompletionRepeatingCallback& callback) {
Joe Downing39d710e2022-08-25 20:11:4566 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]2fc3b422010-09-28 20:59:5667 DCHECK(buffer);
[email protected]83039bb2011-12-09 18:43:5568 DCHECK(!callback.is_null());
69 CHECK(write_callback_.is_null());
[email protected]2fc3b422010-09-28 20:59:5670
71 if (!channel_) {
72 DCHECK(closed_error_code_ != net::OK);
73 return closed_error_code_;
74 }
75
[email protected]4d83fbc2011-04-22 19:35:4976 int result;
[email protected]e758d4c2014-08-06 16:48:1677 rtc::PacketOptions options;
[email protected]4d83fbc2011-04-22 19:35:4978 if (channel_->writable()) {
[email protected]e6b239a2014-02-15 06:09:5279 result = channel_->SendPacket(buffer->data(), buffer_size, options);
[email protected]87185ec2011-07-27 13:25:4080 if (result < 0) {
[email protected]4d83fbc2011-04-22 19:35:4981 result = net::MapSystemError(channel_->GetError());
[email protected]87185ec2011-07-27 13:25:4082
83 // If the underlying socket returns IO pending where it shouldn't we
84 // pretend the packet is dropped and return as succeeded because no
85 // writeable callback will happen.
Joe Downing353ba2c72023-01-11 22:37:3486 if (result == net::ERR_IO_PENDING) {
[email protected]87185ec2011-07-27 13:25:4087 result = net::OK;
Joe Downing353ba2c72023-01-11 22:37:3488 }
[email protected]87185ec2011-07-27 13:25:4089 }
[email protected]4d83fbc2011-04-22 19:35:4990 } else {
91 // Channel is not writable yet.
92 result = net::ERR_IO_PENDING;
[email protected]4d83fbc2011-04-22 19:35:4993 write_callback_ = callback;
94 write_buffer_ = buffer;
95 write_buffer_size_ = buffer_size;
96 }
97
[email protected]2fc3b422010-09-28 20:59:5698 return result;
99}
100
[email protected]2fc3b422010-09-28 20:59:56101void TransportChannelSocketAdapter::Close(int error_code) {
Joe Downing39d710e2022-08-25 20:11:45102 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]2fc3b422010-09-28 20:59:56103
Joe Downing353ba2c72023-01-11 22:37:34104 if (!channel_) { // Already closed.
[email protected]2fc3b422010-09-28 20:59:56105 return;
Joe Downing353ba2c72023-01-11 22:37:34106 }
[email protected]2fc3b422010-09-28 20:59:56107
108 DCHECK(error_code != net::OK);
109 closed_error_code_ = error_code;
110 channel_->SignalReadPacket.disconnect(this);
111 channel_->SignalDestroyed.disconnect(this);
Bartek Nowierskidf0fc8a2020-06-11 01:01:31112 channel_ = nullptr;
[email protected]2fc3b422010-09-28 20:59:56113
[email protected]83039bb2011-12-09 18:43:55114 if (!read_callback_.is_null()) {
Mario Sanchez Prada670d2822019-03-18 21:52:41115 net::CompletionRepeatingCallback callback = read_callback_;
[email protected]3f55aa12011-12-07 02:03:33116 read_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09117 read_buffer_.reset();
[email protected]3f55aa12011-12-07 02:03:33118 callback.Run(error_code);
[email protected]2fc3b422010-09-28 20:59:56119 }
120
[email protected]83039bb2011-12-09 18:43:55121 if (!write_callback_.is_null()) {
Mario Sanchez Prada670d2822019-03-18 21:52:41122 net::CompletionRepeatingCallback callback = write_callback_;
[email protected]83039bb2011-12-09 18:43:55123 write_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09124 write_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55125 callback.Run(error_code);
[email protected]2fc3b422010-09-28 20:59:56126 }
127}
128
129void TransportChannelSocketAdapter::OnNewPacket(
Niels Möllere5cdbff02019-12-18 12:29:45130 rtc::PacketTransportInternal* transport,
[email protected]8bb746372012-04-26 04:20:12131 const char* data,
132 size_t data_size,
Niels Möller6c41fbf52018-12-20 10:22:56133 const int64_t& packet_time,
[email protected]8bb746372012-04-26 04:20:12134 int flags) {
Joe Downing39d710e2022-08-25 20:11:45135 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
sprangd72236c2016-10-21 08:36:04136 DCHECK_EQ(transport, channel_);
[email protected]83039bb2011-12-09 18:43:55137 if (!read_callback_.is_null()) {
[email protected]f9d8a772013-06-01 04:33:17138 DCHECK(read_buffer_.get());
[email protected]2fc3b422010-09-28 20:59:56139 CHECK_LT(data_size, static_cast<size_t>(std::numeric_limits<int>::max()));
140
141 if (read_buffer_size_ < static_cast<int>(data_size)) {
142 LOG(WARNING) << "Data buffer is smaller than the received packet. "
143 << "Dropping the data that doesn't fit.";
144 data_size = read_buffer_size_;
145 }
146
147 memcpy(read_buffer_->data(), data, data_size);
148
Mario Sanchez Prada670d2822019-03-18 21:52:41149 net::CompletionRepeatingCallback callback = read_callback_;
[email protected]83039bb2011-12-09 18:43:55150 read_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09151 read_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55152 callback.Run(data_size);
[email protected]2fc3b422010-09-28 20:59:56153 } else {
154 LOG(WARNING)
155 << "Data was received without a callback. Dropping the packet.";
156 }
157}
158
159void TransportChannelSocketAdapter::OnWritableState(
Niels Möllere5cdbff02019-12-18 12:29:45160 rtc::PacketTransportInternal* transport) {
Joe Downing39d710e2022-08-25 20:11:45161 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]2fc3b422010-09-28 20:59:56162 // Try to send the packet if there is a pending write.
[email protected]83039bb2011-12-09 18:43:55163 if (!write_callback_.is_null()) {
[email protected]e758d4c2014-08-06 16:48:16164 rtc::PacketOptions options;
Joe Downing353ba2c72023-01-11 22:37:34165 int result = channel_->SendPacket(write_buffer_->data(), write_buffer_size_,
[email protected]e6b239a2014-02-15 06:09:52166 options);
Joe Downing353ba2c72023-01-11 22:37:34167 if (result < 0) {
[email protected]f6da0b252011-03-31 00:26:03168 result = net::MapSystemError(channel_->GetError());
Joe Downing353ba2c72023-01-11 22:37:34169 }
[email protected]2fc3b422010-09-28 20:59:56170
171 if (result != net::ERR_IO_PENDING) {
Mario Sanchez Prada670d2822019-03-18 21:52:41172 net::CompletionRepeatingCallback callback = write_callback_;
[email protected]83039bb2011-12-09 18:43:55173 write_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09174 write_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55175 callback.Run(result);
[email protected]2fc3b422010-09-28 20:59:56176 }
177 }
178}
179
180void TransportChannelSocketAdapter::OnChannelDestroyed(
zhihuang1aa292f32017-01-03 19:37:51181 cricket::IceTransportInternal* channel) {
Joe Downing39d710e2022-08-25 20:11:45182 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]2fc3b422010-09-28 20:59:56183 DCHECK_EQ(channel, channel_);
184 Close(net::ERR_CONNECTION_ABORTED);
185}
186
Joe Downing39d710e2022-08-25 20:11:45187} // namespace remoting::protocol