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

Side by Side Diff: content/browser/renderer_host/p2p/socket_host_udp.cc

Issue 693433003: Add a new finch experiment to control the system buffer size. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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
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 "content/browser/renderer_host/p2p/socket_host_udp.h" 5 #include "content/browser/renderer_host/p2p/socket_host_udp.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h"
9 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/strings/string_number_conversions.h"
10 #include "content/browser/renderer_host/p2p/socket_host_throttler.h" 13 #include "content/browser/renderer_host/p2p/socket_host_throttler.h"
11 #include "content/common/p2p_messages.h" 14 #include "content/common/p2p_messages.h"
12 #include "content/public/browser/content_browser_client.h" 15 #include "content/public/browser/content_browser_client.h"
13 #include "content/public/common/content_client.h" 16 #include "content/public/common/content_client.h"
14 #include "ipc/ipc_sender.h" 17 #include "ipc/ipc_sender.h"
15 #include "net/base/io_buffer.h" 18 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
17 #include "net/base/net_util.h" 20 #include "net/base/net_util.h"
18 #include "third_party/webrtc/base/asyncpacketsocket.h" 21 #include "third_party/webrtc/base/asyncpacketsocket.h"
19 22
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 throttler_(throttler) { 80 throttler_(throttler) {
78 } 81 }
79 82
80 P2PSocketHostUdp::~P2PSocketHostUdp() { 83 P2PSocketHostUdp::~P2PSocketHostUdp() {
81 if (state_ == STATE_OPEN) { 84 if (state_ == STATE_OPEN) {
82 DCHECK(socket_.get()); 85 DCHECK(socket_.get());
83 socket_.reset(); 86 socket_.reset();
84 } 87 }
85 } 88 }
86 89
90 void P2PSocketHostUdp::SetSendBufferSize() {
91 unsigned int send_buffer_size = 0;
92
93 base::StringToUint(
94 base::FieldTrialList::FindFullName("WebRTC-SystemUDPSendSocketSize"),
95 &send_buffer_size);
96
97 if (send_buffer_size > 0) {
98 if (!SetOption(P2P_SOCKET_OPT_SNDBUF, send_buffer_size)) {
99 LOG(WARNING) << "Failed to set socket send buffer size to "
100 << send_buffer_size;
101 }
102 }
103 }
104
87 bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address, 105 bool P2PSocketHostUdp::Init(const net::IPEndPoint& local_address,
88 const P2PHostAndIPEndPoint& remote_address) { 106 const P2PHostAndIPEndPoint& remote_address) {
89 DCHECK_EQ(state_, STATE_UNINITIALIZED); 107 DCHECK_EQ(state_, STATE_UNINITIALIZED);
90 108
91 int result = socket_->Listen(local_address); 109 int result = socket_->Listen(local_address);
92 if (result < 0) { 110 if (result < 0) {
93 LOG(ERROR) << "bind() failed: " << result; 111 LOG(ERROR) << "bind() failed: " << result;
94 OnError(); 112 OnError();
95 return false; 113 return false;
96 } 114 }
97 115
98 // Setting recv socket buffer size. 116 // Setting recv socket buffer size.
99 if (socket_->SetReceiveBufferSize(kRecvSocketBufferSize) != net::OK) { 117 if (socket_->SetReceiveBufferSize(kRecvSocketBufferSize) != net::OK) {
100 LOG(WARNING) << "Failed to set socket receive buffer size to " 118 LOG(WARNING) << "Failed to set socket receive buffer size to "
101 << kRecvSocketBufferSize; 119 << kRecvSocketBufferSize;
102 } 120 }
103 121
104 net::IPEndPoint address; 122 net::IPEndPoint address;
105 result = socket_->GetLocalAddress(&address); 123 result = socket_->GetLocalAddress(&address);
106 if (result < 0) { 124 if (result < 0) {
107 LOG(ERROR) << "P2PSocketHostUdp::Init(): unable to get local address: " 125 LOG(ERROR) << "P2PSocketHostUdp::Init(): unable to get local address: "
108 << result; 126 << result;
109 OnError(); 127 OnError();
110 return false; 128 return false;
111 } 129 }
112 VLOG(1) << "Local address: " << address.ToString(); 130 VLOG(1) << "Local address: " << address.ToString();
113 131
114 state_ = STATE_OPEN; 132 state_ = STATE_OPEN;
115 133
134 SetSendBufferSize();
135
116 // NOTE: Remote address will be same as what renderer provided. 136 // NOTE: Remote address will be same as what renderer provided.
117 message_sender_->Send(new P2PMsg_OnSocketCreated( 137 message_sender_->Send(new P2PMsg_OnSocketCreated(
118 id_, address, remote_address.ip_address)); 138 id_, address, remote_address.ip_address));
119 139
120 recv_buffer_ = new net::IOBuffer(kReadBufferSize); 140 recv_buffer_ = new net::IOBuffer(kReadBufferSize);
121 DoRead(); 141 DoRead();
122 142
123 return true; 143 return true;
124 } 144 }
125 145
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 int result = socket_->SetDiffServCodePoint(dscp); 258 int result = socket_->SetDiffServCodePoint(dscp);
239 if (result == net::OK) { 259 if (result == net::OK) {
240 last_dscp_ = dscp; 260 last_dscp_ = dscp;
241 } else if (!IsTransientError(result) && last_dscp_ != net::DSCP_CS0) { 261 } else if (!IsTransientError(result) && last_dscp_ != net::DSCP_CS0) {
242 // We receieved a non-transient error, and it seems we have 262 // We receieved a non-transient error, and it seems we have
243 // not changed the DSCP in the past, disable DSCP as it unlikely 263 // not changed the DSCP in the past, disable DSCP as it unlikely
244 // to work in the future. 264 // to work in the future.
245 last_dscp_ = net::DSCP_NO_CHANGE; 265 last_dscp_ = net::DSCP_NO_CHANGE;
246 } 266 }
247 } 267 }
268
269 uint64 tick_received = base::TimeTicks::Now().ToInternalValue();
270
248 packet_processing_helpers::ApplyPacketOptions( 271 packet_processing_helpers::ApplyPacketOptions(
249 packet.data->data(), packet.size, packet.packet_options, 0); 272 packet.data->data(), packet.size, packet.packet_options, 0);
250 int result = socket_->SendTo( 273 int result = socket_->SendTo(packet.data.get(),
251 packet.data.get(), 274 packet.size,
252 packet.size, 275 packet.to,
253 packet.to, 276 base::Bind(&P2PSocketHostUdp::OnSend,
254 base::Bind(&P2PSocketHostUdp::OnSend, base::Unretained(this), packet.id)); 277 base::Unretained(this),
278 packet.id,
279 tick_received));
255 280
256 // sendto() may return an error, e.g. if we've received an ICMP Destination 281 // sendto() may return an error, e.g. if we've received an ICMP Destination
257 // Unreachable message. When this happens try sending the same packet again, 282 // Unreachable message. When this happens try sending the same packet again,
258 // and just drop it if it fails again. 283 // and just drop it if it fails again.
259 if (IsTransientError(result)) { 284 if (IsTransientError(result)) {
260 result = socket_->SendTo( 285 result = socket_->SendTo(packet.data.get(),
261 packet.data.get(), 286 packet.size,
262 packet.size, 287 packet.to,
263 packet.to, 288 base::Bind(&P2PSocketHostUdp::OnSend,
264 base::Bind(&P2PSocketHostUdp::OnSend, base::Unretained(this), 289 base::Unretained(this),
265 packet.id)); 290 packet.id,
291 tick_received));
266 } 292 }
267 293
268 if (result == net::ERR_IO_PENDING) { 294 if (result == net::ERR_IO_PENDING) {
269 send_pending_ = true; 295 send_pending_ = true;
270 } else { 296 } else {
271 HandleSendResult(packet.id, result); 297 HandleSendResult(packet.id, tick_received, result);
272 } 298 }
273 299
274 if (dump_outgoing_rtp_packet_) 300 if (dump_outgoing_rtp_packet_)
275 DumpRtpPacket(packet.data->data(), packet.size, false); 301 DumpRtpPacket(packet.data->data(), packet.size, false);
276 } 302 }
277 303
278 void P2PSocketHostUdp::OnSend(uint64 packet_id, int result) { 304 void P2PSocketHostUdp::OnSend(uint64 packet_id,
305 uint64 tick_received,
306 int result) {
279 DCHECK(send_pending_); 307 DCHECK(send_pending_);
280 DCHECK_NE(result, net::ERR_IO_PENDING); 308 DCHECK_NE(result, net::ERR_IO_PENDING);
281 309
282 send_pending_ = false; 310 send_pending_ = false;
283 311
284 HandleSendResult(packet_id, result); 312 HandleSendResult(packet_id, tick_received, result);
285 313
286 // Send next packets if we have them waiting in the buffer. 314 // Send next packets if we have them waiting in the buffer.
287 while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) { 315 while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) {
288 PendingPacket packet = send_queue_.front(); 316 PendingPacket packet = send_queue_.front();
289 DoSend(packet); 317 DoSend(packet);
290 send_queue_.pop_front(); 318 send_queue_.pop_front();
291 DecrementDelayedBytes(packet.size); 319 DecrementDelayedBytes(packet.size);
292 } 320 }
293 } 321 }
294 322
295 void P2PSocketHostUdp::HandleSendResult(uint64 packet_id, int result) { 323 void P2PSocketHostUdp::HandleSendResult(uint64 packet_id,
324 uint64 tick_received,
325 int result) {
296 TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id, 326 TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id,
297 "result", result); 327 "result", result);
298 if (result < 0) { 328 if (result < 0) {
299 if (!IsTransientError(result)) { 329 if (!IsTransientError(result)) {
300 LOG(ERROR) << "Error when sending data in UDP socket: " << result; 330 LOG(ERROR) << "Error when sending data in UDP socket: " << result;
301 OnError(); 331 OnError();
302 return; 332 return;
303 } 333 }
304 VLOG(0) << "sendto() has failed twice returning a " 334 VLOG(0) << "sendto() has failed twice returning a "
305 " transient error. Dropping the packet."; 335 " transient error. Dropping the packet.";
306 } 336 }
337
338 // UMA to track the histograms from 1ms to 1 sec for how long a packet spends
339 // in the browser process.
340 UMA_HISTOGRAM_TIMES(
341 "WebRTC.SystemSendPacketDuration_UDP" /* name */,
342 base::TimeTicks::Now() -
343 base::TimeTicks::FromInternalValue(tick_received) /* sample */);
344
307 message_sender_->Send(new P2PMsg_OnSendComplete(id_)); 345 message_sender_->Send(new P2PMsg_OnSendComplete(id_));
308 } 346 }
309 347
310 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection( 348 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection(
311 const net::IPEndPoint& remote_address, int id) { 349 const net::IPEndPoint& remote_address, int id) {
312 NOTREACHED(); 350 NOTREACHED();
313 OnError(); 351 OnError();
314 return NULL; 352 return NULL;
315 } 353 }
316 354
317 bool P2PSocketHostUdp::SetOption(P2PSocketOption option, int value) { 355 bool P2PSocketHostUdp::SetOption(P2PSocketOption option, int value) {
318 DCHECK_EQ(STATE_OPEN, state_); 356 DCHECK_EQ(STATE_OPEN, state_);
319 switch (option) { 357 switch (option) {
320 case P2P_SOCKET_OPT_RCVBUF: 358 case P2P_SOCKET_OPT_RCVBUF:
321 return socket_->SetReceiveBufferSize(value) == net::OK; 359 return socket_->SetReceiveBufferSize(value) == net::OK;
322 case P2P_SOCKET_OPT_SNDBUF: 360 case P2P_SOCKET_OPT_SNDBUF:
323 return socket_->SetSendBufferSize(value) == net::OK; 361 return socket_->SetSendBufferSize(value) == net::OK;
324 case P2P_SOCKET_OPT_DSCP: 362 case P2P_SOCKET_OPT_DSCP:
325 return (net::OK == socket_->SetDiffServCodePoint( 363 return (net::OK == socket_->SetDiffServCodePoint(
326 static_cast<net::DiffServCodePoint>(value))) ? true : false; 364 static_cast<net::DiffServCodePoint>(value))) ? true : false;
327 default: 365 default:
328 NOTREACHED(); 366 NOTREACHED();
329 return false; 367 return false;
330 } 368 }
331 } 369 }
332 370
333 } // namespace content 371 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/p2p/socket_host_udp.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698