OLD | NEW |
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/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 // not changed the DSCP in the past, disable DSCP as it unlikely | 288 // not changed the DSCP in the past, disable DSCP as it unlikely |
289 // to work in the future. | 289 // to work in the future. |
290 last_dscp_ = net::DSCP_NO_CHANGE; | 290 last_dscp_ = net::DSCP_NO_CHANGE; |
291 } | 291 } |
292 } | 292 } |
293 | 293 |
294 uint64 tick_received = base::TimeTicks::Now().ToInternalValue(); | 294 uint64 tick_received = base::TimeTicks::Now().ToInternalValue(); |
295 | 295 |
296 packet_processing_helpers::ApplyPacketOptions( | 296 packet_processing_helpers::ApplyPacketOptions( |
297 packet.data->data(), packet.size, packet.packet_options, 0); | 297 packet.data->data(), packet.size, packet.packet_options, 0); |
298 int result = socket_->SendTo(packet.data.get(), | 298 int result = socket_->SendTo( |
299 packet.size, | 299 packet.data.get(), packet.size, packet.to, |
300 packet.to, | 300 base::Bind(&P2PSocketHostUdp::OnSend, base::Unretained(this), packet.id, |
301 base::Bind(&P2PSocketHostUdp::OnSend, | 301 packet.packet_options.transport_sequence_number, |
302 base::Unretained(this), | 302 tick_received)); |
303 packet.id, | |
304 tick_received)); | |
305 | 303 |
306 // sendto() may return an error, e.g. if we've received an ICMP Destination | 304 // sendto() may return an error, e.g. if we've received an ICMP Destination |
307 // Unreachable message. When this happens try sending the same packet again, | 305 // Unreachable message. When this happens try sending the same packet again, |
308 // and just drop it if it fails again. | 306 // and just drop it if it fails again. |
309 if (IsTransientError(result)) { | 307 if (IsTransientError(result)) { |
310 result = socket_->SendTo(packet.data.get(), | 308 result = socket_->SendTo( |
311 packet.size, | 309 packet.data.get(), packet.size, packet.to, |
312 packet.to, | 310 base::Bind(&P2PSocketHostUdp::OnSend, base::Unretained(this), packet.id, |
313 base::Bind(&P2PSocketHostUdp::OnSend, | 311 packet.packet_options.transport_sequence_number, |
314 base::Unretained(this), | 312 tick_received)); |
315 packet.id, | |
316 tick_received)); | |
317 } | 313 } |
318 | 314 |
319 if (result == net::ERR_IO_PENDING) { | 315 if (result == net::ERR_IO_PENDING) { |
320 send_pending_ = true; | 316 send_pending_ = true; |
321 } else { | 317 } else { |
322 HandleSendResult(packet.id, tick_received, result); | 318 HandleSendResult(packet.id, packet.packet_options.transport_sequence_number, |
| 319 tick_received, result); |
323 } | 320 } |
324 | 321 |
325 if (dump_outgoing_rtp_packet_) | 322 if (dump_outgoing_rtp_packet_) |
326 DumpRtpPacket(packet.data->data(), packet.size, false); | 323 DumpRtpPacket(packet.data->data(), packet.size, false); |
327 } | 324 } |
328 | 325 |
329 void P2PSocketHostUdp::OnSend(uint64 packet_id, | 326 void P2PSocketHostUdp::OnSend(uint64 packet_id, |
| 327 int32_t transport_sequence_number, |
330 uint64 tick_received, | 328 uint64 tick_received, |
331 int result) { | 329 int result) { |
332 DCHECK(send_pending_); | 330 DCHECK(send_pending_); |
333 DCHECK_NE(result, net::ERR_IO_PENDING); | 331 DCHECK_NE(result, net::ERR_IO_PENDING); |
334 | 332 |
335 send_pending_ = false; | 333 send_pending_ = false; |
336 | 334 |
337 HandleSendResult(packet_id, tick_received, result); | 335 HandleSendResult(packet_id, transport_sequence_number, tick_received, result); |
338 | 336 |
339 // Send next packets if we have them waiting in the buffer. | 337 // Send next packets if we have them waiting in the buffer. |
340 while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) { | 338 while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) { |
341 PendingPacket packet = send_queue_.front(); | 339 PendingPacket packet = send_queue_.front(); |
342 DoSend(packet); | 340 DoSend(packet); |
343 send_queue_.pop_front(); | 341 send_queue_.pop_front(); |
344 DecrementDelayedBytes(packet.size); | 342 DecrementDelayedBytes(packet.size); |
345 } | 343 } |
346 } | 344 } |
347 | 345 |
348 void P2PSocketHostUdp::HandleSendResult(uint64 packet_id, | 346 void P2PSocketHostUdp::HandleSendResult(uint64 packet_id, |
| 347 int32_t transport_sequence_number, |
349 uint64 tick_received, | 348 uint64 tick_received, |
350 int result) { | 349 int result) { |
351 TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id, | 350 TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id, |
352 "result", result); | 351 "result", result); |
353 if (result < 0) { | 352 if (result < 0) { |
354 if (!IsTransientError(result)) { | 353 if (!IsTransientError(result)) { |
355 LOG(ERROR) << "Error when sending data in UDP socket: " << result; | 354 LOG(ERROR) << "Error when sending data in UDP socket: " << result; |
356 OnError(); | 355 OnError(); |
357 return; | 356 return; |
358 } | 357 } |
359 VLOG(0) << "sendto() has failed twice returning a " | 358 VLOG(0) << "sendto() has failed twice returning a " |
360 " transient error " << GetTransientErrorName(result) | 359 " transient error " << GetTransientErrorName(result) |
361 << ". Dropping the packet."; | 360 << ". Dropping the packet."; |
362 } | 361 } |
363 | 362 |
364 // UMA to track the histograms from 1ms to 1 sec for how long a packet spends | 363 // UMA to track the histograms from 1ms to 1 sec for how long a packet spends |
365 // in the browser process. | 364 // in the browser process. |
366 UMA_HISTOGRAM_TIMES( | 365 const base::TimeTicks timeticks_received = |
367 "WebRTC.SystemSendPacketDuration_UDP" /* name */, | 366 base::TimeTicks::FromInternalValue(tick_received); |
368 base::TimeTicks::Now() - | 367 UMA_HISTOGRAM_TIMES("WebRTC.SystemSendPacketDuration_UDP" /* name */, |
369 base::TimeTicks::FromInternalValue(tick_received) /* sample */); | 368 base::TimeTicks::Now() - timeticks_received /* sample */); |
370 | 369 |
371 message_sender_->Send( | 370 uint64 send_time_ms = |
372 new P2PMsg_OnSendComplete(id_, P2PSendPacketMetrics(packet_id))); | 371 (timeticks_received - base::TimeTicks::UnixEpoch()).InMilliseconds(); |
| 372 |
| 373 message_sender_->Send(new P2PMsg_OnSendComplete( |
| 374 id_, P2PSendPacketMetrics(packet_id, transport_sequence_number, |
| 375 send_time_ms))); |
373 } | 376 } |
374 | 377 |
375 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection( | 378 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection( |
376 const net::IPEndPoint& remote_address, int id) { | 379 const net::IPEndPoint& remote_address, int id) { |
377 NOTREACHED(); | 380 NOTREACHED(); |
378 OnError(); | 381 OnError(); |
379 return NULL; | 382 return NULL; |
380 } | 383 } |
381 | 384 |
382 bool P2PSocketHostUdp::SetOption(P2PSocketOption option, int value) { | 385 bool P2PSocketHostUdp::SetOption(P2PSocketOption option, int value) { |
(...skipping 11 matching lines...) Expand all Loading... |
394 case P2P_SOCKET_OPT_DSCP: | 397 case P2P_SOCKET_OPT_DSCP: |
395 return (net::OK == socket_->SetDiffServCodePoint( | 398 return (net::OK == socket_->SetDiffServCodePoint( |
396 static_cast<net::DiffServCodePoint>(value))) ? true : false; | 399 static_cast<net::DiffServCodePoint>(value))) ? true : false; |
397 default: | 400 default: |
398 NOTREACHED(); | 401 NOTREACHED(); |
399 return false; | 402 return false; |
400 } | 403 } |
401 } | 404 } |
402 | 405 |
403 } // namespace content | 406 } // namespace content |
OLD | NEW |