| 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/jingle_glue/chromium_socket_factory.h" | 5 #include "remoting/jingle_glue/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" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 // Size of the buffer to allocate for RecvFrom(). | 22 // Size of the buffer to allocate for RecvFrom(). |
| 23 const int kReceiveBufferSize = 65536; | 23 const int kReceiveBufferSize = 65536; |
| 24 | 24 |
| 25 // Maximum amount of data in the send buffers. This is necessary to | 25 // Maximum amount of data in the send buffers. This is necessary to |
| 26 // prevent out-of-memory crashes if the caller sends data faster than | 26 // prevent out-of-memory crashes if the caller sends data faster than |
| 27 // Pepper's UDP API can handle it. This maximum should never be | 27 // Pepper's UDP API can handle it. This maximum should never be |
| 28 // reached under normal conditions. | 28 // reached under normal conditions. |
| 29 const int kMaxSendBufferSize = 256 * 1024; | 29 const int kMaxSendBufferSize = 256 * 1024; |
| 30 | 30 |
| 31 // Defines set of transient errors. These errors are ignored when we get them | 31 // Enum for different actions that can be taken after sendto() returns an error. |
| 32 // from sendto() calls. | 32 enum ErrorAction { |
| 33 bool IsTransientError(int error) { | 33 ERROR_ACTION_FAIL, |
| 34 return error == net::ERR_ADDRESS_UNREACHABLE || | 34 ERROR_ACTION_IGNORE, |
| 35 error == net::ERR_ADDRESS_INVALID; | 35 ERROR_ACTION_RETRY, |
| 36 }; |
| 37 |
| 38 // Returns true if |error| must be ignored when returned from sendto(). |retry| |
| 39 // is set set when sentto() should be called for the same packet again. |
| 40 // |
| 41 // Keep this logic in sync with GetErrorAction() in |
| 42 // remoting/client/plugin/pepper_packet_socket_factory.cc . |
| 43 ErrorAction GetErrorAction(int error) { |
| 44 switch (error) { |
| 45 // UDP is connectionless, so we may receive ICMP unreachable or reset errors |
| 46 // for previous sends to different addresses. |
| 47 case net::ERR_ADDRESS_UNREACHABLE: |
| 48 case net::ERR_CONNECTION_RESET: |
| 49 return ERROR_ACTION_RETRY; |
| 50 |
| 51 // Target address is invalid. The socket is still usable for different |
| 52 // target addresses and the error can be ignored. |
| 53 case net::ERR_ADDRESS_INVALID: |
| 54 return ERROR_ACTION_IGNORE; |
| 55 |
| 56 // May be returned when the packet is blocked by local firewall (see |
| 57 // https://code.google.com/p/webrtc/issues/detail?id=1207). The firewall may |
| 58 // still allow us to send to other addresses, so ignore the error for this |
| 59 // particular send. |
| 60 case net::ERR_ACCESS_DENIED: |
| 61 return ERROR_ACTION_IGNORE; |
| 62 |
| 63 // Indicates that the buffer in the network adapter is full, so drop this |
| 64 // packet and assume the socket is still usable. |
| 65 case net::ERR_OUT_OF_MEMORY: |
| 66 return ERROR_ACTION_IGNORE; |
| 67 |
| 68 default: |
| 69 return ERROR_ACTION_FAIL; |
| 70 } |
| 36 } | 71 } |
| 37 | 72 |
| 38 class UdpPacketSocket : public talk_base::AsyncPacketSocket { | 73 class UdpPacketSocket : public talk_base::AsyncPacketSocket { |
| 39 public: | 74 public: |
| 40 UdpPacketSocket(); | 75 UdpPacketSocket(); |
| 41 virtual ~UdpPacketSocket(); | 76 virtual ~UdpPacketSocket(); |
| 42 | 77 |
| 43 bool Init(const talk_base::SocketAddress& local_address, | 78 bool Init(const talk_base::SocketAddress& local_address, |
| 44 int min_port, int max_port); | 79 int min_port, int max_port); |
| 45 | 80 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 59 virtual void SetError(int error) OVERRIDE; | 94 virtual void SetError(int error) OVERRIDE; |
| 60 | 95 |
| 61 private: | 96 private: |
| 62 struct PendingPacket { | 97 struct PendingPacket { |
| 63 PendingPacket(const void* buffer, | 98 PendingPacket(const void* buffer, |
| 64 int buffer_size, | 99 int buffer_size, |
| 65 const net::IPEndPoint& address); | 100 const net::IPEndPoint& address); |
| 66 | 101 |
| 67 scoped_refptr<net::IOBufferWithSize> data; | 102 scoped_refptr<net::IOBufferWithSize> data; |
| 68 net::IPEndPoint address; | 103 net::IPEndPoint address; |
| 104 bool retried; |
| 69 }; | 105 }; |
| 70 | 106 |
| 71 void OnBindCompleted(int error); | 107 void OnBindCompleted(int error); |
| 72 | 108 |
| 73 void DoSend(); | 109 void DoSend(); |
| 74 void OnSendCompleted(int result); | 110 void OnSendCompleted(int result); |
| 75 | 111 |
| 76 void DoRead(); | 112 void DoRead(); |
| 77 void OnReadCompleted(int result); | 113 void OnReadCompleted(int result); |
| 78 void HandleReadResult(int result); | 114 void HandleReadResult(int result); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 93 int send_queue_size_; | 129 int send_queue_size_; |
| 94 | 130 |
| 95 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); | 131 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); |
| 96 }; | 132 }; |
| 97 | 133 |
| 98 UdpPacketSocket::PendingPacket::PendingPacket( | 134 UdpPacketSocket::PendingPacket::PendingPacket( |
| 99 const void* buffer, | 135 const void* buffer, |
| 100 int buffer_size, | 136 int buffer_size, |
| 101 const net::IPEndPoint& address) | 137 const net::IPEndPoint& address) |
| 102 : data(new net::IOBufferWithSize(buffer_size)), | 138 : data(new net::IOBufferWithSize(buffer_size)), |
| 103 address(address) { | 139 address(address), |
| 140 retried(false) { |
| 104 memcpy(data->data(), buffer, buffer_size); | 141 memcpy(data->data(), buffer, buffer_size); |
| 105 } | 142 } |
| 106 | 143 |
| 107 UdpPacketSocket::UdpPacketSocket() | 144 UdpPacketSocket::UdpPacketSocket() |
| 108 : state_(STATE_CLOSED), | 145 : state_(STATE_CLOSED), |
| 109 error_(0), | 146 error_(0), |
| 110 send_pending_(false), | 147 send_pending_(false), |
| 111 send_queue_size_(0) { | 148 send_queue_size_(0) { |
| 112 } | 149 } |
| 113 | 150 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 send_pending_ = true; | 315 send_pending_ = true; |
| 279 } else { | 316 } else { |
| 280 OnSendCompleted(result); | 317 OnSendCompleted(result); |
| 281 } | 318 } |
| 282 } | 319 } |
| 283 | 320 |
| 284 void UdpPacketSocket::OnSendCompleted(int result) { | 321 void UdpPacketSocket::OnSendCompleted(int result) { |
| 285 send_pending_ = false; | 322 send_pending_ = false; |
| 286 | 323 |
| 287 if (result < 0) { | 324 if (result < 0) { |
| 288 if (!IsTransientError(result)) { | 325 ErrorAction action = GetErrorAction(result); |
| 289 LOG(ERROR) << "Send failed on a UDP socket: " << result; | 326 switch (action) { |
| 290 error_ = EINVAL; | 327 case ERROR_ACTION_FAIL: |
| 291 return; | 328 LOG(ERROR) << "Send failed on a UDP socket: " << result; |
| 329 error_ = EINVAL; |
| 330 return; |
| 331 |
| 332 case ERROR_ACTION_RETRY: |
| 333 // Retry resending only once. |
| 334 if (!send_queue_.front().retried) { |
| 335 send_queue_.front().retried = true; |
| 336 DoSend(); |
| 337 return; |
| 338 } |
| 339 break; |
| 340 |
| 341 case ERROR_ACTION_IGNORE: |
| 342 break; |
| 292 } | 343 } |
| 293 } | 344 } |
| 294 | 345 |
| 295 // Don't need to worry about partial sends because this is a datagram | 346 // Don't need to worry about partial sends because this is a datagram |
| 296 // socket. | 347 // socket. |
| 297 send_queue_size_ -= send_queue_.front().data->size(); | 348 send_queue_size_ -= send_queue_.front().data->size(); |
| 298 send_queue_.pop_front(); | 349 send_queue_.pop_front(); |
| 299 DoSend(); | 350 DoSend(); |
| 300 } | 351 } |
| 301 | 352 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 NOTREACHED(); | 427 NOTREACHED(); |
| 377 return NULL; | 428 return NULL; |
| 378 } | 429 } |
| 379 | 430 |
| 380 talk_base::AsyncResolverInterface* | 431 talk_base::AsyncResolverInterface* |
| 381 ChromiumPacketSocketFactory::CreateAsyncResolver() { | 432 ChromiumPacketSocketFactory::CreateAsyncResolver() { |
| 382 return new talk_base::AsyncResolver(); | 433 return new talk_base::AsyncResolver(); |
| 383 } | 434 } |
| 384 | 435 |
| 385 } // namespace remoting | 436 } // namespace remoting |
| OLD | NEW |