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 |