| 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_tcp.h" | 5 #include "content/browser/renderer_host/p2p/socket_host_tcp.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 LOG(ERROR) << "Page tried to send a data packet to " << to.ToString() | 376 LOG(ERROR) << "Page tried to send a data packet to " << to.ToString() |
| 377 << " before STUN binding is finished."; | 377 << " before STUN binding is finished."; |
| 378 OnError(); | 378 OnError(); |
| 379 return; | 379 return; |
| 380 } | 380 } |
| 381 } | 381 } |
| 382 | 382 |
| 383 DoSend(to, data, options); | 383 DoSend(to, data, options); |
| 384 } | 384 } |
| 385 | 385 |
| 386 void P2PSocketHostTcpBase::WriteOrQueue( | 386 void P2PSocketHostTcpBase::WriteOrQueue(SendBuffer& buffer) { |
| 387 scoped_refptr<net::DrainableIOBuffer>& buffer) { | |
| 388 IncrementTotalSentPackets(); | 387 IncrementTotalSentPackets(); |
| 389 if (write_buffer_.get()) { | 388 if (write_buffer_.second.get()) { |
| 390 write_queue_.push(buffer); | 389 write_queue_.push(buffer); |
| 391 IncrementDelayedPackets(); | 390 IncrementDelayedPackets(); |
| 392 IncrementDelayedBytes(buffer->size()); | 391 IncrementDelayedBytes(buffer.second->size()); |
| 393 return; | 392 return; |
| 394 } | 393 } |
| 395 | 394 |
| 396 write_buffer_ = buffer; | 395 write_buffer_ = buffer; |
| 397 DoWrite(); | 396 DoWrite(); |
| 398 } | 397 } |
| 399 | 398 |
| 400 void P2PSocketHostTcpBase::DoWrite() { | 399 void P2PSocketHostTcpBase::DoWrite() { |
| 401 while (write_buffer_.get() && state_ == STATE_OPEN && !write_pending_) { | 400 while (write_buffer_.second.get() && state_ == STATE_OPEN && |
| 401 !write_pending_) { |
| 402 int result = socket_->Write( | 402 int result = socket_->Write( |
| 403 write_buffer_.get(), | 403 write_buffer_.second.get(), write_buffer_.second->BytesRemaining(), |
| 404 write_buffer_->BytesRemaining(), | |
| 405 base::Bind(&P2PSocketHostTcp::OnWritten, base::Unretained(this))); | 404 base::Bind(&P2PSocketHostTcp::OnWritten, base::Unretained(this))); |
| 406 HandleWriteResult(result); | 405 HandleWriteResult(result); |
| 407 } | 406 } |
| 408 } | 407 } |
| 409 | 408 |
| 410 void P2PSocketHostTcpBase::OnWritten(int result) { | 409 void P2PSocketHostTcpBase::OnWritten(int result) { |
| 411 DCHECK(write_pending_); | 410 DCHECK(write_pending_); |
| 412 DCHECK_NE(result, net::ERR_IO_PENDING); | 411 DCHECK_NE(result, net::ERR_IO_PENDING); |
| 413 | 412 |
| 414 write_pending_ = false; | 413 write_pending_ = false; |
| 415 HandleWriteResult(result); | 414 HandleWriteResult(result); |
| 416 DoWrite(); | 415 DoWrite(); |
| 417 } | 416 } |
| 418 | 417 |
| 419 void P2PSocketHostTcpBase::HandleWriteResult(int result) { | 418 void P2PSocketHostTcpBase::HandleWriteResult(int result) { |
| 420 DCHECK(write_buffer_.get()); | 419 DCHECK(write_buffer_.second.get()); |
| 421 if (result >= 0) { | 420 if (result >= 0) { |
| 422 write_buffer_->DidConsume(result); | 421 write_buffer_.second->DidConsume(result); |
| 423 if (write_buffer_->BytesRemaining() == 0) { | 422 if (write_buffer_.second->BytesRemaining() == 0) { |
| 424 message_sender_->Send( | 423 base::TimeTicks send_time = base::TimeTicks::Now(); |
| 425 new P2PMsg_OnSendComplete(id_, P2PSendPacketMetrics())); | 424 message_sender_->Send(new P2PMsg_OnSendComplete( |
| 425 id_, P2PSendPacketMetrics(0, write_buffer_.first, send_time))); |
| 426 if (write_queue_.empty()) { | 426 if (write_queue_.empty()) { |
| 427 write_buffer_ = nullptr; | 427 write_buffer_.second = nullptr; |
| 428 write_buffer_.first = -1; |
| 428 } else { | 429 } else { |
| 429 write_buffer_ = write_queue_.front(); | 430 write_buffer_ = write_queue_.front(); |
| 430 write_queue_.pop(); | 431 write_queue_.pop(); |
| 431 // Update how many bytes are still waiting to be sent. | 432 // Update how many bytes are still waiting to be sent. |
| 432 DecrementDelayedBytes(write_buffer_->size()); | 433 DecrementDelayedBytes(write_buffer_.second->size()); |
| 433 } | 434 } |
| 434 } | 435 } |
| 435 } else if (result == net::ERR_IO_PENDING) { | 436 } else if (result == net::ERR_IO_PENDING) { |
| 436 write_pending_ = true; | 437 write_pending_ = true; |
| 437 } else { | 438 } else { |
| 438 ReportSocketError(result, "WebRTC.ICE.TcpSocketWriteErrorCode"); | 439 ReportSocketError(result, "WebRTC.ICE.TcpSocketWriteErrorCode"); |
| 439 | 440 |
| 440 LOG(ERROR) << "Error when sending data in TCP socket: " << result; | 441 LOG(ERROR) << "Error when sending data in TCP socket: " << result; |
| 441 OnError(); | 442 OnError(); |
| 442 } | 443 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 std::vector<char> data(cur, cur + packet_size); | 524 std::vector<char> data(cur, cur + packet_size); |
| 524 OnPacket(data); | 525 OnPacket(data); |
| 525 consumed += packet_size; | 526 consumed += packet_size; |
| 526 return consumed; | 527 return consumed; |
| 527 } | 528 } |
| 528 | 529 |
| 529 void P2PSocketHostTcp::DoSend(const net::IPEndPoint& to, | 530 void P2PSocketHostTcp::DoSend(const net::IPEndPoint& to, |
| 530 const std::vector<char>& data, | 531 const std::vector<char>& data, |
| 531 const rtc::PacketOptions& options) { | 532 const rtc::PacketOptions& options) { |
| 532 int size = kPacketHeaderSize + data.size(); | 533 int size = kPacketHeaderSize + data.size(); |
| 533 scoped_refptr<net::DrainableIOBuffer> buffer = | 534 SendBuffer buffer = |
| 534 new net::DrainableIOBuffer(new net::IOBuffer(size), size); | 535 std::make_pair(options.packet_id, |
| 535 *reinterpret_cast<uint16_t*>(buffer->data()) = base::HostToNet16(data.size()); | 536 new net::DrainableIOBuffer(new net::IOBuffer(size), size)); |
| 536 memcpy(buffer->data() + kPacketHeaderSize, &data[0], data.size()); | 537 *reinterpret_cast<uint16_t*>(buffer.second->data()) = |
| 538 base::HostToNet16(data.size()); |
| 539 memcpy(buffer.second->data() + kPacketHeaderSize, &data[0], data.size()); |
| 537 | 540 |
| 538 cricket::ApplyPacketOptions( | 541 cricket::ApplyPacketOptions( |
| 539 reinterpret_cast<uint8_t*>(buffer->data()) + kPacketHeaderSize, | 542 reinterpret_cast<uint8_t*>(buffer.second->data()) + kPacketHeaderSize, |
| 540 buffer->BytesRemaining() - kPacketHeaderSize, options.packet_time_params, | 543 buffer.second->BytesRemaining() - kPacketHeaderSize, |
| 544 options.packet_time_params, |
| 541 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); | 545 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); |
| 542 | 546 |
| 543 WriteOrQueue(buffer); | 547 WriteOrQueue(buffer); |
| 544 } | 548 } |
| 545 | 549 |
| 546 // P2PSocketHostStunTcp | 550 // P2PSocketHostStunTcp |
| 547 P2PSocketHostStunTcp::P2PSocketHostStunTcp( | 551 P2PSocketHostStunTcp::P2PSocketHostStunTcp( |
| 548 IPC::Sender* message_sender, | 552 IPC::Sender* message_sender, |
| 549 int socket_id, | 553 int socket_id, |
| 550 P2PSocketType type, | 554 P2PSocketType type, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 // Accepts only complete STUN/TURN packets. | 601 // Accepts only complete STUN/TURN packets. |
| 598 if (data.size() != expected_len) { | 602 if (data.size() != expected_len) { |
| 599 NOTREACHED(); | 603 NOTREACHED(); |
| 600 OnError(); | 604 OnError(); |
| 601 return; | 605 return; |
| 602 } | 606 } |
| 603 | 607 |
| 604 // Add any pad bytes to the total size. | 608 // Add any pad bytes to the total size. |
| 605 int size = data.size() + pad_bytes; | 609 int size = data.size() + pad_bytes; |
| 606 | 610 |
| 607 scoped_refptr<net::DrainableIOBuffer> buffer = | 611 SendBuffer buffer = |
| 608 new net::DrainableIOBuffer(new net::IOBuffer(size), size); | 612 std::make_pair(options.packet_id, |
| 609 memcpy(buffer->data(), &data[0], data.size()); | 613 new net::DrainableIOBuffer(new net::IOBuffer(size), size)); |
| 614 memcpy(buffer.second->data(), &data[0], data.size()); |
| 610 | 615 |
| 611 cricket::ApplyPacketOptions( | 616 cricket::ApplyPacketOptions( |
| 612 reinterpret_cast<uint8_t*>(buffer->data()), data.size(), | 617 reinterpret_cast<uint8_t*>(buffer.second->data()), data.size(), |
| 613 options.packet_time_params, | 618 options.packet_time_params, |
| 614 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); | 619 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); |
| 615 | 620 |
| 616 if (pad_bytes) { | 621 if (pad_bytes) { |
| 617 char padding[4] = {0}; | 622 char padding[4] = {0}; |
| 618 DCHECK_LE(pad_bytes, 4); | 623 DCHECK_LE(pad_bytes, 4); |
| 619 memcpy(buffer->data() + data.size(), padding, pad_bytes); | 624 memcpy(buffer.second->data() + data.size(), padding, pad_bytes); |
| 620 } | 625 } |
| 621 WriteOrQueue(buffer); | 626 WriteOrQueue(buffer); |
| 622 | 627 |
| 623 if (dump_outgoing_rtp_packet_) | 628 if (dump_outgoing_rtp_packet_) |
| 624 DumpRtpPacket(buffer->data(), data.size(), false); | 629 DumpRtpPacket(buffer.second->data(), data.size(), false); |
| 625 } | 630 } |
| 626 | 631 |
| 627 int P2PSocketHostStunTcp::GetExpectedPacketSize( | 632 int P2PSocketHostStunTcp::GetExpectedPacketSize( |
| 628 const char* data, int len, int* pad_bytes) { | 633 const char* data, int len, int* pad_bytes) { |
| 629 DCHECK_LE(kTurnChannelDataHeaderSize, len); | 634 DCHECK_LE(kTurnChannelDataHeaderSize, len); |
| 630 // Both stun and turn had length at offset 2. | 635 // Both stun and turn had length at offset 2. |
| 631 int packet_size = base::NetToHost16( | 636 int packet_size = base::NetToHost16( |
| 632 *reinterpret_cast<const uint16_t*>(data + kPacketLengthOffset)); | 637 *reinterpret_cast<const uint16_t*>(data + kPacketLengthOffset)); |
| 633 | 638 |
| 634 // Get packet type (STUN or TURN). | 639 // Get packet type (STUN or TURN). |
| 635 uint16_t msg_type = | 640 uint16_t msg_type = |
| 636 base::NetToHost16(*reinterpret_cast<const uint16_t*>(data)); | 641 base::NetToHost16(*reinterpret_cast<const uint16_t*>(data)); |
| 637 | 642 |
| 638 *pad_bytes = 0; | 643 *pad_bytes = 0; |
| 639 // Add heder length to packet length. | 644 // Add heder length to packet length. |
| 640 if ((msg_type & 0xC000) == 0) { | 645 if ((msg_type & 0xC000) == 0) { |
| 641 packet_size += kStunHeaderSize; | 646 packet_size += kStunHeaderSize; |
| 642 } else { | 647 } else { |
| 643 packet_size += kTurnChannelDataHeaderSize; | 648 packet_size += kTurnChannelDataHeaderSize; |
| 644 // Calculate any padding if present. | 649 // Calculate any padding if present. |
| 645 if (packet_size % 4) | 650 if (packet_size % 4) |
| 646 *pad_bytes = 4 - packet_size % 4; | 651 *pad_bytes = 4 - packet_size % 4; |
| 647 } | 652 } |
| 648 return packet_size; | 653 return packet_size; |
| 649 } | 654 } |
| 650 | 655 |
| 651 } // namespace content | 656 } // namespace content |
| OLD | NEW |