| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/client/plugin/pepper_packet_socket_factory.h" | 5 #include "remoting/client/plugin/pepper_packet_socket_factory.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/weak_ptr.h" |
| 9 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
| 10 #include "ppapi/cpp/private/net_address_private.h" | 11 #include "ppapi/cpp/private/net_address_private.h" |
| 11 #include "ppapi/cpp/private/udp_socket_private.h" | 12 #include "ppapi/cpp/private/udp_socket_private.h" |
| 12 #include "remoting/client/plugin/pepper_util.h" | 13 #include "remoting/client/plugin/pepper_util.h" |
| 13 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" | 14 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" |
| 14 | 15 |
| 15 namespace remoting { | 16 namespace remoting { |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 // Size of the buffer to allocate for RecvFrom(). | 20 // Size of the buffer to allocate for RecvFrom(). |
| 20 const int kReceiveBufferSize = 65536; | 21 const int kReceiveBufferSize = 65536; |
| 21 | 22 |
| 22 // Maximum amount of data in the send buffers. This is necessary to | 23 // Maximum amount of data in the send buffers. This is necessary to |
| 23 // prevent out-of-memory crashes if the caller sends data faster than | 24 // prevent out-of-memory crashes if the caller sends data faster than |
| 24 // Pepper's UDP API can handle it. This maximum should never be | 25 // Pepper's UDP API can handle it. This maximum should never be |
| 25 // reached under normal conditions. | 26 // reached under normal conditions. |
| 26 const int kMaxSendBufferSize = 256 * 1024; | 27 const int kMaxSendBufferSize = 256 * 1024; |
| 27 | 28 |
| 28 class UdpPacketSocket : public talk_base::AsyncPacketSocket { | 29 class UdpPacketSocket : public talk_base::AsyncPacketSocket { |
| 29 public: | 30 public: |
| 30 explicit UdpPacketSocket(const pp::InstanceHandle& instance); | 31 explicit UdpPacketSocket(const pp::InstanceHandle& instance); |
| 31 virtual ~UdpPacketSocket(); | 32 virtual ~UdpPacketSocket(); |
| 32 | 33 |
| 33 // |min_port| and |max_port| are set to zero if the port number | 34 // |min_port| and |max_port| are set to zero if the port number |
| 34 // |should be assigned by the OS. | 35 // should be assigned by the OS. |
| 35 bool Init(const talk_base::SocketAddress& local_address, | 36 bool Init(const talk_base::SocketAddress& local_address, |
| 36 int min_port, | 37 int min_port, |
| 37 int max_port); | 38 int max_port); |
| 38 | 39 |
| 39 // talk_base::AsyncPacketSocket interface. | 40 // talk_base::AsyncPacketSocket interface. |
| 40 virtual talk_base::SocketAddress GetLocalAddress() const; | 41 virtual talk_base::SocketAddress GetLocalAddress() const; |
| 41 virtual talk_base::SocketAddress GetRemoteAddress() const; | 42 virtual talk_base::SocketAddress GetRemoteAddress() const; |
| 42 virtual int Send(const void* data, size_t data_size); | 43 virtual int Send(const void* data, size_t data_size); |
| 43 virtual int SendTo(const void* data, | 44 virtual int SendTo(const void* data, |
| 44 size_t data_size, | 45 size_t data_size, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 // the port number is assigned by OS. | 81 // the port number is assigned by OS. |
| 81 uint16_t min_port_; | 82 uint16_t min_port_; |
| 82 uint16_t max_port_; | 83 uint16_t max_port_; |
| 83 | 84 |
| 84 std::vector<char> receive_buffer_; | 85 std::vector<char> receive_buffer_; |
| 85 | 86 |
| 86 bool send_pending_; | 87 bool send_pending_; |
| 87 std::list<PendingPacket> send_queue_; | 88 std::list<PendingPacket> send_queue_; |
| 88 int send_queue_size_; | 89 int send_queue_size_; |
| 89 | 90 |
| 91 base::WeakPtrFactory<UdpPacketSocket> weak_factory_; |
| 92 |
| 90 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); | 93 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); |
| 91 }; | 94 }; |
| 92 | 95 |
| 93 UdpPacketSocket::PendingPacket::PendingPacket( | 96 UdpPacketSocket::PendingPacket::PendingPacket( |
| 94 const void* buffer, | 97 const void* buffer, |
| 95 int buffer_size, | 98 int buffer_size, |
| 96 const PP_NetAddress_Private& address) | 99 const PP_NetAddress_Private& address) |
| 97 : data(new net::IOBufferWithSize(buffer_size)), | 100 : data(new net::IOBufferWithSize(buffer_size)), |
| 98 address(address) { | 101 address(address) { |
| 99 memcpy(data->data(), buffer, buffer_size); | 102 memcpy(data->data(), buffer, buffer_size); |
| 100 } | 103 } |
| 101 | 104 |
| 102 UdpPacketSocket::UdpPacketSocket(const pp::InstanceHandle& instance) | 105 UdpPacketSocket::UdpPacketSocket(const pp::InstanceHandle& instance) |
| 103 : socket_(instance), | 106 : socket_(instance), |
| 104 state_(STATE_CLOSED), | 107 state_(STATE_CLOSED), |
| 105 error_(0), | 108 error_(0), |
| 106 min_port_(0), | 109 min_port_(0), |
| 107 max_port_(0), | 110 max_port_(0), |
| 108 send_pending_(false), | 111 send_pending_(false), |
| 109 send_queue_size_(0) { | 112 send_queue_size_(0), |
| 113 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 110 } | 114 } |
| 111 | 115 |
| 112 UdpPacketSocket::~UdpPacketSocket() { | 116 UdpPacketSocket::~UdpPacketSocket() { |
| 113 Close(); | 117 Close(); |
| 114 } | 118 } |
| 115 | 119 |
| 116 bool UdpPacketSocket::Init(const talk_base::SocketAddress& local_address, | 120 bool UdpPacketSocket::Init(const talk_base::SocketAddress& local_address, |
| 117 int min_port, | 121 int min_port, |
| 118 int max_port) { | 122 int max_port) { |
| 119 if (socket_.is_null()) { | 123 if (socket_.is_null()) { |
| 120 return false; | 124 return false; |
| 121 } | 125 } |
| 122 | 126 |
| 123 local_address_ = local_address; | 127 local_address_ = local_address; |
| 124 max_port_ = max_port; | 128 max_port_ = max_port; |
| 125 min_port_ = min_port; | 129 min_port_ = min_port; |
| 126 | 130 |
| 127 PP_NetAddress_Private pp_local_address; | 131 PP_NetAddress_Private pp_local_address; |
| 128 if (!SocketAddressToPpAddressWithPort(local_address_, &pp_local_address, | 132 if (!SocketAddressToPpAddressWithPort(local_address_, &pp_local_address, |
| 129 min_port_)) { | 133 min_port_)) { |
| 130 return false; | 134 return false; |
| 131 } | 135 } |
| 132 | 136 |
| 133 int result = socket_.Bind(&pp_local_address, PpCompletionCallback( | 137 int result = socket_.Bind(&pp_local_address, PpCompletionCallback( |
| 134 base::Bind(&UdpPacketSocket::OnBindCompleted, base::Unretained(this)))); | 138 base::Bind(&UdpPacketSocket::OnBindCompleted, |
| 139 weak_factory_.GetWeakPtr()))); |
| 135 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); | 140 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); |
| 136 state_ = STATE_BINDING; | 141 state_ = STATE_BINDING; |
| 137 | 142 |
| 138 return true; | 143 return true; |
| 139 } | 144 } |
| 140 | 145 |
| 141 void UdpPacketSocket::OnBindCompleted(int result) { | 146 void UdpPacketSocket::OnBindCompleted(int result) { |
| 142 DCHECK(state_ == STATE_BINDING || state_ == STATE_CLOSED); | 147 DCHECK(state_ == STATE_BINDING || state_ == STATE_CLOSED); |
| 143 | 148 |
| 144 if (result == PP_ERROR_ABORTED) { | 149 if (result == PP_ERROR_ABORTED) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 162 } | 167 } |
| 163 | 168 |
| 164 if (min_port_ < max_port_) { | 169 if (min_port_ < max_port_) { |
| 165 // Try to bind to the next available port. | 170 // Try to bind to the next available port. |
| 166 ++min_port_; | 171 ++min_port_; |
| 167 PP_NetAddress_Private pp_local_address; | 172 PP_NetAddress_Private pp_local_address; |
| 168 if (SocketAddressToPpAddressWithPort(local_address_, &pp_local_address, | 173 if (SocketAddressToPpAddressWithPort(local_address_, &pp_local_address, |
| 169 min_port_)) { | 174 min_port_)) { |
| 170 int result = socket_.Bind(&pp_local_address, PpCompletionCallback( | 175 int result = socket_.Bind(&pp_local_address, PpCompletionCallback( |
| 171 base::Bind(&UdpPacketSocket::OnBindCompleted, | 176 base::Bind(&UdpPacketSocket::OnBindCompleted, |
| 172 base::Unretained(this)))); | 177 weak_factory_.GetWeakPtr()))); |
| 173 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); | 178 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); |
| 174 } | 179 } |
| 175 } else { | 180 } else { |
| 176 LOG(ERROR) << "Failed to bind UDP socket: " << result; | 181 LOG(ERROR) << "Failed to bind UDP socket: " << result; |
| 177 } | 182 } |
| 178 } | 183 } |
| 179 | 184 |
| 180 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const { | 185 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const { |
| 181 DCHECK_EQ(state_, STATE_BOUND); | 186 DCHECK_EQ(state_, STATE_BOUND); |
| 182 return local_address_; | 187 return local_address_; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 } | 256 } |
| 252 | 257 |
| 253 void UdpPacketSocket::DoSend() { | 258 void UdpPacketSocket::DoSend() { |
| 254 if (send_pending_ || send_queue_.empty()) | 259 if (send_pending_ || send_queue_.empty()) |
| 255 return; | 260 return; |
| 256 | 261 |
| 257 int result = socket_.SendTo( | 262 int result = socket_.SendTo( |
| 258 send_queue_.front().data->data(), send_queue_.front().data->size(), | 263 send_queue_.front().data->data(), send_queue_.front().data->size(), |
| 259 &send_queue_.front().address, | 264 &send_queue_.front().address, |
| 260 PpCompletionCallback(base::Bind(&UdpPacketSocket::OnSendCompleted, | 265 PpCompletionCallback(base::Bind(&UdpPacketSocket::OnSendCompleted, |
| 261 base::Unretained(this)))); | 266 weak_factory_.GetWeakPtr()))); |
| 262 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); | 267 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); |
| 263 send_pending_ = true; | 268 send_pending_ = true; |
| 264 } | 269 } |
| 265 | 270 |
| 266 void UdpPacketSocket::OnSendCompleted(int result) { | 271 void UdpPacketSocket::OnSendCompleted(int result) { |
| 267 if (result == PP_ERROR_ABORTED) { | 272 if (result == PP_ERROR_ABORTED) { |
| 268 // Send is aborted when the socket is being destroyed. | 273 // Send is aborted when the socket is being destroyed. |
| 269 // |send_queue_| may be already destroyed, it's not safe to access | 274 // |send_queue_| may be already destroyed, it's not safe to access |
| 270 // it here. | 275 // it here. |
| 271 return; | 276 return; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 298 send_queue_size_ -= send_queue_.front().data->size(); | 303 send_queue_size_ -= send_queue_.front().data->size(); |
| 299 send_queue_.pop_front(); | 304 send_queue_.pop_front(); |
| 300 DoSend(); | 305 DoSend(); |
| 301 } | 306 } |
| 302 | 307 |
| 303 void UdpPacketSocket::DoRead() { | 308 void UdpPacketSocket::DoRead() { |
| 304 receive_buffer_.resize(kReceiveBufferSize); | 309 receive_buffer_.resize(kReceiveBufferSize); |
| 305 int result = socket_.RecvFrom( | 310 int result = socket_.RecvFrom( |
| 306 &receive_buffer_[0], receive_buffer_.size(), | 311 &receive_buffer_[0], receive_buffer_.size(), |
| 307 PpCompletionCallback(base::Bind(&UdpPacketSocket::OnReadCompleted, | 312 PpCompletionCallback(base::Bind(&UdpPacketSocket::OnReadCompleted, |
| 308 base::Unretained(this)))); | 313 weak_factory_.GetWeakPtr()))); |
| 309 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); | 314 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); |
| 310 } | 315 } |
| 311 | 316 |
| 312 void UdpPacketSocket::OnReadCompleted(int result) { | 317 void UdpPacketSocket::OnReadCompleted(int result) { |
| 313 HandleReadResult(result); | 318 HandleReadResult(result); |
| 314 if (result > 0) { | 319 if (result > 0) { |
| 315 DoRead(); | 320 DoRead(); |
| 316 } | 321 } |
| 317 } | 322 } |
| 318 | 323 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 const talk_base::SocketAddress& remote_address, | 374 const talk_base::SocketAddress& remote_address, |
| 370 const talk_base::ProxyInfo& proxy_info, | 375 const talk_base::ProxyInfo& proxy_info, |
| 371 const std::string& user_agent, | 376 const std::string& user_agent, |
| 372 bool ssl) { | 377 bool ssl) { |
| 373 // We don't use TCP sockets for remoting connections. | 378 // We don't use TCP sockets for remoting connections. |
| 374 NOTREACHED(); | 379 NOTREACHED(); |
| 375 return NULL; | 380 return NULL; |
| 376 } | 381 } |
| 377 | 382 |
| 378 } // namespace remoting | 383 } // namespace remoting |
| OLD | NEW |