Chromium Code Reviews| 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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 if (result == net::OK) { | 284 if (result == net::OK) { |
| 285 last_dscp_ = dscp; | 285 last_dscp_ = dscp; |
| 286 } else if (!IsTransientError(result) && last_dscp_ != net::DSCP_CS0) { | 286 } else if (!IsTransientError(result) && last_dscp_ != net::DSCP_CS0) { |
| 287 // We receieved a non-transient error, and it seems we have | 287 // We receieved a non-transient error, and it seems we have |
| 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 base::TimeTicks time_received = base::TimeTicks::Now(); |
| 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 auto callback_binding = base::Bind( |
| 299 packet.size, | 299 &P2PSocketHostUdp::OnSend, base::Unretained(this), packet.id, |
| 300 packet.to, | 300 packet.packet_options.transport_sequence_number, time_received); |
| 301 base::Bind(&P2PSocketHostUdp::OnSend, | 301 int result = socket_->SendTo(packet.data.get(), packet.size, packet.to, |
| 302 base::Unretained(this), | 302 callback_binding); |
| 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(packet.data.get(), packet.size, packet.to, |
| 311 packet.size, | 309 callback_binding); |
| 312 packet.to, | |
| 313 base::Bind(&P2PSocketHostUdp::OnSend, | |
| 314 base::Unretained(this), | |
| 315 packet.id, | |
| 316 tick_received)); | |
| 317 } | 310 } |
| 318 | 311 |
| 319 if (result == net::ERR_IO_PENDING) { | 312 if (result == net::ERR_IO_PENDING) { |
| 320 send_pending_ = true; | 313 send_pending_ = true; |
| 321 } else { | 314 } else { |
| 322 HandleSendResult(packet.id, tick_received, result); | 315 HandleSendResult(packet.id, packet.packet_options.transport_sequence_number, |
| 316 time_received, result); | |
| 323 } | 317 } |
| 324 | 318 |
| 325 if (dump_outgoing_rtp_packet_) | 319 if (dump_outgoing_rtp_packet_) |
| 326 DumpRtpPacket(packet.data->data(), packet.size, false); | 320 DumpRtpPacket(packet.data->data(), packet.size, false); |
| 327 } | 321 } |
| 328 | 322 |
| 329 void P2PSocketHostUdp::OnSend(uint64 packet_id, | 323 void P2PSocketHostUdp::OnSend(uint64_t packet_id, |
| 330 uint64 tick_received, | 324 int32_t transport_sequence_number, |
| 325 base::TimeTicks time_received, | |
| 331 int result) { | 326 int result) { |
| 332 DCHECK(send_pending_); | 327 DCHECK(send_pending_); |
| 333 DCHECK_NE(result, net::ERR_IO_PENDING); | 328 DCHECK_NE(result, net::ERR_IO_PENDING); |
| 334 | 329 |
| 335 send_pending_ = false; | 330 send_pending_ = false; |
| 336 | 331 |
| 337 HandleSendResult(packet_id, tick_received, result); | 332 HandleSendResult(packet_id, transport_sequence_number, time_received, result); |
| 338 | 333 |
| 339 // Send next packets if we have them waiting in the buffer. | 334 // Send next packets if we have them waiting in the buffer. |
| 340 while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) { | 335 while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) { |
| 341 PendingPacket packet = send_queue_.front(); | 336 PendingPacket packet = send_queue_.front(); |
| 342 DoSend(packet); | 337 DoSend(packet); |
| 343 send_queue_.pop_front(); | 338 send_queue_.pop_front(); |
| 344 DecrementDelayedBytes(packet.size); | 339 DecrementDelayedBytes(packet.size); |
| 345 } | 340 } |
| 346 } | 341 } |
| 347 | 342 |
| 348 void P2PSocketHostUdp::HandleSendResult(uint64 packet_id, | 343 void P2PSocketHostUdp::HandleSendResult(uint64_t packet_id, |
| 349 uint64 tick_received, | 344 int32_t transport_sequence_number, |
| 345 base::TimeTicks time_received, | |
|
Sergey Ulanov
2015/09/18 21:16:11
Should this be called send_time, or something like
Stefan
2015/09/22 07:51:36
I definitely agree. Changing.
| |
| 350 int result) { | 346 int result) { |
| 351 TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id, | 347 TRACE_EVENT_ASYNC_END1("p2p", "Send", packet_id, |
| 352 "result", result); | 348 "result", result); |
| 353 if (result < 0) { | 349 if (result < 0) { |
| 354 if (!IsTransientError(result)) { | 350 if (!IsTransientError(result)) { |
| 355 LOG(ERROR) << "Error when sending data in UDP socket: " << result; | 351 LOG(ERROR) << "Error when sending data in UDP socket: " << result; |
| 356 OnError(); | 352 OnError(); |
| 357 return; | 353 return; |
| 358 } | 354 } |
| 359 VLOG(0) << "sendto() has failed twice returning a " | 355 VLOG(0) << "sendto() has failed twice returning a " |
| 360 " transient error " << GetTransientErrorName(result) | 356 " transient error " << GetTransientErrorName(result) |
| 361 << ". Dropping the packet."; | 357 << ". Dropping the packet."; |
| 362 } | 358 } |
| 363 | 359 |
| 364 // UMA to track the histograms from 1ms to 1 sec for how long a packet spends | 360 // UMA to track the histograms from 1ms to 1 sec for how long a packet spends |
| 365 // in the browser process. | 361 // in the browser process. |
| 366 UMA_HISTOGRAM_TIMES( | 362 UMA_HISTOGRAM_TIMES("WebRTC.SystemSendPacketDuration_UDP" /* name */, |
| 367 "WebRTC.SystemSendPacketDuration_UDP" /* name */, | 363 base::TimeTicks::Now() - time_received /* sample */); |
| 368 base::TimeTicks::Now() - | |
| 369 base::TimeTicks::FromInternalValue(tick_received) /* sample */); | |
| 370 | 364 |
| 371 message_sender_->Send( | 365 message_sender_->Send(new P2PMsg_OnSendComplete( |
| 372 new P2PMsg_OnSendComplete(id_, P2PSendPacketMetrics(packet_id))); | 366 id_, P2PSendPacketMetrics(packet_id, transport_sequence_number, |
| 367 time_received))); | |
| 373 } | 368 } |
| 374 | 369 |
| 375 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection( | 370 P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection( |
| 376 const net::IPEndPoint& remote_address, int id) { | 371 const net::IPEndPoint& remote_address, int id) { |
| 377 NOTREACHED(); | 372 NOTREACHED(); |
| 378 OnError(); | 373 OnError(); |
| 379 return NULL; | 374 return NULL; |
| 380 } | 375 } |
| 381 | 376 |
| 382 bool P2PSocketHostUdp::SetOption(P2PSocketOption option, int value) { | 377 bool P2PSocketHostUdp::SetOption(P2PSocketOption option, int value) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 394 case P2P_SOCKET_OPT_DSCP: | 389 case P2P_SOCKET_OPT_DSCP: |
| 395 return (net::OK == socket_->SetDiffServCodePoint( | 390 return (net::OK == socket_->SetDiffServCodePoint( |
| 396 static_cast<net::DiffServCodePoint>(value))) ? true : false; | 391 static_cast<net::DiffServCodePoint>(value))) ? true : false; |
| 397 default: | 392 default: |
| 398 NOTREACHED(); | 393 NOTREACHED(); |
| 399 return false; | 394 return false; |
| 400 } | 395 } |
| 401 } | 396 } |
| 402 | 397 |
| 403 } // namespace content | 398 } // namespace content |
| OLD | NEW |