blob: 5922be705f2b0bb7b4bb2c16cc42dfccd7ceadd3 [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(
42 const scoped_refptr<net::IOBuffer>& buf, int buffer_size,
[email protected]3f55aa12011-12-07 02:03:3343 const net::CompletionCallback& callback) {
sergeyu031ce3b32015-07-06 19:00:4644 DCHECK(thread_checker_.CalledOnValidThread());
[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(
62 const scoped_refptr<net::IOBuffer>& buffer, int buffer_size,
[email protected]83039bb2011-12-09 18:43:5563 const net::CompletionCallback& callback) {
sergeyu031ce3b32015-07-06 19:00:4664 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]2fc3b422010-09-28 20:59:5665 DCHECK(buffer);
[email protected]83039bb2011-12-09 18:43:5566 DCHECK(!callback.is_null());
67 CHECK(write_callback_.is_null());
[email protected]2fc3b422010-09-28 20:59:5668
69 if (!channel_) {
70 DCHECK(closed_error_code_ != net::OK);
71 return closed_error_code_;
72 }
73
[email protected]4d83fbc2011-04-22 19:35:4974 int result;
[email protected]e758d4c2014-08-06 16:48:1675 rtc::PacketOptions options;
[email protected]4d83fbc2011-04-22 19:35:4976 if (channel_->writable()) {
[email protected]e6b239a2014-02-15 06:09:5277 result = channel_->SendPacket(buffer->data(), buffer_size, options);
[email protected]87185ec2011-07-27 13:25:4078 if (result < 0) {
[email protected]4d83fbc2011-04-22 19:35:4979 result = net::MapSystemError(channel_->GetError());
[email protected]87185ec2011-07-27 13:25:4080
81 // If the underlying socket returns IO pending where it shouldn't we
82 // pretend the packet is dropped and return as succeeded because no
83 // writeable callback will happen.
84 if (result == net::ERR_IO_PENDING)
85 result = net::OK;
86 }
[email protected]4d83fbc2011-04-22 19:35:4987 } else {
88 // Channel is not writable yet.
89 result = net::ERR_IO_PENDING;
[email protected]4d83fbc2011-04-22 19:35:4990 write_callback_ = callback;
91 write_buffer_ = buffer;
92 write_buffer_size_ = buffer_size;
93 }
94
[email protected]2fc3b422010-09-28 20:59:5695 return result;
96}
97
[email protected]2fc3b422010-09-28 20:59:5698void TransportChannelSocketAdapter::Close(int error_code) {
sergeyu031ce3b32015-07-06 19:00:4699 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]2fc3b422010-09-28 20:59:56100
101 if (!channel_) // Already closed.
102 return;
103
104 DCHECK(error_code != net::OK);
105 closed_error_code_ = error_code;
106 channel_->SignalReadPacket.disconnect(this);
107 channel_->SignalDestroyed.disconnect(this);
108 channel_ = NULL;
109
[email protected]83039bb2011-12-09 18:43:55110 if (!read_callback_.is_null()) {
[email protected]3f55aa12011-12-07 02:03:33111 net::CompletionCallback callback = read_callback_;
112 read_callback_.Reset();
113 read_buffer_ = NULL;
114 callback.Run(error_code);
[email protected]2fc3b422010-09-28 20:59:56115 }
116
[email protected]83039bb2011-12-09 18:43:55117 if (!write_callback_.is_null()) {
118 net::CompletionCallback callback = write_callback_;
119 write_callback_.Reset();
[email protected]2fc3b422010-09-28 20:59:56120 write_buffer_ = NULL;
[email protected]83039bb2011-12-09 18:43:55121 callback.Run(error_code);
[email protected]2fc3b422010-09-28 20:59:56122 }
123}
124
125void TransportChannelSocketAdapter::OnNewPacket(
sprangd72236c2016-10-21 08:36:04126 rtc::PacketTransportInterface* transport,
[email protected]8bb746372012-04-26 04:20:12127 const char* data,
128 size_t data_size,
Niels Möller6c41fbf52018-12-20 10:22:56129 const int64_t& packet_time,
[email protected]8bb746372012-04-26 04:20:12130 int flags) {
sergeyu031ce3b32015-07-06 19:00:46131 DCHECK(thread_checker_.CalledOnValidThread());
sprangd72236c2016-10-21 08:36:04132 DCHECK_EQ(transport, channel_);
[email protected]83039bb2011-12-09 18:43:55133 if (!read_callback_.is_null()) {
[email protected]f9d8a772013-06-01 04:33:17134 DCHECK(read_buffer_.get());
[email protected]2fc3b422010-09-28 20:59:56135 CHECK_LT(data_size, static_cast<size_t>(std::numeric_limits<int>::max()));
136
137 if (read_buffer_size_ < static_cast<int>(data_size)) {
138 LOG(WARNING) << "Data buffer is smaller than the received packet. "
139 << "Dropping the data that doesn't fit.";
140 data_size = read_buffer_size_;
141 }
142
143 memcpy(read_buffer_->data(), data, data_size);
144
[email protected]83039bb2011-12-09 18:43:55145 net::CompletionCallback callback = read_callback_;
146 read_callback_.Reset();
147 read_buffer_ = NULL;
148
149 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(
sprangd72236c2016-10-21 08:36:04157 rtc::PacketTransportInterface* transport) {
sergeyu031ce3b32015-07-06 19:00:46158 DCHECK(thread_checker_.CalledOnValidThread());
[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) {
[email protected]83039bb2011-12-09 18:43:55169 net::CompletionCallback callback = write_callback_;
170 write_callback_.Reset();
[email protected]f749f9c2011-12-09 01:06:19171 write_buffer_ = NULL;
[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) {
sergeyu031ce3b32015-07-06 19:00:46179 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]2fc3b422010-09-28 20:59:56180 DCHECK_EQ(channel, channel_);
181 Close(net::ERR_CONNECTION_ABORTED);
182}
183
sergeyu031ce3b32015-07-06 19:00:46184} // namespace protocol
185} // namespace remoting