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

Side by Side Diff: remoting/client/plugin/pepper_packet_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
« no previous file with comments | « no previous file | remoting/jingle_glue/chromium_socket_factory.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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 "net/base/io_buffer.h" 9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h"
10 #include "ppapi/cpp/net_address.h" 11 #include "ppapi/cpp/net_address.h"
11 #include "ppapi/cpp/udp_socket.h" 12 #include "ppapi/cpp/udp_socket.h"
12 #include "ppapi/utility/completion_callback_factory.h" 13 #include "ppapi/utility/completion_callback_factory.h"
13 #include "remoting/client/plugin/pepper_util.h" 14 #include "remoting/client/plugin/pepper_util.h"
15 #include "remoting/jingle_glue/socket_util.h"
14 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" 16 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
15 17
16 namespace remoting { 18 namespace remoting {
17 19
18 namespace { 20 namespace {
19 21
20 // Size of the buffer to allocate for RecvFrom(). 22 // Size of the buffer to allocate for RecvFrom().
21 const int kReceiveBufferSize = 65536; 23 const int kReceiveBufferSize = 65536;
22 24
23 // 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
24 // 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
25 // 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
26 // reached under normal conditions. 28 // reached under normal conditions.
27 const int kMaxSendBufferSize = 256 * 1024; 29 const int kMaxSendBufferSize = 256 * 1024;
28 30
29 // Enum for different actions that can be taken after sendto() returns an error. 31 int PepperErrorToNetError(int error) {
Wez 2014/06/17 22:39:21 nit: Could this go into e.g. pepper_util.h?
Sergey Ulanov 2014/06/17 22:45:01 I don't think it's necessary because it's specific
30 enum ErrorAction {
31 ERROR_ACTION_FAIL,
32 ERROR_ACTION_IGNORE,
33 ERROR_ACTION_RETRY,
34 };
35
36 // Returns ErrorAction to perform if sendto() fails with |error|.
37 ErrorAction GetErrorAction(int error) {
38 switch (error) { 32 switch (error) {
39 // UDP is connectionless, so we may receive ICMP unreachable or reset errors 33 case PP_OK:
40 // for previous sends to different addresses. 34 return net::OK;
35 case PP_OK_COMPLETIONPENDING:
36 return net::ERR_IO_PENDING;
37 case PP_ERROR_ABORTED:
38 return net::ERR_ABORTED;
39 case PP_ERROR_BADARGUMENT:
40 return net::ERR_INVALID_ARGUMENT;
41 case PP_ERROR_FILENOTFOUND:
42 return net::ERR_FILE_NOT_FOUND;
43 case PP_ERROR_TIMEDOUT:
44 return net::ERR_TIMED_OUT;
45 case PP_ERROR_FILETOOBIG:
46 return net::ERR_FILE_TOO_BIG;
47 case PP_ERROR_NOTSUPPORTED:
48 return net::ERR_NOT_IMPLEMENTED;
49 case PP_ERROR_NOMEMORY:
50 return net::ERR_OUT_OF_MEMORY;
51 case PP_ERROR_FILEEXISTS:
52 return net::ERR_FILE_EXISTS;
53 case PP_ERROR_NOSPACE:
54 return net::ERR_FILE_NO_SPACE;
55 case PP_ERROR_CONNECTION_CLOSED:
56 return net::ERR_CONNECTION_CLOSED;
57 case PP_ERROR_CONNECTION_RESET:
58 return net::ERR_CONNECTION_RESET;
59 case PP_ERROR_CONNECTION_REFUSED:
60 return net::ERR_CONNECTION_REFUSED;
61 case PP_ERROR_CONNECTION_ABORTED:
62 return net::ERR_CONNECTION_ABORTED;
63 case PP_ERROR_CONNECTION_FAILED:
64 return net::ERR_CONNECTION_FAILED;
65 case PP_ERROR_NAME_NOT_RESOLVED:
66 return net::ERR_NAME_NOT_RESOLVED;
67 case PP_ERROR_ADDRESS_INVALID:
68 return net::ERR_ADDRESS_INVALID;
41 case PP_ERROR_ADDRESS_UNREACHABLE: 69 case PP_ERROR_ADDRESS_UNREACHABLE:
42 case PP_ERROR_CONNECTION_RESET: 70 return net::ERR_ADDRESS_UNREACHABLE;
43 return ERROR_ACTION_RETRY; 71 case PP_ERROR_CONNECTION_TIMEDOUT:
44 72 return net::ERR_CONNECTION_TIMED_OUT;
45 // Target address is invalid. The socket is still usable for different
46 // target addresses and the error can be ignored.
47 case PP_ERROR_ADDRESS_INVALID:
48 return ERROR_ACTION_IGNORE;
49
50 // May be returned when the packet is blocked by local firewall (see
51 // https://code.google.com/p/webrtc/issues/detail?id=1207). The firewall may
52 // still allow us to send to other addresses, so ignore the error for this
53 // particular send.
54 case PP_ERROR_NOACCESS: 73 case PP_ERROR_NOACCESS:
55 return ERROR_ACTION_IGNORE; 74 return net::ERR_NETWORK_ACCESS_DENIED;
56 75 case PP_ERROR_MESSAGE_TOO_BIG:
57 // Indicates that the buffer in the network adapter is full, so drop this 76 return net::ERR_MSG_TOO_BIG;
58 // packet and assume the socket is still usable. 77 case PP_ERROR_ADDRESS_IN_USE:
59 case PP_ERROR_NOMEMORY: 78 return net::ERR_ADDRESS_IN_USE;
60 return ERROR_ACTION_IGNORE;
61
62 default: 79 default:
63 return ERROR_ACTION_FAIL; 80 return net::ERR_FAILED;
64 } 81 }
65 } 82 }
66 83
67 class UdpPacketSocket : public talk_base::AsyncPacketSocket { 84 class UdpPacketSocket : public talk_base::AsyncPacketSocket {
68 public: 85 public:
69 explicit UdpPacketSocket(const pp::InstanceHandle& instance); 86 explicit UdpPacketSocket(const pp::InstanceHandle& instance);
70 virtual ~UdpPacketSocket(); 87 virtual ~UdpPacketSocket();
71 88
72 // |min_port| and |max_port| are set to zero if the port number 89 // |min_port| and |max_port| are set to zero if the port number
73 // should be assigned by the OS. 90 // should be assigned by the OS.
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 if (result == PP_ERROR_ABORTED) { 332 if (result == PP_ERROR_ABORTED) {
316 // Send is aborted when the socket is being destroyed. 333 // Send is aborted when the socket is being destroyed.
317 // |send_queue_| may be already destroyed, it's not safe to access 334 // |send_queue_| may be already destroyed, it's not safe to access
318 // it here. 335 // it here.
319 return; 336 return;
320 } 337 }
321 338
322 send_pending_ = false; 339 send_pending_ = false;
323 340
324 if (result < 0) { 341 if (result < 0) {
325 ErrorAction action = GetErrorAction(result); 342 int net_error = PepperErrorToNetError(result);
343 SocketErrorAction action = GetSocketErrorAction(net_error);
326 switch (action) { 344 switch (action) {
327 case ERROR_ACTION_FAIL: 345 case SOCKET_ERROR_ACTION_FAIL:
328 LOG(ERROR) << "Send failed on a UDP socket: " << result; 346 LOG(ERROR) << "Send failed on a UDP socket: " << result;
329 error_ = EINVAL; 347 error_ = EINVAL;
330 return; 348 return;
331 349
332 case ERROR_ACTION_RETRY: 350 case SOCKET_ERROR_ACTION_RETRY:
333 // Retry resending only once. 351 // Retry resending only once.
334 if (!send_queue_.front().retried) { 352 if (!send_queue_.front().retried) {
335 send_queue_.front().retried = true; 353 send_queue_.front().retried = true;
336 DoSend(); 354 DoSend();
337 return; 355 return;
338 } 356 }
339 break; 357 break;
340 358
341 case ERROR_ACTION_IGNORE: 359 case SOCKET_ERROR_ACTION_IGNORE:
342 break; 360 break;
343 } 361 }
344 } 362 }
345 363
346 send_queue_size_ -= send_queue_.front().data->size(); 364 send_queue_size_ -= send_queue_.front().data->size();
347 send_queue_.pop_front(); 365 send_queue_.pop_front();
348 DoSend(); 366 DoSend();
349 } 367 }
350 368
351 void UdpPacketSocket::DoRead() { 369 void UdpPacketSocket::DoRead() {
352 receive_buffer_.resize(kReceiveBufferSize); 370 receive_buffer_.resize(kReceiveBufferSize);
353 pp::CompletionCallbackWithOutput<pp::NetAddress> callback = 371 pp::CompletionCallbackWithOutput<pp::NetAddress> callback =
354 callback_factory_.NewCallbackWithOutput( 372 callback_factory_.NewCallbackWithOutput(
355 &UdpPacketSocket::OnReadCompleted); 373 &UdpPacketSocket::OnReadCompleted);
356 int result = 374 int result =
357 socket_.RecvFrom(&receive_buffer_[0], receive_buffer_.size(), callback); 375 socket_.RecvFrom(&receive_buffer_[0], receive_buffer_.size(), callback);
358 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 376 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
359 } 377 }
360 378
361 void UdpPacketSocket::OnReadCompleted(int result, pp::NetAddress address) { 379 void UdpPacketSocket::OnReadCompleted(int result, pp::NetAddress address) {
362 HandleReadResult(result, address); 380 HandleReadResult(result, address);
363 if (result > 0) { 381 if (result > 0) {
364 DoRead(); 382 DoRead();
365 } 383 }
366 } 384 }
367 385
368 void UdpPacketSocket::HandleReadResult(int result, pp::NetAddress address) { 386 void UdpPacketSocket::HandleReadResult(int result, pp::NetAddress address) {
369 if (result > 0) { 387 if (result > 0) {
370 talk_base::SocketAddress socket_address; 388 talk_base::SocketAddress socket_address;
371 PpNetAddressToSocketAddress(address, &socket_address); 389 PpNetAddressToSocketAddress(address, &socket_address);
372 SignalReadPacket(this, &receive_buffer_[0], result, socket_address, 390 SignalReadPacket(this, &receive_buffer_[0], result, socket_address,
373 talk_base::CreatePacketTime(0)); 391 talk_base::CreatePacketTime(0));
374 } else if (result != PP_ERROR_ABORTED) { 392 } else if (result != PP_ERROR_ABORTED) {
375 LOG(ERROR) << "Received error when reading from UDP socket: " << result; 393 LOG(ERROR) << "Received error when reading from UDP socket: " << result;
376 } 394 }
377 } 395 }
378 396
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 return NULL; 435 return NULL;
418 } 436 }
419 437
420 talk_base::AsyncResolverInterface* 438 talk_base::AsyncResolverInterface*
421 PepperPacketSocketFactory::CreateAsyncResolver() { 439 PepperPacketSocketFactory::CreateAsyncResolver() {
422 NOTREACHED(); 440 NOTREACHED();
423 return NULL; 441 return NULL;
424 } 442 }
425 443
426 } // namespace remoting 444 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | remoting/jingle_glue/chromium_socket_factory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698