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

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
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 // Returns true if |error| must be ignored when returned from sendto().
30 bool IsTransientError(int error) {
Wez 2014/06/16 22:36:36 Are all of these errors really transient per-packe
Sergey Ulanov 2014/06/17 00:53:35 This list is based on what chrome does for sockets
31 return error == PP_ERROR_ADDRESS_UNREACHABLE ||
32 error == PP_ERROR_ADDRESS_INVALID || error == PP_ERROR_NOACCESS ||
33 error == PP_ERROR_CONNECTION_RESET || error == PP_ERROR_NOMEMORY;
Wez 2014/06/16 22:36:36 I think it'd be good to clarify why this particula
Sergey Ulanov 2014/06/17 00:53:35 Done. Also added |retry| flag. It makes sense to r
34 }
35
29 class UdpPacketSocket : public talk_base::AsyncPacketSocket { 36 class UdpPacketSocket : public talk_base::AsyncPacketSocket {
30 public: 37 public:
31 explicit UdpPacketSocket(const pp::InstanceHandle& instance); 38 explicit UdpPacketSocket(const pp::InstanceHandle& instance);
32 virtual ~UdpPacketSocket(); 39 virtual ~UdpPacketSocket();
33 40
34 // |min_port| and |max_port| are set to zero if the port number 41 // |min_port| and |max_port| are set to zero if the port number
35 // should be assigned by the OS. 42 // should be assigned by the OS.
36 bool Init(const talk_base::SocketAddress& local_address, 43 bool Init(const talk_base::SocketAddress& local_address,
37 int min_port, 44 int min_port,
38 int max_port); 45 int max_port);
(...skipping 15 matching lines...) Expand all
54 virtual void SetError(int error) OVERRIDE; 61 virtual void SetError(int error) OVERRIDE;
55 62
56 private: 63 private:
57 struct PendingPacket { 64 struct PendingPacket {
58 PendingPacket(const void* buffer, 65 PendingPacket(const void* buffer,
59 int buffer_size, 66 int buffer_size,
60 const pp::NetAddress& address); 67 const pp::NetAddress& address);
61 68
62 scoped_refptr<net::IOBufferWithSize> data; 69 scoped_refptr<net::IOBufferWithSize> data;
63 pp::NetAddress address; 70 pp::NetAddress address;
71 bool retried;
64 }; 72 };
65 73
66 void OnBindCompleted(int error); 74 void OnBindCompleted(int error);
67 75
68 void DoSend(); 76 void DoSend();
69 void OnSendCompleted(int result); 77 void OnSendCompleted(int result);
70 78
71 void DoRead(); 79 void DoRead();
72 void OnReadCompleted(int result, pp::NetAddress address); 80 void OnReadCompleted(int result, pp::NetAddress address);
73 void HandleReadResult(int result, pp::NetAddress address); 81 void HandleReadResult(int result, pp::NetAddress address);
(...skipping 21 matching lines...) Expand all
95 pp::CompletionCallbackFactory<UdpPacketSocket> callback_factory_; 103 pp::CompletionCallbackFactory<UdpPacketSocket> callback_factory_;
96 104
97 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); 105 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket);
98 }; 106 };
99 107
100 UdpPacketSocket::PendingPacket::PendingPacket( 108 UdpPacketSocket::PendingPacket::PendingPacket(
101 const void* buffer, 109 const void* buffer,
102 int buffer_size, 110 int buffer_size,
103 const pp::NetAddress& address) 111 const pp::NetAddress& address)
104 : data(new net::IOBufferWithSize(buffer_size)), 112 : data(new net::IOBufferWithSize(buffer_size)),
105 address(address) { 113 address(address),
114 retried(true) {
106 memcpy(data->data(), buffer, buffer_size); 115 memcpy(data->data(), buffer, buffer_size);
107 } 116 }
108 117
109 UdpPacketSocket::UdpPacketSocket(const pp::InstanceHandle& instance) 118 UdpPacketSocket::UdpPacketSocket(const pp::InstanceHandle& instance)
110 : instance_(instance), 119 : instance_(instance),
111 socket_(instance), 120 socket_(instance),
112 state_(STATE_CLOSED), 121 state_(STATE_CLOSED),
113 error_(0), 122 error_(0),
114 min_port_(0), 123 min_port_(0),
115 max_port_(0), 124 max_port_(0),
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 ++min_port_; 179 ++min_port_;
171 pp::NetAddress pp_local_address; 180 pp::NetAddress pp_local_address;
172 if (SocketAddressToPpNetAddressWithPort( 181 if (SocketAddressToPpNetAddressWithPort(
173 instance_, local_address_, &pp_local_address, min_port_)) { 182 instance_, local_address_, &pp_local_address, min_port_)) {
174 pp::CompletionCallback callback = 183 pp::CompletionCallback callback =
175 callback_factory_.NewCallback(&UdpPacketSocket::OnBindCompleted); 184 callback_factory_.NewCallback(&UdpPacketSocket::OnBindCompleted);
176 int result = socket_.Bind(pp_local_address, callback); 185 int result = socket_.Bind(pp_local_address, callback);
177 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 186 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
178 } 187 }
179 } else { 188 } else {
180 LOG(ERROR) << "Failed to bind UDP socket: " << result; 189 LOG(ERROR) << "Failed to bind UDP socket to " << local_address_.ToString()
190 << ", error: " << result;
181 } 191 }
182 } 192 }
183 193
184 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const { 194 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const {
185 DCHECK_EQ(state_, STATE_BOUND); 195 DCHECK_EQ(state_, STATE_BOUND);
186 return local_address_; 196 return local_address_;
187 } 197 }
188 198
189 talk_base::SocketAddress UdpPacketSocket::GetRemoteAddress() const { 199 talk_base::SocketAddress UdpPacketSocket::GetRemoteAddress() const {
190 // UDP sockets are not connected - this method should never be called. 200 // 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) { 284 if (result == PP_ERROR_ABORTED) {
275 // Send is aborted when the socket is being destroyed. 285 // Send is aborted when the socket is being destroyed.
276 // |send_queue_| may be already destroyed, it's not safe to access 286 // |send_queue_| may be already destroyed, it's not safe to access
277 // it here. 287 // it here.
278 return; 288 return;
279 } 289 }
280 290
281 send_pending_ = false; 291 send_pending_ = false;
282 292
283 if (result < 0) { 293 if (result < 0) {
284 LOG(ERROR) << "Send failed on a UDP socket: " << result; 294 if (!IsTransientError(result)) {
295 LOG(ERROR) << "Send failed on a UDP socket: " << result;
296 return;
297 }
285 298
286 // OS (e.g. OSX) may return EHOSTUNREACH when the peer has the 299 // If this is a transient error and we haven't tried resending the packet
287 // same subnet address as the local host but connected to a 300 // yet, then try resending it.
288 // different network. That error must be ingored because the 301 if (!send_queue_.front().retried) {
289 // socket may still be useful for other ICE canidadates (e.g. for 302 send_queue_.front().retried = true;
290 // STUN candidates with a different address). Unfortunately pepper 303 DoSend();
291 // interface currently returns PP_ERROR_FAILED for any error (see 304 return;
292 // crbug.com/136406). It's not possible to distinguish that case 305 }
293 // from other errors and so we have to ingore all of them. This
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
301 // error_ = EINVAL;
302 // return;
303 } 306 }
304 307
305 send_queue_size_ -= send_queue_.front().data->size(); 308 send_queue_size_ -= send_queue_.front().data->size();
306 send_queue_.pop_front(); 309 send_queue_.pop_front();
307 DoSend(); 310 DoSend();
308 } 311 }
309 312
310 void UdpPacketSocket::DoRead() { 313 void UdpPacketSocket::DoRead() {
311 receive_buffer_.resize(kReceiveBufferSize); 314 receive_buffer_.resize(kReceiveBufferSize);
312 pp::CompletionCallbackWithOutput<pp::NetAddress> callback = 315 pp::CompletionCallbackWithOutput<pp::NetAddress> callback =
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 return NULL; 379 return NULL;
377 } 380 }
378 381
379 talk_base::AsyncResolverInterface* 382 talk_base::AsyncResolverInterface*
380 PepperPacketSocketFactory::CreateAsyncResolver() { 383 PepperPacketSocketFactory::CreateAsyncResolver() {
381 NOTREACHED(); 384 NOTREACHED();
382 return NULL; 385 return NULL;
383 } 386 }
384 387
385 } // namespace remoting 388 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698