blob: ac31f443258e6a9b96dd851c4a736638571d40f0 [file] [log] [blame]
sergeyu031ce3b32015-07-06 19:00:461// Copyright 2015 The Chromium Authors. All rights reserved.
[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_);
Evan Stade86dadf152020-03-16 20:06:3331 if (destruction_callback_)
32 std::move(destruction_callback_).Run();
[email protected]ad48b7f2012-02-21 21:20:0233}
34
35void TransportChannelSocketAdapter::SetOnDestroyedCallback(
Evan Stade86dadf152020-03-16 20:06:3336 base::OnceClosure callback) {
37 destruction_callback_ = std::move(callback);
[email protected]2fc3b422010-09-28 20:59:5638}
39
sergeyuaa22c082015-07-20 19:41:1340int TransportChannelSocketAdapter::Recv(
Mario Sanchez Prada670d2822019-03-18 21:52:4141 const scoped_refptr<net::IOBuffer>& buf,
42 int buffer_size,
43 const net::CompletionRepeatingCallback& callback) {
Joe Downing39d710e2022-08-25 20:11:4544 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]3f55aa12011-12-07 02:03:3345 DCHECK(buf);
46 DCHECK(!callback.is_null());
[email protected]83039bb2011-12-09 18:43:5547 CHECK(read_callback_.is_null());
[email protected]2fc3b422010-09-28 20:59:5648
49 if (!channel_) {
50 DCHECK(closed_error_code_ != net::OK);
51 return closed_error_code_;
52 }
53
54 read_callback_ = callback;
55 read_buffer_ = buf;
56 read_buffer_size_ = buffer_size;
[email protected]2fc3b422010-09-28 20:59:5657
58 return net::ERR_IO_PENDING;
59}
60
sergeyuaa22c082015-07-20 19:41:1361int TransportChannelSocketAdapter::Send(
Mario Sanchez Prada670d2822019-03-18 21:52:4162 const scoped_refptr<net::IOBuffer>& buffer,
63 int buffer_size,
64 const net::CompletionRepeatingCallback& callback) {
Joe Downing39d710e2022-08-25 20:11:4565 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]2fc3b422010-09-28 20:59:5666 DCHECK(buffer);
[email protected]83039bb2011-12-09 18:43:5567 DCHECK(!callback.is_null());
68 CHECK(write_callback_.is_null());
[email protected]2fc3b422010-09-28 20:59:5669
70 if (!channel_) {
71 DCHECK(closed_error_code_ != net::OK);
72 return closed_error_code_;
73 }
74
[email protected]4d83fbc2011-04-22 19:35:4975 int result;
[email protected]e758d4c2014-08-06 16:48:1676 rtc::PacketOptions options;
[email protected]4d83fbc2011-04-22 19:35:4977 if (channel_->writable()) {
[email protected]e6b239a2014-02-15 06:09:5278 result = channel_->SendPacket(buffer->data(), buffer_size, options);
[email protected]87185ec2011-07-27 13:25:4079 if (result < 0) {
[email protected]4d83fbc2011-04-22 19:35:4980 result = net::MapSystemError(channel_->GetError());
[email protected]87185ec2011-07-27 13:25:4081
82 // If the underlying socket returns IO pending where it shouldn't we
83 // pretend the packet is dropped and return as succeeded because no
84 // writeable callback will happen.
85 if (result == net::ERR_IO_PENDING)
86 result = net::OK;
87 }
[email protected]4d83fbc2011-04-22 19:35:4988 } else {
89 // Channel is not writable yet.
90 result = net::ERR_IO_PENDING;
[email protected]4d83fbc2011-04-22 19:35:4991 write_callback_ = callback;
92 write_buffer_ = buffer;
93 write_buffer_size_ = buffer_size;
94 }
95
[email protected]2fc3b422010-09-28 20:59:5696 return result;
97}
98
[email protected]2fc3b422010-09-28 20:59:5699void TransportChannelSocketAdapter::Close(int error_code) {
Joe Downing39d710e2022-08-25 20:11:45100 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]2fc3b422010-09-28 20:59:56101
102 if (!channel_) // Already closed.
103 return;
104
105 DCHECK(error_code != net::OK);
106 closed_error_code_ = error_code;
107 channel_->SignalReadPacket.disconnect(this);
108 channel_->SignalDestroyed.disconnect(this);
Bartek Nowierskidf0fc8a2020-06-11 01:01:31109 channel_ = nullptr;
[email protected]2fc3b422010-09-28 20:59:56110
[email protected]83039bb2011-12-09 18:43:55111 if (!read_callback_.is_null()) {
Mario Sanchez Prada670d2822019-03-18 21:52:41112 net::CompletionRepeatingCallback callback = read_callback_;
[email protected]3f55aa12011-12-07 02:03:33113 read_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09114 read_buffer_.reset();
[email protected]3f55aa12011-12-07 02:03:33115 callback.Run(error_code);
[email protected]2fc3b422010-09-28 20:59:56116 }
117
[email protected]83039bb2011-12-09 18:43:55118 if (!write_callback_.is_null()) {
Mario Sanchez Prada670d2822019-03-18 21:52:41119 net::CompletionRepeatingCallback callback = write_callback_;
[email protected]83039bb2011-12-09 18:43:55120 write_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09121 write_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55122 callback.Run(error_code);
[email protected]2fc3b422010-09-28 20:59:56123 }
124}
125
126void TransportChannelSocketAdapter::OnNewPacket(
Niels Möllere5cdbff02019-12-18 12:29:45127 rtc::PacketTransportInternal* transport,
[email protected]8bb746372012-04-26 04:20:12128 const char* data,
129 size_t data_size,
Niels Möller6c41fbf52018-12-20 10:22:56130 const int64_t& packet_time,
[email protected]8bb746372012-04-26 04:20:12131 int flags) {
Joe Downing39d710e2022-08-25 20:11:45132 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
sprangd72236c2016-10-21 08:36:04133 DCHECK_EQ(transport, channel_);
[email protected]83039bb2011-12-09 18:43:55134 if (!read_callback_.is_null()) {
[email protected]f9d8a772013-06-01 04:33:17135 DCHECK(read_buffer_.get());
[email protected]2fc3b422010-09-28 20:59:56136 CHECK_LT(data_size, static_cast<size_t>(std::numeric_limits<int>::max()));
137
138 if (read_buffer_size_ < static_cast<int>(data_size)) {
139 LOG(WARNING) << "Data buffer is smaller than the received packet. "
140 << "Dropping the data that doesn't fit.";
141 data_size = read_buffer_size_;
142 }
143
144 memcpy(read_buffer_->data(), data, data_size);
145
Mario Sanchez Prada670d2822019-03-18 21:52:41146 net::CompletionRepeatingCallback callback = read_callback_;
[email protected]83039bb2011-12-09 18:43:55147 read_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09148 read_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55149 callback.Run(data_size);
[email protected]2fc3b422010-09-28 20:59:56150 } else {
151 LOG(WARNING)
152 << "Data was received without a callback. Dropping the packet.";
153 }
154}
155
156void TransportChannelSocketAdapter::OnWritableState(
Niels Möllere5cdbff02019-12-18 12:29:45157 rtc::PacketTransportInternal* transport) {
Joe Downing39d710e2022-08-25 20:11:45158 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]2fc3b422010-09-28 20:59:56159 // Try to send the packet if there is a pending write.
[email protected]83039bb2011-12-09 18:43:55160 if (!write_callback_.is_null()) {
[email protected]e758d4c2014-08-06 16:48:16161 rtc::PacketOptions options;
[email protected]2fc3b422010-09-28 20:59:56162 int result = channel_->SendPacket(write_buffer_->data(),
[email protected]7791cf42013-09-23 23:11:57163 write_buffer_size_,
[email protected]e6b239a2014-02-15 06:09:52164 options);
[email protected]2fc3b422010-09-28 20:59:56165 if (result < 0)
[email protected]f6da0b252011-03-31 00:26:03166 result = net::MapSystemError(channel_->GetError());
[email protected]2fc3b422010-09-28 20:59:56167
168 if (result != net::ERR_IO_PENDING) {
Mario Sanchez Prada670d2822019-03-18 21:52:41169 net::CompletionRepeatingCallback callback = write_callback_;
[email protected]83039bb2011-12-09 18:43:55170 write_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09171 write_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55172 callback.Run(result);
[email protected]2fc3b422010-09-28 20:59:56173 }
174 }
175}
176
177void TransportChannelSocketAdapter::OnChannelDestroyed(
zhihuang1aa292f32017-01-03 19:37:51178 cricket::IceTransportInternal* channel) {
Joe Downing39d710e2022-08-25 20:11:45179 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
[email protected]2fc3b422010-09-28 20:59:56180 DCHECK_EQ(channel, channel_);
181 Close(net::ERR_CONNECTION_ABORTED);
182}
183
Joe Downing39d710e2022-08-25 20:11:45184} // namespace remoting::protocol