 Chromium Code Reviews
 Chromium Code Reviews Issue 1823503002:
  Reland Use CopyOnWriteBuffer instead of Buffer to avoid unnecessary copies.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 1823503002:
  Reland Use CopyOnWriteBuffer instead of Buffer to avoid unnecessary copies.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 
| 3 * | 3 * | 
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license | 
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source | 
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found | 
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may | 
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. | 
| 9 */ | 9 */ | 
| 10 | 10 | 
| 11 #include "webrtc/media/sctp/sctpdataengine.h" | 11 #include "webrtc/media/sctp/sctpdataengine.h" | 
| 12 | 12 | 
| 13 #include <stdarg.h> | 13 #include <stdarg.h> | 
| 14 #include <stdio.h> | 14 #include <stdio.h> | 
| 15 | 15 | 
| 16 #include <memory> | 16 #include <memory> | 
| 17 #include <sstream> | 17 #include <sstream> | 
| 18 #include <vector> | 18 #include <vector> | 
| 19 | 19 | 
| 20 #include "usrsctplib/usrsctp.h" | 20 #include "usrsctplib/usrsctp.h" | 
| 21 #include "webrtc/base/arraysize.h" | 21 #include "webrtc/base/arraysize.h" | 
| 22 #include "webrtc/base/buffer.h" | 22 #include "webrtc/base/copyonwritebuffer.h" | 
| 23 #include "webrtc/base/helpers.h" | 23 #include "webrtc/base/helpers.h" | 
| 24 #include "webrtc/base/logging.h" | 24 #include "webrtc/base/logging.h" | 
| 25 #include "webrtc/base/safe_conversions.h" | 25 #include "webrtc/base/safe_conversions.h" | 
| 26 #include "webrtc/media/base/codec.h" | 26 #include "webrtc/media/base/codec.h" | 
| 27 #include "webrtc/media/base/mediaconstants.h" | 27 #include "webrtc/media/base/mediaconstants.h" | 
| 28 #include "webrtc/media/base/streamparams.h" | 28 #include "webrtc/media/base/streamparams.h" | 
| 29 | 29 | 
| 30 namespace { | 30 namespace { | 
| 31 typedef cricket::SctpDataMediaChannel::StreamSet StreamSet; | 31 typedef cricket::SctpDataMediaChannel::StreamSet StreamSet; | 
| 32 // Returns a comma-separated, human-readable list of the stream IDs in 's' | 32 // Returns a comma-separated, human-readable list of the stream IDs in 's' | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 } else { | 82 } else { | 
| 83 result << array[i]; | 83 result << array[i]; | 
| 84 } | 84 } | 
| 85 } | 85 } | 
| 86 return result.str(); | 86 return result.str(); | 
| 87 } | 87 } | 
| 88 } // namespace | 88 } // namespace | 
| 89 | 89 | 
| 90 namespace cricket { | 90 namespace cricket { | 
| 91 typedef rtc::ScopedMessageData<SctpInboundPacket> InboundPacketMessage; | 91 typedef rtc::ScopedMessageData<SctpInboundPacket> InboundPacketMessage; | 
| 92 typedef rtc::ScopedMessageData<rtc::Buffer> OutboundPacketMessage; | 92 typedef rtc::ScopedMessageData<rtc::CopyOnWriteBuffer> OutboundPacketMessage; | 
| 93 | 93 | 
| 94 // The biggest SCTP packet. Starting from a 'safe' wire MTU value of 1280, | 94 // The biggest SCTP packet. Starting from a 'safe' wire MTU value of 1280, | 
| 95 // take off 80 bytes for DTLS/TURN/TCP/IP overhead. | 95 // take off 80 bytes for DTLS/TURN/TCP/IP overhead. | 
| 96 static const size_t kSctpMtu = 1200; | 96 static const size_t kSctpMtu = 1200; | 
| 97 | 97 | 
| 98 // The size of the SCTP association send buffer. 256kB, the usrsctp default. | 98 // The size of the SCTP association send buffer. 256kB, the usrsctp default. | 
| 99 static const int kSendBufferSize = 262144; | 99 static const int kSendBufferSize = 262144; | 
| 100 enum { | 100 enum { | 
| 101 MSG_SCTPINBOUNDPACKET = 1, // MessageData is SctpInboundPacket | 101 MSG_SCTPINBOUNDPACKET = 1, // MessageData is SctpInboundPacket | 
| 102 MSG_SCTPOUTBOUNDPACKET = 2, // MessageData is rtc:Buffer | 102 MSG_SCTPOUTBOUNDPACKET = 2, // MessageData is rtc:Buffer | 
| 103 }; | 103 }; | 
| 104 | 104 | 
| 105 struct SctpInboundPacket { | 105 struct SctpInboundPacket { | 
| 106 rtc::Buffer buffer; | 106 rtc::CopyOnWriteBuffer buffer; | 
| 107 ReceiveDataParams params; | 107 ReceiveDataParams params; | 
| 108 // The |flags| parameter is used by SCTP to distinguish notification packets | 108 // The |flags| parameter is used by SCTP to distinguish notification packets | 
| 109 // from other types of packets. | 109 // from other types of packets. | 
| 110 int flags; | 110 int flags; | 
| 111 }; | 111 }; | 
| 112 | 112 | 
| 113 // Helper for logging SCTP messages. | 113 // Helper for logging SCTP messages. | 
| 114 static void debug_sctp_printf(const char *format, ...) { | 114 static void debug_sctp_printf(const char *format, ...) { | 
| 115 char s[255]; | 115 char s[255]; | 
| 116 va_list ap; | 116 va_list ap; | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 case SctpDataMediaChannel::PPID_NONE: | 158 case SctpDataMediaChannel::PPID_NONE: | 
| 159 *dest = cricket::DMT_NONE; | 159 *dest = cricket::DMT_NONE; | 
| 160 return true; | 160 return true; | 
| 161 | 161 | 
| 162 default: | 162 default: | 
| 163 return false; | 163 return false; | 
| 164 } | 164 } | 
| 165 } | 165 } | 
| 166 | 166 | 
| 167 // Log the packet in text2pcap format, if log level is at LS_VERBOSE. | 167 // Log the packet in text2pcap format, if log level is at LS_VERBOSE. | 
| 168 static void VerboseLogPacket(void *data, size_t length, int direction) { | 168 static void VerboseLogPacket(const void *data, size_t length, int direction) { | 
| 169 if (LOG_CHECK_LEVEL(LS_VERBOSE) && length > 0) { | 169 if (LOG_CHECK_LEVEL(LS_VERBOSE) && length > 0) { | 
| 170 char *dump_buf; | 170 char *dump_buf; | 
| 171 // Some downstream project uses an older version of usrsctp that expects | |
| 172 // a non-const "void*" as first parameter when dumping the packet, so we | |
| 173 // need to cast the const away here to avoid a compiler error. | |
| 171 if ((dump_buf = usrsctp_dumppacket( | 174 if ((dump_buf = usrsctp_dumppacket( | 
| 172 data, length, direction)) != NULL) { | 175 const_cast<void*>(data), length, direction)) != NULL) { | 
| 
joachim
2016/03/20 10:14:10
This is the change compared to https://codereview.
 | |
| 173 LOG(LS_VERBOSE) << dump_buf; | 176 LOG(LS_VERBOSE) << dump_buf; | 
| 174 usrsctp_freedumpbuffer(dump_buf); | 177 usrsctp_freedumpbuffer(dump_buf); | 
| 175 } | 178 } | 
| 176 } | 179 } | 
| 177 } | 180 } | 
| 178 | 181 | 
| 179 // This is the callback usrsctp uses when there's data to send on the network | 182 // This is the callback usrsctp uses when there's data to send on the network | 
| 180 // that has been wrapped appropriatly for the SCTP protocol. | 183 // that has been wrapped appropriatly for the SCTP protocol. | 
| 181 static int OnSctpOutboundPacket(void* addr, void* data, size_t length, | 184 static int OnSctpOutboundPacket(void* addr, void* data, size_t length, | 
| 182 uint8_t tos, uint8_t set_df) { | 185 uint8_t tos, uint8_t set_df) { | 
| 183 SctpDataMediaChannel* channel = static_cast<SctpDataMediaChannel*>(addr); | 186 SctpDataMediaChannel* channel = static_cast<SctpDataMediaChannel*>(addr); | 
| 184 LOG(LS_VERBOSE) << "global OnSctpOutboundPacket():" | 187 LOG(LS_VERBOSE) << "global OnSctpOutboundPacket():" | 
| 185 << "addr: " << addr << "; length: " << length | 188 << "addr: " << addr << "; length: " << length | 
| 186 << "; tos: " << std::hex << static_cast<int>(tos) | 189 << "; tos: " << std::hex << static_cast<int>(tos) | 
| 187 << "; set_df: " << std::hex << static_cast<int>(set_df); | 190 << "; set_df: " << std::hex << static_cast<int>(set_df); | 
| 188 | 191 | 
| 189 VerboseLogPacket(addr, length, SCTP_DUMP_OUTBOUND); | 192 VerboseLogPacket(addr, length, SCTP_DUMP_OUTBOUND); | 
| 190 // Note: We have to copy the data; the caller will delete it. | 193 // Note: We have to copy the data; the caller will delete it. | 
| 191 auto* msg = new OutboundPacketMessage( | 194 auto* msg = new OutboundPacketMessage( | 
| 192 new rtc::Buffer(reinterpret_cast<uint8_t*>(data), length)); | 195 new rtc::CopyOnWriteBuffer(reinterpret_cast<uint8_t*>(data), length)); | 
| 193 channel->worker_thread()->Post(channel, MSG_SCTPOUTBOUNDPACKET, msg); | 196 channel->worker_thread()->Post(channel, MSG_SCTPOUTBOUNDPACKET, msg); | 
| 194 return 0; | 197 return 0; | 
| 195 } | 198 } | 
| 196 | 199 | 
| 197 // This is the callback called from usrsctp when data has been received, after | 200 // This is the callback called from usrsctp when data has been received, after | 
| 198 // a packet has been interpreted and parsed by usrsctp and found to contain | 201 // a packet has been interpreted and parsed by usrsctp and found to contain | 
| 199 // payload data. It is called by a usrsctp thread. It is assumed this function | 202 // payload data. It is called by a usrsctp thread. It is assumed this function | 
| 200 // will free the memory used by 'data'. | 203 // will free the memory used by 'data'. | 
| 201 static int OnSctpInboundPacket(struct socket* sock, union sctp_sockstore addr, | 204 static int OnSctpInboundPacket(struct socket* sock, union sctp_sockstore addr, | 
| 202 void* data, size_t length, | 205 void* data, size_t length, | 
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 574 | 577 | 
| 575 bool SctpDataMediaChannel::RemoveRecvStream(uint32_t ssrc) { | 578 bool SctpDataMediaChannel::RemoveRecvStream(uint32_t ssrc) { | 
| 576 // SCTP DataChannels are always bi-directional and calling RemoveSendStream | 579 // SCTP DataChannels are always bi-directional and calling RemoveSendStream | 
| 577 // will disable both sending and receiving on the stream. So RemoveRecvStream | 580 // will disable both sending and receiving on the stream. So RemoveRecvStream | 
| 578 // is a no-op. | 581 // is a no-op. | 
| 579 return true; | 582 return true; | 
| 580 } | 583 } | 
| 581 | 584 | 
| 582 bool SctpDataMediaChannel::SendData( | 585 bool SctpDataMediaChannel::SendData( | 
| 583 const SendDataParams& params, | 586 const SendDataParams& params, | 
| 584 const rtc::Buffer& payload, | 587 const rtc::CopyOnWriteBuffer& payload, | 
| 585 SendDataResult* result) { | 588 SendDataResult* result) { | 
| 586 if (result) { | 589 if (result) { | 
| 587 // Preset |result| to assume an error. If SendData succeeds, we'll | 590 // Preset |result| to assume an error. If SendData succeeds, we'll | 
| 588 // overwrite |*result| once more at the end. | 591 // overwrite |*result| once more at the end. | 
| 589 *result = SDR_ERROR; | 592 *result = SDR_ERROR; | 
| 590 } | 593 } | 
| 591 | 594 | 
| 592 if (!sending_) { | 595 if (!sending_) { | 
| 593 LOG(LS_WARNING) << debug_name_ << "->SendData(...): " | 596 LOG(LS_WARNING) << debug_name_ << "->SendData(...): " | 
| 594 << "Not sending packet with ssrc=" << params.ssrc | 597 << "Not sending packet with ssrc=" << params.ssrc | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 } | 647 } | 
| 645 if (result) { | 648 if (result) { | 
| 646 // Only way out now is success. | 649 // Only way out now is success. | 
| 647 *result = SDR_SUCCESS; | 650 *result = SDR_SUCCESS; | 
| 648 } | 651 } | 
| 649 return true; | 652 return true; | 
| 650 } | 653 } | 
| 651 | 654 | 
| 652 // Called by network interface when a packet has been received. | 655 // Called by network interface when a packet has been received. | 
| 653 void SctpDataMediaChannel::OnPacketReceived( | 656 void SctpDataMediaChannel::OnPacketReceived( | 
| 654 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { | 657 rtc::CopyOnWriteBuffer* packet, const rtc::PacketTime& packet_time) { | 
| 655 RTC_DCHECK(rtc::Thread::Current() == worker_thread_); | 658 RTC_DCHECK(rtc::Thread::Current() == worker_thread_); | 
| 656 LOG(LS_VERBOSE) << debug_name_ << "->OnPacketReceived(...): " | 659 LOG(LS_VERBOSE) << debug_name_ << "->OnPacketReceived(...): " | 
| 657 << " length=" << packet->size() << ", sending: " << sending_; | 660 << " length=" << packet->size() << ", sending: " << sending_; | 
| 658 // Only give receiving packets to usrsctp after if connected. This enables two | 661 // Only give receiving packets to usrsctp after if connected. This enables two | 
| 659 // peers to each make a connect call, but for them not to receive an INIT | 662 // peers to each make a connect call, but for them not to receive an INIT | 
| 660 // packet before they have called connect; least the last receiver of the INIT | 663 // packet before they have called connect; least the last receiver of the INIT | 
| 661 // packet will have called connect, and a connection will be established. | 664 // packet will have called connect, and a connection will be established. | 
| 662 if (sending_) { | 665 if (sending_) { | 
| 663 // Pass received packet to SCTP stack. Once processed by usrsctp, the data | 666 // Pass received packet to SCTP stack. Once processed by usrsctp, the data | 
| 664 // will be will be given to the global OnSctpInboundData, and then, | 667 // will be will be given to the global OnSctpInboundData, and then, | 
| 665 // marshalled by a Post and handled with OnMessage. | 668 // marshalled by a Post and handled with OnMessage. | 
| 666 VerboseLogPacket(packet->data(), packet->size(), SCTP_DUMP_INBOUND); | 669 VerboseLogPacket(packet->cdata(), packet->size(), SCTP_DUMP_INBOUND); | 
| 667 usrsctp_conninput(this, packet->data(), packet->size(), 0); | 670 usrsctp_conninput(this, packet->cdata(), packet->size(), 0); | 
| 668 } else { | 671 } else { | 
| 669 // TODO(ldixon): Consider caching the packet for very slightly better | 672 // TODO(ldixon): Consider caching the packet for very slightly better | 
| 670 // reliability. | 673 // reliability. | 
| 671 } | 674 } | 
| 672 } | 675 } | 
| 673 | 676 | 
| 674 void SctpDataMediaChannel::OnInboundPacketFromSctpToChannel( | 677 void SctpDataMediaChannel::OnInboundPacketFromSctpToChannel( | 
| 675 SctpInboundPacket* packet) { | 678 SctpInboundPacket* packet) { | 
| 676 LOG(LS_VERBOSE) << debug_name_ << "->OnInboundPacketFromSctpToChannel(...): " | 679 LOG(LS_VERBOSE) << debug_name_ << "->OnInboundPacketFromSctpToChannel(...): " | 
| 677 << "Received SCTP data:" | 680 << "Received SCTP data:" | 
| 678 << " ssrc=" << packet->params.ssrc | 681 << " ssrc=" << packet->params.ssrc | 
| 679 << " notification: " << (packet->flags & MSG_NOTIFICATION) | 682 << " notification: " << (packet->flags & MSG_NOTIFICATION) | 
| 680 << " length=" << packet->buffer.size(); | 683 << " length=" << packet->buffer.size(); | 
| 681 // Sending a packet with data == NULL (no data) is SCTPs "close the | 684 // Sending a packet with data == NULL (no data) is SCTPs "close the | 
| 682 // connection" message. This sets sock_ = NULL; | 685 // connection" message. This sets sock_ = NULL; | 
| 683 if (!packet->buffer.size() || !packet->buffer.data()) { | 686 if (!packet->buffer.size() || !packet->buffer.data()) { | 
| 684 LOG(LS_INFO) << debug_name_ << "->OnInboundPacketFromSctpToChannel(...): " | 687 LOG(LS_INFO) << debug_name_ << "->OnInboundPacketFromSctpToChannel(...): " | 
| 685 "No data, closing."; | 688 "No data, closing."; | 
| 686 return; | 689 return; | 
| 687 } | 690 } | 
| 688 if (packet->flags & MSG_NOTIFICATION) { | 691 if (packet->flags & MSG_NOTIFICATION) { | 
| 689 OnNotificationFromSctp(&packet->buffer); | 692 OnNotificationFromSctp(packet->buffer); | 
| 690 } else { | 693 } else { | 
| 691 OnDataFromSctpToChannel(packet->params, &packet->buffer); | 694 OnDataFromSctpToChannel(packet->params, packet->buffer); | 
| 692 } | 695 } | 
| 693 } | 696 } | 
| 694 | 697 | 
| 695 void SctpDataMediaChannel::OnDataFromSctpToChannel( | 698 void SctpDataMediaChannel::OnDataFromSctpToChannel( | 
| 696 const ReceiveDataParams& params, rtc::Buffer* buffer) { | 699 const ReceiveDataParams& params, const rtc::CopyOnWriteBuffer& buffer) { | 
| 697 if (receiving_) { | 700 if (receiving_) { | 
| 698 LOG(LS_VERBOSE) << debug_name_ << "->OnDataFromSctpToChannel(...): " | 701 LOG(LS_VERBOSE) << debug_name_ << "->OnDataFromSctpToChannel(...): " | 
| 699 << "Posting with length: " << buffer->size() | 702 << "Posting with length: " << buffer.size() | 
| 700 << " on stream " << params.ssrc; | 703 << " on stream " << params.ssrc; | 
| 701 // Reports all received messages to upper layers, no matter whether the sid | 704 // Reports all received messages to upper layers, no matter whether the sid | 
| 702 // is known. | 705 // is known. | 
| 703 SignalDataReceived(params, buffer->data<char>(), buffer->size()); | 706 SignalDataReceived(params, buffer.data<char>(), buffer.size()); | 
| 704 } else { | 707 } else { | 
| 705 LOG(LS_WARNING) << debug_name_ << "->OnDataFromSctpToChannel(...): " | 708 LOG(LS_WARNING) << debug_name_ << "->OnDataFromSctpToChannel(...): " | 
| 706 << "Not receiving packet with sid=" << params.ssrc | 709 << "Not receiving packet with sid=" << params.ssrc | 
| 707 << " len=" << buffer->size() << " before SetReceive(true)."; | 710 << " len=" << buffer.size() << " before SetReceive(true)."; | 
| 708 } | 711 } | 
| 709 } | 712 } | 
| 710 | 713 | 
| 711 bool SctpDataMediaChannel::AddStream(const StreamParams& stream) { | 714 bool SctpDataMediaChannel::AddStream(const StreamParams& stream) { | 
| 712 if (!stream.has_ssrcs()) { | 715 if (!stream.has_ssrcs()) { | 
| 713 return false; | 716 return false; | 
| 714 } | 717 } | 
| 715 | 718 | 
| 716 const uint32_t ssrc = stream.first_ssrc(); | 719 const uint32_t ssrc = stream.first_ssrc(); | 
| 717 if (ssrc >= cricket::kMaxSctpSid) { | 720 if (ssrc >= cricket::kMaxSctpSid) { | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 760 // SendQueuedStreamResets(). | 763 // SendQueuedStreamResets(). | 
| 761 queued_reset_streams_.insert(ssrc); | 764 queued_reset_streams_.insert(ssrc); | 
| 762 | 765 | 
| 763 // Signal our stream-reset logic that it should try to send now, if it can. | 766 // Signal our stream-reset logic that it should try to send now, if it can. | 
| 764 SendQueuedStreamResets(); | 767 SendQueuedStreamResets(); | 
| 765 | 768 | 
| 766 // The stream will actually get removed when we get the acknowledgment. | 769 // The stream will actually get removed when we get the acknowledgment. | 
| 767 return true; | 770 return true; | 
| 768 } | 771 } | 
| 769 | 772 | 
| 770 void SctpDataMediaChannel::OnNotificationFromSctp(rtc::Buffer* buffer) { | 773 void SctpDataMediaChannel::OnNotificationFromSctp( | 
| 774 const rtc::CopyOnWriteBuffer& buffer) { | |
| 771 const sctp_notification& notification = | 775 const sctp_notification& notification = | 
| 772 reinterpret_cast<const sctp_notification&>(*buffer->data()); | 776 reinterpret_cast<const sctp_notification&>(*buffer.data()); | 
| 773 ASSERT(notification.sn_header.sn_length == buffer->size()); | 777 ASSERT(notification.sn_header.sn_length == buffer.size()); | 
| 774 | 778 | 
| 775 // TODO(ldixon): handle notifications appropriately. | 779 // TODO(ldixon): handle notifications appropriately. | 
| 776 switch (notification.sn_header.sn_type) { | 780 switch (notification.sn_header.sn_type) { | 
| 777 case SCTP_ASSOC_CHANGE: | 781 case SCTP_ASSOC_CHANGE: | 
| 778 LOG(LS_VERBOSE) << "SCTP_ASSOC_CHANGE"; | 782 LOG(LS_VERBOSE) << "SCTP_ASSOC_CHANGE"; | 
| 779 OnNotificationAssocChange(notification.sn_assoc_change); | 783 OnNotificationAssocChange(notification.sn_assoc_change); | 
| 780 break; | 784 break; | 
| 781 case SCTP_REMOTE_ERROR: | 785 case SCTP_REMOTE_ERROR: | 
| 782 LOG(LS_INFO) << "SCTP_REMOTE_ERROR"; | 786 LOG(LS_INFO) << "SCTP_REMOTE_ERROR"; | 
| 783 break; | 787 break; | 
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 956 &remote_port_); | 960 &remote_port_); | 
| 957 } | 961 } | 
| 958 | 962 | 
| 959 bool SctpDataMediaChannel::SetRecvCodecs(const std::vector<DataCodec>& codecs) { | 963 bool SctpDataMediaChannel::SetRecvCodecs(const std::vector<DataCodec>& codecs) { | 
| 960 return GetCodecIntParameter( | 964 return GetCodecIntParameter( | 
| 961 codecs, kGoogleSctpDataCodecId, kGoogleSctpDataCodecName, kCodecParamPort, | 965 codecs, kGoogleSctpDataCodecId, kGoogleSctpDataCodecName, kCodecParamPort, | 
| 962 &local_port_); | 966 &local_port_); | 
| 963 } | 967 } | 
| 964 | 968 | 
| 965 void SctpDataMediaChannel::OnPacketFromSctpToNetwork( | 969 void SctpDataMediaChannel::OnPacketFromSctpToNetwork( | 
| 966 rtc::Buffer* buffer) { | 970 rtc::CopyOnWriteBuffer* buffer) { | 
| 967 // usrsctp seems to interpret the MTU we give it strangely -- it seems to | 971 // usrsctp seems to interpret the MTU we give it strangely -- it seems to | 
| 968 // give us back packets bigger than that MTU, if only by a fixed amount. | 972 // give us back packets bigger than that MTU, if only by a fixed amount. | 
| 969 // This is that amount that we've observed. | 973 // This is that amount that we've observed. | 
| 970 const int kSctpOverhead = 76; | 974 const int kSctpOverhead = 76; | 
| 971 if (buffer->size() > (kSctpOverhead + kSctpMtu)) { | 975 if (buffer->size() > (kSctpOverhead + kSctpMtu)) { | 
| 972 LOG(LS_ERROR) << debug_name_ << "->OnPacketFromSctpToNetwork(...): " | 976 LOG(LS_ERROR) << debug_name_ << "->OnPacketFromSctpToNetwork(...): " | 
| 973 << "SCTP seems to have made a packet that is bigger " | 977 << "SCTP seems to have made a packet that is bigger " | 
| 974 << "than its official MTU: " << buffer->size() | 978 << "than its official MTU: " << buffer->size() | 
| 975 << " vs max of " << kSctpMtu | 979 << " vs max of " << kSctpMtu | 
| 976 << " even after adding " << kSctpOverhead | 980 << " even after adding " << kSctpOverhead | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1029 } | 1033 } | 
| 1030 case MSG_SCTPOUTBOUNDPACKET: { | 1034 case MSG_SCTPOUTBOUNDPACKET: { | 
| 1031 std::unique_ptr<OutboundPacketMessage> pdata( | 1035 std::unique_ptr<OutboundPacketMessage> pdata( | 
| 1032 static_cast<OutboundPacketMessage*>(msg->pdata)); | 1036 static_cast<OutboundPacketMessage*>(msg->pdata)); | 
| 1033 OnPacketFromSctpToNetwork(pdata->data().get()); | 1037 OnPacketFromSctpToNetwork(pdata->data().get()); | 
| 1034 break; | 1038 break; | 
| 1035 } | 1039 } | 
| 1036 } | 1040 } | 
| 1037 } | 1041 } | 
| 1038 } // namespace cricket | 1042 } // namespace cricket | 
| OLD | NEW |