Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: remoting/jingle_glue/chromium_socket_factory.cc

Issue 339503006: Update error-handling logic in ChromiumPacketSocketFactory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698