| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/protocol/chromium_socket_factory.h" | 5 #include "remoting/protocol/chromium_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/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "jingle/glue/utils.h" | 10 #include "jingle/glue/utils.h" |
| 11 #include "net/base/io_buffer.h" | 11 #include "net/base/io_buffer.h" |
| 12 #include "net/base/ip_endpoint.h" | 12 #include "net/base/ip_endpoint.h" |
| 13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 14 #include "net/udp/udp_server_socket.h" | 14 #include "net/udp/udp_server_socket.h" |
| 15 #include "remoting/protocol/socket_util.h" | 15 #include "remoting/protocol/socket_util.h" |
| 16 #include "third_party/webrtc/base/asyncpacketsocket.h" | 16 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" |
| 17 #include "third_party/webrtc/base/nethelpers.h" | 17 #include "third_party/libjingle/source/talk/base/nethelpers.h" |
| 18 | 18 |
| 19 namespace remoting { | 19 namespace remoting { |
| 20 namespace protocol { | 20 namespace protocol { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 // Size of the buffer to allocate for RecvFrom(). | 24 // Size of the buffer to allocate for RecvFrom(). |
| 25 const int kReceiveBufferSize = 65536; | 25 const int kReceiveBufferSize = 65536; |
| 26 | 26 |
| 27 // Maximum amount of data in the send buffers. This is necessary to | 27 // Maximum amount of data in the send buffers. This is necessary to |
| 28 // prevent out-of-memory crashes if the caller sends data faster than | 28 // prevent out-of-memory crashes if the caller sends data faster than |
| 29 // Pepper's UDP API can handle it. This maximum should never be | 29 // Pepper's UDP API can handle it. This maximum should never be |
| 30 // reached under normal conditions. | 30 // reached under normal conditions. |
| 31 const int kMaxSendBufferSize = 256 * 1024; | 31 const int kMaxSendBufferSize = 256 * 1024; |
| 32 | 32 |
| 33 class UdpPacketSocket : public rtc::AsyncPacketSocket { | 33 class UdpPacketSocket : public talk_base::AsyncPacketSocket { |
| 34 public: | 34 public: |
| 35 UdpPacketSocket(); | 35 UdpPacketSocket(); |
| 36 virtual ~UdpPacketSocket(); | 36 virtual ~UdpPacketSocket(); |
| 37 | 37 |
| 38 bool Init(const rtc::SocketAddress& local_address, | 38 bool Init(const talk_base::SocketAddress& local_address, |
| 39 int min_port, int max_port); | 39 int min_port, int max_port); |
| 40 | 40 |
| 41 // rtc::AsyncPacketSocket interface. | 41 // talk_base::AsyncPacketSocket interface. |
| 42 virtual rtc::SocketAddress GetLocalAddress() const OVERRIDE; | 42 virtual talk_base::SocketAddress GetLocalAddress() const OVERRIDE; |
| 43 virtual rtc::SocketAddress GetRemoteAddress() const OVERRIDE; | 43 virtual talk_base::SocketAddress GetRemoteAddress() const OVERRIDE; |
| 44 virtual int Send(const void* data, size_t data_size, | 44 virtual int Send(const void* data, size_t data_size, |
| 45 const rtc::PacketOptions& options) OVERRIDE; | 45 const talk_base::PacketOptions& options) OVERRIDE; |
| 46 virtual int SendTo(const void* data, size_t data_size, | 46 virtual int SendTo(const void* data, size_t data_size, |
| 47 const rtc::SocketAddress& address, | 47 const talk_base::SocketAddress& address, |
| 48 const rtc::PacketOptions& options) OVERRIDE; | 48 const talk_base::PacketOptions& options) OVERRIDE; |
| 49 virtual int Close() OVERRIDE; | 49 virtual int Close() OVERRIDE; |
| 50 virtual State GetState() const OVERRIDE; | 50 virtual State GetState() const OVERRIDE; |
| 51 virtual int GetOption(rtc::Socket::Option option, int* value) OVERRIDE; | 51 virtual int GetOption(talk_base::Socket::Option option, int* value) OVERRIDE; |
| 52 virtual int SetOption(rtc::Socket::Option option, int value) OVERRIDE; | 52 virtual int SetOption(talk_base::Socket::Option option, int value) OVERRIDE; |
| 53 virtual int GetError() const OVERRIDE; | 53 virtual int GetError() const OVERRIDE; |
| 54 virtual void SetError(int error) OVERRIDE; | 54 virtual void SetError(int error) OVERRIDE; |
| 55 | 55 |
| 56 private: | 56 private: |
| 57 struct PendingPacket { | 57 struct PendingPacket { |
| 58 PendingPacket(const void* buffer, | 58 PendingPacket(const void* buffer, |
| 59 int buffer_size, | 59 int buffer_size, |
| 60 const net::IPEndPoint& address); | 60 const net::IPEndPoint& address); |
| 61 | 61 |
| 62 scoped_refptr<net::IOBufferWithSize> data; | 62 scoped_refptr<net::IOBufferWithSize> data; |
| 63 net::IPEndPoint address; | 63 net::IPEndPoint address; |
| 64 bool retried; | 64 bool retried; |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 void OnBindCompleted(int error); | 67 void OnBindCompleted(int error); |
| 68 | 68 |
| 69 void DoSend(); | 69 void DoSend(); |
| 70 void OnSendCompleted(int result); | 70 void OnSendCompleted(int result); |
| 71 | 71 |
| 72 void DoRead(); | 72 void DoRead(); |
| 73 void OnReadCompleted(int result); | 73 void OnReadCompleted(int result); |
| 74 void HandleReadResult(int result); | 74 void HandleReadResult(int result); |
| 75 | 75 |
| 76 scoped_ptr<net::UDPServerSocket> socket_; | 76 scoped_ptr<net::UDPServerSocket> socket_; |
| 77 | 77 |
| 78 State state_; | 78 State state_; |
| 79 int error_; | 79 int error_; |
| 80 | 80 |
| 81 rtc::SocketAddress local_address_; | 81 talk_base::SocketAddress local_address_; |
| 82 | 82 |
| 83 // Receive buffer and address are populated by asynchronous reads. | 83 // Receive buffer and address are populated by asynchronous reads. |
| 84 scoped_refptr<net::IOBuffer> receive_buffer_; | 84 scoped_refptr<net::IOBuffer> receive_buffer_; |
| 85 net::IPEndPoint receive_address_; | 85 net::IPEndPoint receive_address_; |
| 86 | 86 |
| 87 bool send_pending_; | 87 bool send_pending_; |
| 88 std::list<PendingPacket> send_queue_; | 88 std::list<PendingPacket> send_queue_; |
| 89 int send_queue_size_; | 89 int send_queue_size_; |
| 90 | 90 |
| 91 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); | 91 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 105 : state_(STATE_CLOSED), | 105 : state_(STATE_CLOSED), |
| 106 error_(0), | 106 error_(0), |
| 107 send_pending_(false), | 107 send_pending_(false), |
| 108 send_queue_size_(0) { | 108 send_queue_size_(0) { |
| 109 } | 109 } |
| 110 | 110 |
| 111 UdpPacketSocket::~UdpPacketSocket() { | 111 UdpPacketSocket::~UdpPacketSocket() { |
| 112 Close(); | 112 Close(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 bool UdpPacketSocket::Init(const rtc::SocketAddress& local_address, | 115 bool UdpPacketSocket::Init(const talk_base::SocketAddress& local_address, |
| 116 int min_port, int max_port) { | 116 int min_port, int max_port) { |
| 117 net::IPEndPoint local_endpoint; | 117 net::IPEndPoint local_endpoint; |
| 118 if (!jingle_glue::SocketAddressToIPEndPoint( | 118 if (!jingle_glue::SocketAddressToIPEndPoint( |
| 119 local_address, &local_endpoint)) { | 119 local_address, &local_endpoint)) { |
| 120 return false; | 120 return false; |
| 121 } | 121 } |
| 122 | 122 |
| 123 for (int port = min_port; port <= max_port; ++port) { | 123 for (int port = min_port; port <= max_port; ++port) { |
| 124 socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source())); | 124 socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source())); |
| 125 int result = socket_->Listen( | 125 int result = socket_->Listen( |
| (...skipping 15 matching lines...) Expand all Loading... |
| 141 &local_address_)) { | 141 &local_address_)) { |
| 142 return false; | 142 return false; |
| 143 } | 143 } |
| 144 | 144 |
| 145 state_ = STATE_BOUND; | 145 state_ = STATE_BOUND; |
| 146 DoRead(); | 146 DoRead(); |
| 147 | 147 |
| 148 return true; | 148 return true; |
| 149 } | 149 } |
| 150 | 150 |
| 151 rtc::SocketAddress UdpPacketSocket::GetLocalAddress() const { | 151 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const { |
| 152 DCHECK_EQ(state_, STATE_BOUND); | 152 DCHECK_EQ(state_, STATE_BOUND); |
| 153 return local_address_; | 153 return local_address_; |
| 154 } | 154 } |
| 155 | 155 |
| 156 rtc::SocketAddress UdpPacketSocket::GetRemoteAddress() const { | 156 talk_base::SocketAddress UdpPacketSocket::GetRemoteAddress() const { |
| 157 // UDP sockets are not connected - this method should never be called. | 157 // UDP sockets are not connected - this method should never be called. |
| 158 NOTREACHED(); | 158 NOTREACHED(); |
| 159 return rtc::SocketAddress(); | 159 return talk_base::SocketAddress(); |
| 160 } | 160 } |
| 161 | 161 |
| 162 int UdpPacketSocket::Send(const void* data, size_t data_size, | 162 int UdpPacketSocket::Send(const void* data, size_t data_size, |
| 163 const rtc::PacketOptions& options) { | 163 const talk_base::PacketOptions& options) { |
| 164 // UDP sockets are not connected - this method should never be called. | 164 // UDP sockets are not connected - this method should never be called. |
| 165 NOTREACHED(); | 165 NOTREACHED(); |
| 166 return EWOULDBLOCK; | 166 return EWOULDBLOCK; |
| 167 } | 167 } |
| 168 | 168 |
| 169 int UdpPacketSocket::SendTo(const void* data, size_t data_size, | 169 int UdpPacketSocket::SendTo(const void* data, size_t data_size, |
| 170 const rtc::SocketAddress& address, | 170 const talk_base::SocketAddress& address, |
| 171 const rtc::PacketOptions& options) { | 171 const talk_base::PacketOptions& options) { |
| 172 if (state_ != STATE_BOUND) { | 172 if (state_ != STATE_BOUND) { |
| 173 NOTREACHED(); | 173 NOTREACHED(); |
| 174 return EINVAL; | 174 return EINVAL; |
| 175 } | 175 } |
| 176 | 176 |
| 177 if (error_ != 0) { | 177 if (error_ != 0) { |
| 178 return error_; | 178 return error_; |
| 179 } | 179 } |
| 180 | 180 |
| 181 net::IPEndPoint endpoint; | 181 net::IPEndPoint endpoint; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 193 DoSend(); | 193 DoSend(); |
| 194 return data_size; | 194 return data_size; |
| 195 } | 195 } |
| 196 | 196 |
| 197 int UdpPacketSocket::Close() { | 197 int UdpPacketSocket::Close() { |
| 198 state_ = STATE_CLOSED; | 198 state_ = STATE_CLOSED; |
| 199 socket_.reset(); | 199 socket_.reset(); |
| 200 return 0; | 200 return 0; |
| 201 } | 201 } |
| 202 | 202 |
| 203 rtc::AsyncPacketSocket::State UdpPacketSocket::GetState() const { | 203 talk_base::AsyncPacketSocket::State UdpPacketSocket::GetState() const { |
| 204 return state_; | 204 return state_; |
| 205 } | 205 } |
| 206 | 206 |
| 207 int UdpPacketSocket::GetOption(rtc::Socket::Option option, int* value) { | 207 int UdpPacketSocket::GetOption(talk_base::Socket::Option option, int* value) { |
| 208 // This method is never called by libjingle. | 208 // This method is never called by libjingle. |
| 209 NOTIMPLEMENTED(); | 209 NOTIMPLEMENTED(); |
| 210 return -1; | 210 return -1; |
| 211 } | 211 } |
| 212 | 212 |
| 213 int UdpPacketSocket::SetOption(rtc::Socket::Option option, int value) { | 213 int UdpPacketSocket::SetOption(talk_base::Socket::Option option, int value) { |
| 214 if (state_ != STATE_BOUND) { | 214 if (state_ != STATE_BOUND) { |
| 215 NOTREACHED(); | 215 NOTREACHED(); |
| 216 return EINVAL; | 216 return EINVAL; |
| 217 } | 217 } |
| 218 | 218 |
| 219 switch (option) { | 219 switch (option) { |
| 220 case rtc::Socket::OPT_DONTFRAGMENT: | 220 case talk_base::Socket::OPT_DONTFRAGMENT: |
| 221 NOTIMPLEMENTED(); | 221 NOTIMPLEMENTED(); |
| 222 return -1; | 222 return -1; |
| 223 | 223 |
| 224 case rtc::Socket::OPT_RCVBUF: { | 224 case talk_base::Socket::OPT_RCVBUF: { |
| 225 int net_error = socket_->SetReceiveBufferSize(value); | 225 int net_error = socket_->SetReceiveBufferSize(value); |
| 226 return (net_error == net::OK) ? 0 : -1; | 226 return (net_error == net::OK) ? 0 : -1; |
| 227 } | 227 } |
| 228 | 228 |
| 229 case rtc::Socket::OPT_SNDBUF: { | 229 case talk_base::Socket::OPT_SNDBUF: { |
| 230 int net_error = socket_->SetSendBufferSize(value); | 230 int net_error = socket_->SetSendBufferSize(value); |
| 231 return (net_error == net::OK) ? 0 : -1; | 231 return (net_error == net::OK) ? 0 : -1; |
| 232 } | 232 } |
| 233 | 233 |
| 234 case rtc::Socket::OPT_NODELAY: | 234 case talk_base::Socket::OPT_NODELAY: |
| 235 // OPT_NODELAY is only for TCP sockets. | 235 // OPT_NODELAY is only for TCP sockets. |
| 236 NOTREACHED(); | 236 NOTREACHED(); |
| 237 return -1; | 237 return -1; |
| 238 | 238 |
| 239 case rtc::Socket::OPT_IPV6_V6ONLY: | 239 case talk_base::Socket::OPT_IPV6_V6ONLY: |
| 240 NOTIMPLEMENTED(); | 240 NOTIMPLEMENTED(); |
| 241 return -1; | 241 return -1; |
| 242 | 242 |
| 243 case rtc::Socket::OPT_DSCP: | 243 case talk_base::Socket::OPT_DSCP: |
| 244 NOTIMPLEMENTED(); | 244 NOTIMPLEMENTED(); |
| 245 return -1; | 245 return -1; |
| 246 | 246 |
| 247 case rtc::Socket::OPT_RTP_SENDTIME_EXTN_ID: | 247 case talk_base::Socket::OPT_RTP_SENDTIME_EXTN_ID: |
| 248 NOTIMPLEMENTED(); | 248 NOTIMPLEMENTED(); |
| 249 return -1; | 249 return -1; |
| 250 } | 250 } |
| 251 | 251 |
| 252 NOTREACHED(); | 252 NOTREACHED(); |
| 253 return -1; | 253 return -1; |
| 254 } | 254 } |
| 255 | 255 |
| 256 int UdpPacketSocket::GetError() const { | 256 int UdpPacketSocket::GetError() const { |
| 257 return error_; | 257 return error_; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 DoRead(); | 329 DoRead(); |
| 330 } | 330 } |
| 331 } | 331 } |
| 332 | 332 |
| 333 void UdpPacketSocket::HandleReadResult(int result) { | 333 void UdpPacketSocket::HandleReadResult(int result) { |
| 334 if (result == net::ERR_IO_PENDING) { | 334 if (result == net::ERR_IO_PENDING) { |
| 335 return; | 335 return; |
| 336 } | 336 } |
| 337 | 337 |
| 338 if (result > 0) { | 338 if (result > 0) { |
| 339 rtc::SocketAddress address; | 339 talk_base::SocketAddress address; |
| 340 if (!jingle_glue::IPEndPointToSocketAddress(receive_address_, &address)) { | 340 if (!jingle_glue::IPEndPointToSocketAddress(receive_address_, &address)) { |
| 341 NOTREACHED(); | 341 NOTREACHED(); |
| 342 LOG(ERROR) << "Failed to convert address received from RecvFrom()."; | 342 LOG(ERROR) << "Failed to convert address received from RecvFrom()."; |
| 343 return; | 343 return; |
| 344 } | 344 } |
| 345 SignalReadPacket(this, receive_buffer_->data(), result, address, | 345 SignalReadPacket(this, receive_buffer_->data(), result, address, |
| 346 rtc::CreatePacketTime(0)); | 346 talk_base::CreatePacketTime(0)); |
| 347 } else { | 347 } else { |
| 348 LOG(ERROR) << "Received error when reading from UDP socket: " << result; | 348 LOG(ERROR) << "Received error when reading from UDP socket: " << result; |
| 349 } | 349 } |
| 350 } | 350 } |
| 351 | 351 |
| 352 } // namespace | 352 } // namespace |
| 353 | 353 |
| 354 ChromiumPacketSocketFactory::ChromiumPacketSocketFactory() { | 354 ChromiumPacketSocketFactory::ChromiumPacketSocketFactory() { |
| 355 } | 355 } |
| 356 | 356 |
| 357 ChromiumPacketSocketFactory::~ChromiumPacketSocketFactory() { | 357 ChromiumPacketSocketFactory::~ChromiumPacketSocketFactory() { |
| 358 } | 358 } |
| 359 | 359 |
| 360 rtc::AsyncPacketSocket* ChromiumPacketSocketFactory::CreateUdpSocket( | 360 talk_base::AsyncPacketSocket* ChromiumPacketSocketFactory::CreateUdpSocket( |
| 361 const rtc::SocketAddress& local_address, | 361 const talk_base::SocketAddress& local_address, |
| 362 int min_port, int max_port) { | 362 int min_port, int max_port) { |
| 363 scoped_ptr<UdpPacketSocket> result(new UdpPacketSocket()); | 363 scoped_ptr<UdpPacketSocket> result(new UdpPacketSocket()); |
| 364 if (!result->Init(local_address, min_port, max_port)) | 364 if (!result->Init(local_address, min_port, max_port)) |
| 365 return NULL; | 365 return NULL; |
| 366 return result.release(); | 366 return result.release(); |
| 367 } | 367 } |
| 368 | 368 |
| 369 rtc::AsyncPacketSocket* | 369 talk_base::AsyncPacketSocket* |
| 370 ChromiumPacketSocketFactory::CreateServerTcpSocket( | 370 ChromiumPacketSocketFactory::CreateServerTcpSocket( |
| 371 const rtc::SocketAddress& local_address, | 371 const talk_base::SocketAddress& local_address, |
| 372 int min_port, int max_port, | 372 int min_port, int max_port, |
| 373 int opts) { | 373 int opts) { |
| 374 // We don't use TCP sockets for remoting connections. | 374 // We don't use TCP sockets for remoting connections. |
| 375 NOTIMPLEMENTED(); | 375 NOTIMPLEMENTED(); |
| 376 return NULL; | 376 return NULL; |
| 377 } | 377 } |
| 378 | 378 |
| 379 rtc::AsyncPacketSocket* | 379 talk_base::AsyncPacketSocket* |
| 380 ChromiumPacketSocketFactory::CreateClientTcpSocket( | 380 ChromiumPacketSocketFactory::CreateClientTcpSocket( |
| 381 const rtc::SocketAddress& local_address, | 381 const talk_base::SocketAddress& local_address, |
| 382 const rtc::SocketAddress& remote_address, | 382 const talk_base::SocketAddress& remote_address, |
| 383 const rtc::ProxyInfo& proxy_info, | 383 const talk_base::ProxyInfo& proxy_info, |
| 384 const std::string& user_agent, | 384 const std::string& user_agent, |
| 385 int opts) { | 385 int opts) { |
| 386 // We don't use TCP sockets for remoting connections. | 386 // We don't use TCP sockets for remoting connections. |
| 387 NOTREACHED(); | 387 NOTREACHED(); |
| 388 return NULL; | 388 return NULL; |
| 389 } | 389 } |
| 390 | 390 |
| 391 rtc::AsyncResolverInterface* | 391 talk_base::AsyncResolverInterface* |
| 392 ChromiumPacketSocketFactory::CreateAsyncResolver() { | 392 ChromiumPacketSocketFactory::CreateAsyncResolver() { |
| 393 return new rtc::AsyncResolver(); | 393 return new talk_base::AsyncResolver(); |
| 394 } | 394 } |
| 395 | 395 |
| 396 } // namespace protocol | 396 } // namespace protocol |
| 397 } // namespace remoting | 397 } // namespace remoting |
| OLD | NEW |