blob: 03811a4c93520ab9bdfebe7c2856ba7e9d747b1e [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
sergeyu031ce3b32015-07-06 19:00:4614namespace remoting {
15namespace protocol {
[email protected]2fc3b422010-09-28 20:59:5616
17TransportChannelSocketAdapter::TransportChannelSocketAdapter(
zhihuang1aa292f32017-01-03 19:37:5118 cricket::IceTransportInternal* ice_transport)
19 : channel_(ice_transport), closed_error_code_(net::OK) {
[email protected]2fc3b422010-09-28 20:59:5620 DCHECK(channel_);
21
22 channel_->SignalReadPacket.connect(
23 this, &TransportChannelSocketAdapter::OnNewPacket);
24 channel_->SignalWritableState.connect(
25 this, &TransportChannelSocketAdapter::OnWritableState);
26 channel_->SignalDestroyed.connect(
27 this, &TransportChannelSocketAdapter::OnChannelDestroyed);
28}
29
30TransportChannelSocketAdapter::~TransportChannelSocketAdapter() {
joedow18837eb2017-05-17 18:28:2431 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]ad48b7f2012-02-21 21:20:0232 if (!destruction_callback_.is_null())
33 destruction_callback_.Run();
34}
35
36void TransportChannelSocketAdapter::SetOnDestroyedCallback(
37 const base::Closure& callback) {
38 destruction_callback_ = 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) {
sergeyu031ce3b32015-07-06 19:00:4645 DCHECK(thread_checker_.CalledOnValidThread());
[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) {
sergeyu031ce3b32015-07-06 19:00:4666 DCHECK(thread_checker_.CalledOnValidThread());
[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.
86 if (result == net::ERR_IO_PENDING)
87 result = net::OK;
88 }
[email protected]4d83fbc2011-04-22 19:35:4989 } else {
90 // Channel is not writable yet.
91 result = net::ERR_IO_PENDING;
[email protected]4d83fbc2011-04-22 19:35:4992 write_callback_ = callback;
93 write_buffer_ = buffer;
94 write_buffer_size_ = buffer_size;
95 }
96
[email protected]2fc3b422010-09-28 20:59:5697 return result;
98}
99
[email protected]2fc3b422010-09-28 20:59:56100void TransportChannelSocketAdapter::Close(int error_code) {
sergeyu031ce3b32015-07-06 19:00:46101 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]2fc3b422010-09-28 20:59:56102
103 if (!channel_) // Already closed.
104 return;
105
106 DCHECK(error_code != net::OK);
107 closed_error_code_ = error_code;
108 channel_->SignalReadPacket.disconnect(this);
109 channel_->SignalDestroyed.disconnect(this);
110 channel_ = NULL;
111
[email protected]83039bb2011-12-09 18:43:55112 if (!read_callback_.is_null()) {
Mario Sanchez Prada670d2822019-03-18 21:52:41113 net::CompletionRepeatingCallback callback = read_callback_;
[email protected]3f55aa12011-12-07 02:03:33114 read_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09115 read_buffer_.reset();
[email protected]3f55aa12011-12-07 02:03:33116 callback.Run(error_code);
[email protected]2fc3b422010-09-28 20:59:56117 }
118
[email protected]83039bb2011-12-09 18:43:55119 if (!write_callback_.is_null()) {
Mario Sanchez Prada670d2822019-03-18 21:52:41120 net::CompletionRepeatingCallback callback = write_callback_;
[email protected]83039bb2011-12-09 18:43:55121 write_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09122 write_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55123 callback.Run(error_code);
[email protected]2fc3b422010-09-28 20:59:56124 }
125}
126
127void TransportChannelSocketAdapter::OnNewPacket(
Niels Möllere5cdbff02019-12-18 12:29:45128 rtc::PacketTransportInternal* transport,
[email protected]8bb746372012-04-26 04:20:12129 const char* data,
130 size_t data_size,
Niels Möller6c41fbf52018-12-20 10:22:56131 const int64_t& packet_time,
[email protected]8bb746372012-04-26 04:20:12132 int flags) {
sergeyu031ce3b32015-07-06 19:00:46133 DCHECK(thread_checker_.CalledOnValidThread());
sprangd72236c2016-10-21 08:36:04134 DCHECK_EQ(transport, channel_);
[email protected]83039bb2011-12-09 18:43:55135 if (!read_callback_.is_null()) {
[email protected]f9d8a772013-06-01 04:33:17136 DCHECK(read_buffer_.get());
[email protected]2fc3b422010-09-28 20:59:56137 CHECK_LT(data_size, static_cast<size_t>(std::numeric_limits<int>::max()));
138
139 if (read_buffer_size_ < static_cast<int>(data_size)) {
140 LOG(WARNING) << "Data buffer is smaller than the received packet. "
141 << "Dropping the data that doesn't fit.";
142 data_size = read_buffer_size_;
143 }
144
145 memcpy(read_buffer_->data(), data, data_size);
146
Mario Sanchez Prada670d2822019-03-18 21:52:41147 net::CompletionRepeatingCallback callback = read_callback_;
[email protected]83039bb2011-12-09 18:43:55148 read_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09149 read_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55150 callback.Run(data_size);
[email protected]2fc3b422010-09-28 20:59:56151 } else {
152 LOG(WARNING)
153 << "Data was received without a callback. Dropping the packet.";
154 }
155}
156
157void TransportChannelSocketAdapter::OnWritableState(
Niels Möllere5cdbff02019-12-18 12:29:45158 rtc::PacketTransportInternal* transport) {
sergeyu031ce3b32015-07-06 19:00:46159 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]2fc3b422010-09-28 20:59:56160 // Try to send the packet if there is a pending write.
[email protected]83039bb2011-12-09 18:43:55161 if (!write_callback_.is_null()) {
[email protected]e758d4c2014-08-06 16:48:16162 rtc::PacketOptions options;
[email protected]2fc3b422010-09-28 20:59:56163 int result = channel_->SendPacket(write_buffer_->data(),
[email protected]7791cf42013-09-23 23:11:57164 write_buffer_size_,
[email protected]e6b239a2014-02-15 06:09:52165 options);
[email protected]2fc3b422010-09-28 20:59:56166 if (result < 0)
[email protected]f6da0b252011-03-31 00:26:03167 result = net::MapSystemError(channel_->GetError());
[email protected]2fc3b422010-09-28 20:59:56168
169 if (result != net::ERR_IO_PENDING) {
Mario Sanchez Prada670d2822019-03-18 21:52:41170 net::CompletionRepeatingCallback callback = write_callback_;
[email protected]83039bb2011-12-09 18:43:55171 write_callback_.Reset();
kylechar80b4c9f2019-11-14 23:07:09172 write_buffer_.reset();
[email protected]83039bb2011-12-09 18:43:55173 callback.Run(result);
[email protected]2fc3b422010-09-28 20:59:56174 }
175 }
176}
177
178void TransportChannelSocketAdapter::OnChannelDestroyed(
zhihuang1aa292f32017-01-03 19:37:51179 cricket::IceTransportInternal* channel) {
sergeyu031ce3b32015-07-06 19:00:46180 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]2fc3b422010-09-28 20:59:56181 DCHECK_EQ(channel, channel_);
182 Close(net::ERR_CONNECTION_ABORTED);
183}
184
sergeyu031ce3b32015-07-06 19:00:46185} // namespace protocol
186} // namespace remoting