| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 bool IsPseudoTlsClientSocket(content::P2PSocketType type) { | 43 bool IsPseudoTlsClientSocket(content::P2PSocketType type) { |
| 44 return (type == content::P2P_SOCKET_SSLTCP_CLIENT || | 44 return (type == content::P2P_SOCKET_SSLTCP_CLIENT || |
| 45 type == content::P2P_SOCKET_STUN_SSLTCP_CLIENT); | 45 type == content::P2P_SOCKET_STUN_SSLTCP_CLIENT); |
| 46 } | 46 } |
| 47 | 47 |
| 48 } // namespace | 48 } // namespace |
| 49 | 49 |
| 50 namespace content { | 50 namespace content { |
| 51 | 51 |
| 52 P2PSocketHostTcp::SendBuffer::SendBuffer() : rtc_packet_id(-1) {} |
| 53 P2PSocketHostTcp::SendBuffer::SendBuffer( |
| 54 int32_t rtc_packet_id, |
| 55 scoped_refptr<net::DrainableIOBuffer> buffer) |
| 56 : rtc_packet_id(rtc_packet_id), buffer(buffer) {} |
| 57 P2PSocketHostTcp::SendBuffer::SendBuffer(const SendBuffer& rhs) |
| 58 : rtc_packet_id(rhs.rtc_packet_id), buffer(rhs.buffer) {} |
| 59 P2PSocketHostTcp::SendBuffer::~SendBuffer() {} |
| 60 |
| 52 P2PSocketHostTcpBase::P2PSocketHostTcpBase( | 61 P2PSocketHostTcpBase::P2PSocketHostTcpBase( |
| 53 IPC::Sender* message_sender, | 62 IPC::Sender* message_sender, |
| 54 int socket_id, | 63 int socket_id, |
| 55 P2PSocketType type, | 64 P2PSocketType type, |
| 56 net::URLRequestContextGetter* url_context) | 65 net::URLRequestContextGetter* url_context) |
| 57 : P2PSocketHost(message_sender, socket_id, P2PSocketHost::TCP), | 66 : P2PSocketHost(message_sender, socket_id, P2PSocketHost::TCP), |
| 58 write_pending_(false), | 67 write_pending_(false), |
| 59 connected_(false), | 68 connected_(false), |
| 60 type_(type), | 69 type_(type), |
| 61 url_context_(url_context) { | 70 url_context_(url_context) { |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 LOG(ERROR) << "Page tried to send a data packet to " << to.ToString() | 385 LOG(ERROR) << "Page tried to send a data packet to " << to.ToString() |
| 377 << " before STUN binding is finished."; | 386 << " before STUN binding is finished."; |
| 378 OnError(); | 387 OnError(); |
| 379 return; | 388 return; |
| 380 } | 389 } |
| 381 } | 390 } |
| 382 | 391 |
| 383 DoSend(to, data, options); | 392 DoSend(to, data, options); |
| 384 } | 393 } |
| 385 | 394 |
| 386 void P2PSocketHostTcpBase::WriteOrQueue( | 395 void P2PSocketHostTcpBase::WriteOrQueue(SendBuffer& send_buffer) { |
| 387 scoped_refptr<net::DrainableIOBuffer>& buffer) { | |
| 388 IncrementTotalSentPackets(); | 396 IncrementTotalSentPackets(); |
| 389 if (write_buffer_.get()) { | 397 if (write_buffer_.buffer.get()) { |
| 390 write_queue_.push(buffer); | 398 write_queue_.push(send_buffer); |
| 391 IncrementDelayedPackets(); | 399 IncrementDelayedPackets(); |
| 392 IncrementDelayedBytes(buffer->size()); | 400 IncrementDelayedBytes(send_buffer.buffer->size()); |
| 393 return; | 401 return; |
| 394 } | 402 } |
| 395 | 403 |
| 396 write_buffer_ = buffer; | 404 write_buffer_ = send_buffer; |
| 397 DoWrite(); | 405 DoWrite(); |
| 398 } | 406 } |
| 399 | 407 |
| 400 void P2PSocketHostTcpBase::DoWrite() { | 408 void P2PSocketHostTcpBase::DoWrite() { |
| 401 while (write_buffer_.get() && state_ == STATE_OPEN && !write_pending_) { | 409 while (write_buffer_.buffer.get() && state_ == STATE_OPEN && |
| 410 !write_pending_) { |
| 402 int result = socket_->Write( | 411 int result = socket_->Write( |
| 403 write_buffer_.get(), | 412 write_buffer_.buffer.get(), write_buffer_.buffer->BytesRemaining(), |
| 404 write_buffer_->BytesRemaining(), | |
| 405 base::Bind(&P2PSocketHostTcp::OnWritten, base::Unretained(this))); | 413 base::Bind(&P2PSocketHostTcp::OnWritten, base::Unretained(this))); |
| 406 HandleWriteResult(result); | 414 HandleWriteResult(result); |
| 407 } | 415 } |
| 408 } | 416 } |
| 409 | 417 |
| 410 void P2PSocketHostTcpBase::OnWritten(int result) { | 418 void P2PSocketHostTcpBase::OnWritten(int result) { |
| 411 DCHECK(write_pending_); | 419 DCHECK(write_pending_); |
| 412 DCHECK_NE(result, net::ERR_IO_PENDING); | 420 DCHECK_NE(result, net::ERR_IO_PENDING); |
| 413 | 421 |
| 414 write_pending_ = false; | 422 write_pending_ = false; |
| 415 HandleWriteResult(result); | 423 HandleWriteResult(result); |
| 416 DoWrite(); | 424 DoWrite(); |
| 417 } | 425 } |
| 418 | 426 |
| 419 void P2PSocketHostTcpBase::HandleWriteResult(int result) { | 427 void P2PSocketHostTcpBase::HandleWriteResult(int result) { |
| 420 DCHECK(write_buffer_.get()); | 428 DCHECK(write_buffer_.buffer.get()); |
| 421 if (result >= 0) { | 429 if (result >= 0) { |
| 422 write_buffer_->DidConsume(result); | 430 write_buffer_.buffer->DidConsume(result); |
| 423 if (write_buffer_->BytesRemaining() == 0) { | 431 if (write_buffer_.buffer->BytesRemaining() == 0) { |
| 424 message_sender_->Send( | 432 base::TimeTicks send_time = base::TimeTicks::Now(); |
| 425 new P2PMsg_OnSendComplete(id_, P2PSendPacketMetrics())); | 433 message_sender_->Send(new P2PMsg_OnSendComplete( |
| 434 id_, |
| 435 P2PSendPacketMetrics(0, write_buffer_.rtc_packet_id, send_time))); |
| 426 if (write_queue_.empty()) { | 436 if (write_queue_.empty()) { |
| 427 write_buffer_ = nullptr; | 437 write_buffer_.buffer = nullptr; |
| 438 write_buffer_.rtc_packet_id = -1; |
| 428 } else { | 439 } else { |
| 429 write_buffer_ = write_queue_.front(); | 440 write_buffer_ = write_queue_.front(); |
| 430 write_queue_.pop(); | 441 write_queue_.pop(); |
| 431 // Update how many bytes are still waiting to be sent. | 442 // Update how many bytes are still waiting to be sent. |
| 432 DecrementDelayedBytes(write_buffer_->size()); | 443 DecrementDelayedBytes(write_buffer_.buffer->size()); |
| 433 } | 444 } |
| 434 } | 445 } |
| 435 } else if (result == net::ERR_IO_PENDING) { | 446 } else if (result == net::ERR_IO_PENDING) { |
| 436 write_pending_ = true; | 447 write_pending_ = true; |
| 437 } else { | 448 } else { |
| 438 ReportSocketError(result, "WebRTC.ICE.TcpSocketWriteErrorCode"); | 449 ReportSocketError(result, "WebRTC.ICE.TcpSocketWriteErrorCode"); |
| 439 | 450 |
| 440 LOG(ERROR) << "Error when sending data in TCP socket: " << result; | 451 LOG(ERROR) << "Error when sending data in TCP socket: " << result; |
| 441 OnError(); | 452 OnError(); |
| 442 } | 453 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 std::vector<char> data(cur, cur + packet_size); | 534 std::vector<char> data(cur, cur + packet_size); |
| 524 OnPacket(data); | 535 OnPacket(data); |
| 525 consumed += packet_size; | 536 consumed += packet_size; |
| 526 return consumed; | 537 return consumed; |
| 527 } | 538 } |
| 528 | 539 |
| 529 void P2PSocketHostTcp::DoSend(const net::IPEndPoint& to, | 540 void P2PSocketHostTcp::DoSend(const net::IPEndPoint& to, |
| 530 const std::vector<char>& data, | 541 const std::vector<char>& data, |
| 531 const rtc::PacketOptions& options) { | 542 const rtc::PacketOptions& options) { |
| 532 int size = kPacketHeaderSize + data.size(); | 543 int size = kPacketHeaderSize + data.size(); |
| 533 scoped_refptr<net::DrainableIOBuffer> buffer = | 544 SendBuffer send_buffer(options.packet_id, new net::DrainableIOBuffer( |
| 534 new net::DrainableIOBuffer(new net::IOBuffer(size), size); | 545 new net::IOBuffer(size), size)); |
| 535 *reinterpret_cast<uint16_t*>(buffer->data()) = base::HostToNet16(data.size()); | 546 *reinterpret_cast<uint16_t*>(send_buffer.buffer->data()) = |
| 536 memcpy(buffer->data() + kPacketHeaderSize, &data[0], data.size()); | 547 base::HostToNet16(data.size()); |
| 548 memcpy(send_buffer.buffer->data() + kPacketHeaderSize, &data[0], data.size()); |
| 537 | 549 |
| 538 cricket::ApplyPacketOptions( | 550 cricket::ApplyPacketOptions( |
| 539 reinterpret_cast<uint8_t*>(buffer->data()) + kPacketHeaderSize, | 551 reinterpret_cast<uint8_t*>(send_buffer.buffer->data()) + |
| 540 buffer->BytesRemaining() - kPacketHeaderSize, options.packet_time_params, | 552 kPacketHeaderSize, |
| 553 send_buffer.buffer->BytesRemaining() - kPacketHeaderSize, |
| 554 options.packet_time_params, |
| 541 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); | 555 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); |
| 542 | 556 |
| 543 WriteOrQueue(buffer); | 557 WriteOrQueue(send_buffer); |
| 544 } | 558 } |
| 545 | 559 |
| 546 // P2PSocketHostStunTcp | 560 // P2PSocketHostStunTcp |
| 547 P2PSocketHostStunTcp::P2PSocketHostStunTcp( | 561 P2PSocketHostStunTcp::P2PSocketHostStunTcp( |
| 548 IPC::Sender* message_sender, | 562 IPC::Sender* message_sender, |
| 549 int socket_id, | 563 int socket_id, |
| 550 P2PSocketType type, | 564 P2PSocketType type, |
| 551 net::URLRequestContextGetter* url_context) | 565 net::URLRequestContextGetter* url_context) |
| 552 : P2PSocketHostTcpBase(message_sender, socket_id, type, url_context) { | 566 : P2PSocketHostTcpBase(message_sender, socket_id, type, url_context) { |
| 553 DCHECK(type == P2P_SOCKET_STUN_TCP_CLIENT || | 567 DCHECK(type == P2P_SOCKET_STUN_TCP_CLIENT || |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 // Accepts only complete STUN/TURN packets. | 611 // Accepts only complete STUN/TURN packets. |
| 598 if (data.size() != expected_len) { | 612 if (data.size() != expected_len) { |
| 599 NOTREACHED(); | 613 NOTREACHED(); |
| 600 OnError(); | 614 OnError(); |
| 601 return; | 615 return; |
| 602 } | 616 } |
| 603 | 617 |
| 604 // Add any pad bytes to the total size. | 618 // Add any pad bytes to the total size. |
| 605 int size = data.size() + pad_bytes; | 619 int size = data.size() + pad_bytes; |
| 606 | 620 |
| 607 scoped_refptr<net::DrainableIOBuffer> buffer = | 621 SendBuffer send_buffer(options.packet_id, new net::DrainableIOBuffer( |
| 608 new net::DrainableIOBuffer(new net::IOBuffer(size), size); | 622 new net::IOBuffer(size), size)); |
| 609 memcpy(buffer->data(), &data[0], data.size()); | 623 memcpy(send_buffer.buffer->data(), &data[0], data.size()); |
| 610 | 624 |
| 611 cricket::ApplyPacketOptions( | 625 cricket::ApplyPacketOptions( |
| 612 reinterpret_cast<uint8_t*>(buffer->data()), data.size(), | 626 reinterpret_cast<uint8_t*>(send_buffer.buffer->data()), data.size(), |
| 613 options.packet_time_params, | 627 options.packet_time_params, |
| 614 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); | 628 (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); |
| 615 | 629 |
| 616 if (pad_bytes) { | 630 if (pad_bytes) { |
| 617 char padding[4] = {0}; | 631 char padding[4] = {0}; |
| 618 DCHECK_LE(pad_bytes, 4); | 632 DCHECK_LE(pad_bytes, 4); |
| 619 memcpy(buffer->data() + data.size(), padding, pad_bytes); | 633 memcpy(send_buffer.buffer->data() + data.size(), padding, pad_bytes); |
| 620 } | 634 } |
| 621 WriteOrQueue(buffer); | 635 WriteOrQueue(send_buffer); |
| 622 | 636 |
| 623 if (dump_outgoing_rtp_packet_) | 637 if (dump_outgoing_rtp_packet_) |
| 624 DumpRtpPacket(buffer->data(), data.size(), false); | 638 DumpRtpPacket(send_buffer.buffer->data(), data.size(), false); |
| 625 } | 639 } |
| 626 | 640 |
| 627 int P2PSocketHostStunTcp::GetExpectedPacketSize( | 641 int P2PSocketHostStunTcp::GetExpectedPacketSize( |
| 628 const char* data, int len, int* pad_bytes) { | 642 const char* data, int len, int* pad_bytes) { |
| 629 DCHECK_LE(kTurnChannelDataHeaderSize, len); | 643 DCHECK_LE(kTurnChannelDataHeaderSize, len); |
| 630 // Both stun and turn had length at offset 2. | 644 // Both stun and turn had length at offset 2. |
| 631 int packet_size = base::NetToHost16( | 645 int packet_size = base::NetToHost16( |
| 632 *reinterpret_cast<const uint16_t*>(data + kPacketLengthOffset)); | 646 *reinterpret_cast<const uint16_t*>(data + kPacketLengthOffset)); |
| 633 | 647 |
| 634 // Get packet type (STUN or TURN). | 648 // Get packet type (STUN or TURN). |
| 635 uint16_t msg_type = | 649 uint16_t msg_type = |
| 636 base::NetToHost16(*reinterpret_cast<const uint16_t*>(data)); | 650 base::NetToHost16(*reinterpret_cast<const uint16_t*>(data)); |
| 637 | 651 |
| 638 *pad_bytes = 0; | 652 *pad_bytes = 0; |
| 639 // Add heder length to packet length. | 653 // Add heder length to packet length. |
| 640 if ((msg_type & 0xC000) == 0) { | 654 if ((msg_type & 0xC000) == 0) { |
| 641 packet_size += kStunHeaderSize; | 655 packet_size += kStunHeaderSize; |
| 642 } else { | 656 } else { |
| 643 packet_size += kTurnChannelDataHeaderSize; | 657 packet_size += kTurnChannelDataHeaderSize; |
| 644 // Calculate any padding if present. | 658 // Calculate any padding if present. |
| 645 if (packet_size % 4) | 659 if (packet_size % 4) |
| 646 *pad_bytes = 4 - packet_size % 4; | 660 *pad_bytes = 4 - packet_size % 4; |
| 647 } | 661 } |
| 648 return packet_size; | 662 return packet_size; |
| 649 } | 663 } |
| 650 | 664 |
| 651 } // namespace content | 665 } // namespace content |
| OLD | NEW |