| 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 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "webrtc/base/copyonwritebuffer.h" | 22 #include "webrtc/base/copyonwritebuffer.h" |
| 23 #include "webrtc/base/criticalsection.h" | 23 #include "webrtc/base/criticalsection.h" |
| 24 #include "webrtc/base/helpers.h" | 24 #include "webrtc/base/helpers.h" |
| 25 #include "webrtc/base/logging.h" | 25 #include "webrtc/base/logging.h" |
| 26 #include "webrtc/base/safe_conversions.h" | 26 #include "webrtc/base/safe_conversions.h" |
| 27 #include "webrtc/media/base/codec.h" | 27 #include "webrtc/media/base/codec.h" |
| 28 #include "webrtc/media/base/mediaconstants.h" | 28 #include "webrtc/media/base/mediaconstants.h" |
| 29 #include "webrtc/media/base/streamparams.h" | 29 #include "webrtc/media/base/streamparams.h" |
| 30 | 30 |
| 31 namespace cricket { | 31 namespace cricket { |
| 32 // The biggest SCTP packet. Starting from a 'safe' wire MTU value of 1280, | 32 // The biggest SCTP packet. Starting from a 'safe' wire MTU value of 1280, |
| 33 // take off 80 bytes for DTLS/TURN/TCP/IP overhead. | 33 // take off 80 bytes for DTLS/TURN/TCP/IP overhead. |
| 34 static const size_t kSctpMtu = 1200; | 34 static constexpr size_t kSctpMtu = 1200; |
| 35 | 35 |
| 36 // The size of the SCTP association send buffer. 256kB, the usrsctp default. | 36 // The size of the SCTP association send buffer. 256kB, the usrsctp default. |
| 37 static const int kSendBufferSize = 262144; | 37 static constexpr int kSendBufferSize = 262144; |
| 38 | 38 |
| 39 struct SctpInboundPacket { | 39 struct SctpInboundPacket { |
| 40 rtc::CopyOnWriteBuffer buffer; | 40 rtc::CopyOnWriteBuffer buffer; |
| 41 ReceiveDataParams params; | 41 ReceiveDataParams params; |
| 42 // The |flags| parameter is used by SCTP to distinguish notification packets | 42 // The |flags| parameter is used by SCTP to distinguish notification packets |
| 43 // from other types of packets. | 43 // from other types of packets. |
| 44 int flags; | 44 int flags; |
| 45 }; | 45 }; |
| 46 | 46 |
| 47 namespace { | 47 namespace { |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 } | 466 } |
| 467 | 467 |
| 468 // Nagle. | 468 // Nagle. |
| 469 uint32_t nodelay = 1; | 469 uint32_t nodelay = 1; |
| 470 if (usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, | 470 if (usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, |
| 471 sizeof(nodelay))) { | 471 sizeof(nodelay))) { |
| 472 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to set SCTP_NODELAY."; | 472 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to set SCTP_NODELAY."; |
| 473 return false; | 473 return false; |
| 474 } | 474 } |
| 475 | 475 |
| 476 // Disable MTU discovery | |
| 477 sctp_paddrparams params = {{0}}; | |
| 478 params.spp_assoc_id = 0; | |
| 479 params.spp_flags = SPP_PMTUD_DISABLE; | |
| 480 params.spp_pathmtu = kSctpMtu; | |
| 481 if (usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, ¶ms, | |
| 482 sizeof(params))) { | |
| 483 LOG_ERRNO(LS_ERROR) << debug_name_ | |
| 484 << "Failed to set SCTP_PEER_ADDR_PARAMS."; | |
| 485 return false; | |
| 486 } | |
| 487 | |
| 488 // Subscribe to SCTP event notifications. | 476 // Subscribe to SCTP event notifications. |
| 489 int event_types[] = {SCTP_ASSOC_CHANGE, | 477 int event_types[] = {SCTP_ASSOC_CHANGE, |
| 490 SCTP_PEER_ADDR_CHANGE, | 478 SCTP_PEER_ADDR_CHANGE, |
| 491 SCTP_SEND_FAILED_EVENT, | 479 SCTP_SEND_FAILED_EVENT, |
| 492 SCTP_SENDER_DRY_EVENT, | 480 SCTP_SENDER_DRY_EVENT, |
| 493 SCTP_STREAM_RESET_EVENT}; | 481 SCTP_STREAM_RESET_EVENT}; |
| 494 struct sctp_event event = {0}; | 482 struct sctp_event event = {0}; |
| 495 event.se_assoc_id = SCTP_ALL_ASSOC; | 483 event.se_assoc_id = SCTP_ALL_ASSOC; |
| 496 event.se_on = 1; | 484 event.se_on = 1; |
| 497 for (size_t i = 0; i < arraysize(event_types); i++) { | 485 for (size_t i = 0; i < arraysize(event_types); i++) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 // Note: conversion from int to uint16_t happens on assignment. | 543 // Note: conversion from int to uint16_t happens on assignment. |
| 556 sockaddr_conn remote_sconn = GetSctpSockAddr(remote_port_); | 544 sockaddr_conn remote_sconn = GetSctpSockAddr(remote_port_); |
| 557 int connect_result = usrsctp_connect( | 545 int connect_result = usrsctp_connect( |
| 558 sock_, reinterpret_cast<sockaddr *>(&remote_sconn), sizeof(remote_sconn)); | 546 sock_, reinterpret_cast<sockaddr *>(&remote_sconn), sizeof(remote_sconn)); |
| 559 if (connect_result < 0 && errno != SCTP_EINPROGRESS) { | 547 if (connect_result < 0 && errno != SCTP_EINPROGRESS) { |
| 560 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed usrsctp_connect. got errno=" | 548 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed usrsctp_connect. got errno=" |
| 561 << errno << ", but wanted " << SCTP_EINPROGRESS; | 549 << errno << ", but wanted " << SCTP_EINPROGRESS; |
| 562 CloseSctpSocket(); | 550 CloseSctpSocket(); |
| 563 return false; | 551 return false; |
| 564 } | 552 } |
| 553 // Set the MTU and disable MTU discovery. |
| 554 // We can only do this after usrsctp_connect or it has no effect. |
| 555 sctp_paddrparams params = {{0}}; |
| 556 memcpy(reinterpret_cast<sockaddr*>(¶ms.spp_address), |
| 557 reinterpret_cast<sockaddr*>(&remote_sconn), sizeof(sockaddr)); |
| 558 params.spp_flags = SPP_PMTUD_DISABLE; |
| 559 params.spp_pathmtu = kSctpMtu; |
| 560 if (usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, ¶ms, |
| 561 sizeof(params))) { |
| 562 LOG_ERRNO(LS_ERROR) << debug_name_ |
| 563 << "Failed to set SCTP_PEER_ADDR_PARAMS."; |
| 564 } |
| 565 return true; | 565 return true; |
| 566 } | 566 } |
| 567 | 567 |
| 568 void SctpDataMediaChannel::Disconnect() { | 568 void SctpDataMediaChannel::Disconnect() { |
| 569 // TODO(ldixon): Consider calling |usrsctp_shutdown(sock_, ...)| to do a | 569 // TODO(ldixon): Consider calling |usrsctp_shutdown(sock_, ...)| to do a |
| 570 // shutdown handshake and remove the association. | 570 // shutdown handshake and remove the association. |
| 571 CloseSctpSocket(); | 571 CloseSctpSocket(); |
| 572 } | 572 } |
| 573 | 573 |
| 574 bool SctpDataMediaChannel::SetSend(bool send) { | 574 bool SctpDataMediaChannel::SetSend(bool send) { |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 } | 995 } |
| 996 | 996 |
| 997 bool SctpDataMediaChannel::SetRecvCodecs(const std::vector<DataCodec>& codecs) { | 997 bool SctpDataMediaChannel::SetRecvCodecs(const std::vector<DataCodec>& codecs) { |
| 998 return GetCodecIntParameter( | 998 return GetCodecIntParameter( |
| 999 codecs, kGoogleSctpDataCodecId, kGoogleSctpDataCodecName, kCodecParamPort, | 999 codecs, kGoogleSctpDataCodecId, kGoogleSctpDataCodecName, kCodecParamPort, |
| 1000 &local_port_); | 1000 &local_port_); |
| 1001 } | 1001 } |
| 1002 | 1002 |
| 1003 void SctpDataMediaChannel::OnPacketFromSctpToNetwork( | 1003 void SctpDataMediaChannel::OnPacketFromSctpToNetwork( |
| 1004 rtc::CopyOnWriteBuffer* buffer) { | 1004 rtc::CopyOnWriteBuffer* buffer) { |
| 1005 // usrsctp seems to interpret the MTU we give it strangely -- it seems to | 1005 if (buffer->size() > (kSctpMtu)) { |
| 1006 // give us back packets bigger than that MTU, if only by a fixed amount. | |
| 1007 // This is that amount that we've observed. | |
| 1008 const int kSctpOverhead = 76; | |
| 1009 if (buffer->size() > (kSctpOverhead + kSctpMtu)) { | |
| 1010 LOG(LS_ERROR) << debug_name_ << "->OnPacketFromSctpToNetwork(...): " | 1006 LOG(LS_ERROR) << debug_name_ << "->OnPacketFromSctpToNetwork(...): " |
| 1011 << "SCTP seems to have made a packet that is bigger " | 1007 << "SCTP seems to have made a packet that is bigger " |
| 1012 << "than its official MTU: " << buffer->size() | 1008 << "than its official MTU: " << buffer->size() |
| 1013 << " vs max of " << kSctpMtu | 1009 << " vs max of " << kSctpMtu; |
| 1014 << " even after adding " << kSctpOverhead | |
| 1015 << " extra SCTP overhead"; | |
| 1016 } | 1010 } |
| 1017 MediaChannel::SendPacket(buffer, rtc::PacketOptions()); | 1011 MediaChannel::SendPacket(buffer, rtc::PacketOptions()); |
| 1018 } | 1012 } |
| 1019 | 1013 |
| 1020 bool SctpDataMediaChannel::SendQueuedStreamResets() { | 1014 bool SctpDataMediaChannel::SendQueuedStreamResets() { |
| 1021 if (!sent_reset_streams_.empty() || queued_reset_streams_.empty()) { | 1015 if (!sent_reset_streams_.empty() || queued_reset_streams_.empty()) { |
| 1022 return true; | 1016 return true; |
| 1023 } | 1017 } |
| 1024 | 1018 |
| 1025 LOG(LS_VERBOSE) << "SendQueuedStreamResets[" << debug_name_ << "]: Sending [" | 1019 LOG(LS_VERBOSE) << "SendQueuedStreamResets[" << debug_name_ << "]: Sending [" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 } | 1062 } |
| 1069 case MSG_SCTPOUTBOUNDPACKET: { | 1063 case MSG_SCTPOUTBOUNDPACKET: { |
| 1070 std::unique_ptr<OutboundPacketMessage> pdata( | 1064 std::unique_ptr<OutboundPacketMessage> pdata( |
| 1071 static_cast<OutboundPacketMessage*>(msg->pdata)); | 1065 static_cast<OutboundPacketMessage*>(msg->pdata)); |
| 1072 OnPacketFromSctpToNetwork(pdata->data().get()); | 1066 OnPacketFromSctpToNetwork(pdata->data().get()); |
| 1073 break; | 1067 break; |
| 1074 } | 1068 } |
| 1075 } | 1069 } |
| 1076 } | 1070 } |
| 1077 } // namespace cricket | 1071 } // namespace cricket |
| OLD | NEW |