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

Side by Side Diff: remoting/client/plugin/pepper_packet_socket_factory.cc

Issue 336113002: Avoid error messages from UDP sockets in Chromoting client. (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 | « remoting/client/plugin/pepper_network_manager.cc ('k') | no next file » | 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 "ppapi/cpp/net_address.h" 10 #include "ppapi/cpp/net_address.h"
11 #include "ppapi/cpp/udp_socket.h" 11 #include "ppapi/cpp/udp_socket.h"
12 #include "ppapi/utility/completion_callback_factory.h" 12 #include "ppapi/utility/completion_callback_factory.h"
13 #include "remoting/client/plugin/pepper_util.h" 13 #include "remoting/client/plugin/pepper_util.h"
14 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" 14 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
15 15
16 namespace remoting { 16 namespace remoting {
17 17
18 namespace { 18 namespace {
19 19
20 // Size of the buffer to allocate for RecvFrom(). 20 // Size of the buffer to allocate for RecvFrom().
21 const int kReceiveBufferSize = 65536; 21 const int kReceiveBufferSize = 65536;
22 22
23 // 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
24 // 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
25 // 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
26 // reached under normal conditions. 26 // reached under normal conditions.
27 const int kMaxSendBufferSize = 256 * 1024; 27 const int kMaxSendBufferSize = 256 * 1024;
28 28
29 // Enum for different actions that can be taken after sendto() returns an error.
30 enum ErrorAction {
31 ERROR_ACTION_FAIL,
32 ERROR_ACTION_IGNORE,
33 ERROR_ACTION_RETRY,
34 };
35
36 // Returns ErrorAction that must be taken after |error| returned from sendto().
Wez 2014/06/17 02:34:10 nit: is returned (which triggers line-wrap, so I'd
Sergey Ulanov 2014/06/17 02:54:13 Done.
37 ErrorAction GetErrorAction(int error) {
38 switch (error) {
39 // These errors are returned when one of the previous datagrams was sent to
40 // an unreachable address.
Wez 2014/06/17 02:34:10 nit: Be explicit that the error could correspond t
Sergey Ulanov 2014/06/17 02:54:13 Done, though I think the previous comment is expli
41 case PP_ERROR_ADDRESS_UNREACHABLE:
42 case PP_ERROR_CONNECTION_RESET:
43 return ERROR_ACTION_RETRY;
44
45 // Target address is invalid.
46 case PP_ERROR_ADDRESS_INVALID:
47 return ERROR_ACTION_IGNORE;
Wez 2014/06/17 02:34:10 Again, it would be good to clarify why we want to
Sergey Ulanov 2014/06/17 02:54:13 Done.
48
49 // May be returned when the packet is blocked by local firewall (see
50 // https://code.google.com/p/webrtc/issues/detail?id=1207). The error is
51 // transient because the firewall may block only some target addresses.
Wez 2014/06/17 02:34:10 nit: Suggest for the second sentence "The firewall
Sergey Ulanov 2014/06/17 02:54:13 Done.
52 case PP_ERROR_NOACCESS:
53 return ERROR_ACTION_IGNORE;
54
55 // Indicates that the buffer in the network adapter is full. The socket is
56 // still usable.
Wez 2014/06/17 02:34:10 nit: Suggest extending second sentence ".... is fu
Sergey Ulanov 2014/06/17 02:54:13 Done.
57 case PP_ERROR_NOMEMORY:
58 return ERROR_ACTION_IGNORE;
59
60 default:
61 return ERROR_ACTION_FAIL;
62 }
63 }
64
29 class UdpPacketSocket : public talk_base::AsyncPacketSocket { 65 class UdpPacketSocket : public talk_base::AsyncPacketSocket {
30 public: 66 public:
31 explicit UdpPacketSocket(const pp::InstanceHandle& instance); 67 explicit UdpPacketSocket(const pp::InstanceHandle& instance);
32 virtual ~UdpPacketSocket(); 68 virtual ~UdpPacketSocket();
33 69
34 // |min_port| and |max_port| are set to zero if the port number 70 // |min_port| and |max_port| are set to zero if the port number
35 // should be assigned by the OS. 71 // should be assigned by the OS.
36 bool Init(const talk_base::SocketAddress& local_address, 72 bool Init(const talk_base::SocketAddress& local_address,
37 int min_port, 73 int min_port,
38 int max_port); 74 int max_port);
(...skipping 15 matching lines...) Expand all
54 virtual void SetError(int error) OVERRIDE; 90 virtual void SetError(int error) OVERRIDE;
55 91
56 private: 92 private:
57 struct PendingPacket { 93 struct PendingPacket {
58 PendingPacket(const void* buffer, 94 PendingPacket(const void* buffer,
59 int buffer_size, 95 int buffer_size,
60 const pp::NetAddress& address); 96 const pp::NetAddress& address);
61 97
62 scoped_refptr<net::IOBufferWithSize> data; 98 scoped_refptr<net::IOBufferWithSize> data;
63 pp::NetAddress address; 99 pp::NetAddress address;
100 bool retried;
64 }; 101 };
65 102
66 void OnBindCompleted(int error); 103 void OnBindCompleted(int error);
67 104
68 void DoSend(); 105 void DoSend();
69 void OnSendCompleted(int result); 106 void OnSendCompleted(int result);
70 107
71 void DoRead(); 108 void DoRead();
72 void OnReadCompleted(int result, pp::NetAddress address); 109 void OnReadCompleted(int result, pp::NetAddress address);
73 void HandleReadResult(int result, pp::NetAddress address); 110 void HandleReadResult(int result, pp::NetAddress address);
(...skipping 21 matching lines...) Expand all
95 pp::CompletionCallbackFactory<UdpPacketSocket> callback_factory_; 132 pp::CompletionCallbackFactory<UdpPacketSocket> callback_factory_;
96 133
97 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); 134 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket);
98 }; 135 };
99 136
100 UdpPacketSocket::PendingPacket::PendingPacket( 137 UdpPacketSocket::PendingPacket::PendingPacket(
101 const void* buffer, 138 const void* buffer,
102 int buffer_size, 139 int buffer_size,
103 const pp::NetAddress& address) 140 const pp::NetAddress& address)
104 : data(new net::IOBufferWithSize(buffer_size)), 141 : data(new net::IOBufferWithSize(buffer_size)),
105 address(address) { 142 address(address),
143 retried(true) {
106 memcpy(data->data(), buffer, buffer_size); 144 memcpy(data->data(), buffer, buffer_size);
107 } 145 }
108 146
109 UdpPacketSocket::UdpPacketSocket(const pp::InstanceHandle& instance) 147 UdpPacketSocket::UdpPacketSocket(const pp::InstanceHandle& instance)
110 : instance_(instance), 148 : instance_(instance),
111 socket_(instance), 149 socket_(instance),
112 state_(STATE_CLOSED), 150 state_(STATE_CLOSED),
113 error_(0), 151 error_(0),
114 min_port_(0), 152 min_port_(0),
115 max_port_(0), 153 max_port_(0),
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 ++min_port_; 208 ++min_port_;
171 pp::NetAddress pp_local_address; 209 pp::NetAddress pp_local_address;
172 if (SocketAddressToPpNetAddressWithPort( 210 if (SocketAddressToPpNetAddressWithPort(
173 instance_, local_address_, &pp_local_address, min_port_)) { 211 instance_, local_address_, &pp_local_address, min_port_)) {
174 pp::CompletionCallback callback = 212 pp::CompletionCallback callback =
175 callback_factory_.NewCallback(&UdpPacketSocket::OnBindCompleted); 213 callback_factory_.NewCallback(&UdpPacketSocket::OnBindCompleted);
176 int result = socket_.Bind(pp_local_address, callback); 214 int result = socket_.Bind(pp_local_address, callback);
177 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 215 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
178 } 216 }
179 } else { 217 } else {
180 LOG(ERROR) << "Failed to bind UDP socket: " << result; 218 LOG(ERROR) << "Failed to bind UDP socket to " << local_address_.ToString()
219 << ", error: " << result;
181 } 220 }
182 } 221 }
183 222
184 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const { 223 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const {
185 DCHECK_EQ(state_, STATE_BOUND); 224 DCHECK_EQ(state_, STATE_BOUND);
186 return local_address_; 225 return local_address_;
187 } 226 }
188 227
189 talk_base::SocketAddress UdpPacketSocket::GetRemoteAddress() const { 228 talk_base::SocketAddress UdpPacketSocket::GetRemoteAddress() const {
190 // UDP sockets are not connected - this method should never be called. 229 // UDP sockets are not connected - this method should never be called.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 if (result == PP_ERROR_ABORTED) { 313 if (result == PP_ERROR_ABORTED) {
275 // Send is aborted when the socket is being destroyed. 314 // Send is aborted when the socket is being destroyed.
276 // |send_queue_| may be already destroyed, it's not safe to access 315 // |send_queue_| may be already destroyed, it's not safe to access
277 // it here. 316 // it here.
278 return; 317 return;
279 } 318 }
280 319
281 send_pending_ = false; 320 send_pending_ = false;
282 321
283 if (result < 0) { 322 if (result < 0) {
284 LOG(ERROR) << "Send failed on a UDP socket: " << result; 323 ErrorAction action = GetErrorAction(result);
324 switch (action) {
325 case ERROR_ACTION_FAIL:
326 LOG(ERROR) << "Send failed on a UDP socket: " << result;
327 error_ = EINVAL;
328 return;
285 329
286 // OS (e.g. OSX) may return EHOSTUNREACH when the peer has the 330 case ERROR_ACTION_RETRY:
287 // same subnet address as the local host but connected to a 331 // Retry resending only once.
288 // different network. That error must be ingored because the 332 if (!send_queue_.front().retried) {
289 // socket may still be useful for other ICE canidadates (e.g. for 333 send_queue_.front().retried = true;
290 // STUN candidates with a different address). Unfortunately pepper 334 DoSend();
291 // interface currently returns PP_ERROR_FAILED for any error (see 335 return;
292 // crbug.com/136406). It's not possible to distinguish that case 336 }
293 // from other errors and so we have to ingore all of them. This 337 break;
294 // behavior matchers the libjingle's AsyncUDPSocket used by the
295 // host.
296 //
297 // TODO(sergeyu): Once implementation of the Pepper UDP interface
298 // is fixed, uncomment the code below, but ignore
299 // host-unreacheable error.
300 338
301 // error_ = EINVAL; 339 case ERROR_ACTION_IGNORE:
302 // return; 340 break;
341 }
303 } 342 }
304 343
305 send_queue_size_ -= send_queue_.front().data->size(); 344 send_queue_size_ -= send_queue_.front().data->size();
306 send_queue_.pop_front(); 345 send_queue_.pop_front();
307 DoSend(); 346 DoSend();
308 } 347 }
309 348
310 void UdpPacketSocket::DoRead() { 349 void UdpPacketSocket::DoRead() {
311 receive_buffer_.resize(kReceiveBufferSize); 350 receive_buffer_.resize(kReceiveBufferSize);
312 pp::CompletionCallbackWithOutput<pp::NetAddress> callback = 351 pp::CompletionCallbackWithOutput<pp::NetAddress> callback =
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 return NULL; 415 return NULL;
377 } 416 }
378 417
379 talk_base::AsyncResolverInterface* 418 talk_base::AsyncResolverInterface*
380 PepperPacketSocketFactory::CreateAsyncResolver() { 419 PepperPacketSocketFactory::CreateAsyncResolver() {
381 NOTREACHED(); 420 NOTREACHED();
382 return NULL; 421 return NULL;
383 } 422 }
384 423
385 } // namespace remoting 424 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/plugin/pepper_network_manager.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698