Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Side by Side Diff: webrtc/api/webrtcsession.cc

Issue 2564333002: Reland of: Separating SCTP code from BaseChannel/MediaChannel. (Closed)
Patch Set: Merge with master. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/api/webrtcsession.h ('k') | webrtc/api/webrtcsession_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright 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 15 matching lines...) Expand all
26 #include "webrtc/base/basictypes.h" 26 #include "webrtc/base/basictypes.h"
27 #include "webrtc/base/bind.h" 27 #include "webrtc/base/bind.h"
28 #include "webrtc/base/checks.h" 28 #include "webrtc/base/checks.h"
29 #include "webrtc/base/helpers.h" 29 #include "webrtc/base/helpers.h"
30 #include "webrtc/base/logging.h" 30 #include "webrtc/base/logging.h"
31 #include "webrtc/base/stringencode.h" 31 #include "webrtc/base/stringencode.h"
32 #include "webrtc/base/stringutils.h" 32 #include "webrtc/base/stringutils.h"
33 #include "webrtc/call/call.h" 33 #include "webrtc/call/call.h"
34 #include "webrtc/media/base/mediaconstants.h" 34 #include "webrtc/media/base/mediaconstants.h"
35 #include "webrtc/media/base/videocapturer.h" 35 #include "webrtc/media/base/videocapturer.h"
36 #include "webrtc/media/sctp/sctptransportinternal.h"
36 #include "webrtc/p2p/base/portallocator.h" 37 #include "webrtc/p2p/base/portallocator.h"
37 #include "webrtc/p2p/base/transportchannel.h" 38 #include "webrtc/p2p/base/transportchannel.h"
38 #include "webrtc/pc/channel.h" 39 #include "webrtc/pc/channel.h"
39 #include "webrtc/pc/channelmanager.h" 40 #include "webrtc/pc/channelmanager.h"
40 #include "webrtc/pc/mediasession.h" 41 #include "webrtc/pc/mediasession.h"
41 42
42 #ifdef HAVE_QUIC 43 #ifdef HAVE_QUIC
43 #include "webrtc/p2p/quic/quictransportchannel.h" 44 #include "webrtc/p2p/quic/quictransportchannel.h"
44 #endif // HAVE_QUIC 45 #endif // HAVE_QUIC
45 46
(...skipping 21 matching lines...) Expand all
67 const char kPushDownTDFailed[] = 68 const char kPushDownTDFailed[] =
68 "Failed to push down transport description:"; 69 "Failed to push down transport description:";
69 const char kSdpWithoutDtlsFingerprint[] = 70 const char kSdpWithoutDtlsFingerprint[] =
70 "Called with SDP without DTLS fingerprint."; 71 "Called with SDP without DTLS fingerprint.";
71 const char kSdpWithoutSdesCrypto[] = 72 const char kSdpWithoutSdesCrypto[] =
72 "Called with SDP without SDES crypto."; 73 "Called with SDP without SDES crypto.";
73 const char kSdpWithoutIceUfragPwd[] = 74 const char kSdpWithoutIceUfragPwd[] =
74 "Called with SDP without ice-ufrag and ice-pwd."; 75 "Called with SDP without ice-ufrag and ice-pwd.";
75 const char kSessionError[] = "Session error code: "; 76 const char kSessionError[] = "Session error code: ";
76 const char kSessionErrorDesc[] = "Session error description: "; 77 const char kSessionErrorDesc[] = "Session error description: ";
77 const char kDtlsSetupFailureRtp[] = 78 const char kDtlsSrtpSetupFailureRtp[] =
78 "Couldn't set up DTLS-SRTP on RTP channel."; 79 "Couldn't set up DTLS-SRTP on RTP channel.";
79 const char kDtlsSetupFailureRtcp[] = 80 const char kDtlsSrtpSetupFailureRtcp[] =
80 "Couldn't set up DTLS-SRTP on RTCP channel."; 81 "Couldn't set up DTLS-SRTP on RTCP channel.";
81 const char kEnableBundleFailed[] = "Failed to enable BUNDLE."; 82 const char kEnableBundleFailed[] = "Failed to enable BUNDLE.";
82 83
83 IceCandidatePairType GetIceCandidatePairCounter( 84 IceCandidatePairType GetIceCandidatePairCounter(
84 const cricket::Candidate& local, 85 const cricket::Candidate& local,
85 const cricket::Candidate& remote) { 86 const cricket::Candidate& remote) {
86 const auto& l = local.type(); 87 const auto& l = local.type();
87 const auto& r = remote.type(); 88 const auto& r = remote.type();
88 const auto& host = LOCAL_PORT_TYPE; 89 const auto& host = LOCAL_PORT_TYPE;
89 const auto& srflx = STUN_PORT_TYPE; 90 const auto& srflx = STUN_PORT_TYPE;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 const auto* found = 285 const auto* found =
285 cricket::GetStreamBySsrc(video_content->streams(), ssrc); 286 cricket::GetStreamBySsrc(video_content->streams(), ssrc);
286 if (found) { 287 if (found) {
287 *track_id = found->id; 288 *track_id = found->id;
288 return true; 289 return true;
289 } 290 }
290 } 291 }
291 return false; 292 return false;
292 } 293 }
293 294
295 // Get the SCTP port out of a SessionDescription.
296 // Return -1 if not found.
297 static int GetSctpPort(const SessionDescription* session_description) {
298 const ContentInfo* content_info = GetFirstDataContent(session_description);
299 RTC_DCHECK(content_info);
300 if (!content_info) {
301 return -1;
302 }
303 const cricket::DataContentDescription* data =
304 static_cast<const cricket::DataContentDescription*>(
305 (content_info->description));
306 std::string value;
307 cricket::DataCodec match_pattern(cricket::kGoogleSctpDataCodecPlType,
308 cricket::kGoogleSctpDataCodecName);
309 for (const cricket::DataCodec& codec : data->codecs()) {
310 if (!codec.Matches(match_pattern)) {
311 continue;
312 }
313 if (codec.GetParam(cricket::kCodecParamPort, &value)) {
314 return rtc::FromString<int>(value);
315 }
316 }
317 return -1;
318 }
319
294 static bool BadSdp(const std::string& source, 320 static bool BadSdp(const std::string& source,
295 const std::string& type, 321 const std::string& type,
296 const std::string& reason, 322 const std::string& reason,
297 std::string* err_desc) { 323 std::string* err_desc) {
298 std::ostringstream desc; 324 std::ostringstream desc;
299 desc << "Failed to set " << source; 325 desc << "Failed to set " << source;
300 if (!type.empty()) { 326 if (!type.empty()) {
301 desc << " " << type; 327 desc << " " << type;
302 } 328 }
303 desc << " sdp: " << reason; 329 desc << " sdp: " << reason;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 } 459 }
434 return false; 460 return false;
435 } 461 }
436 462
437 WebRtcSession::WebRtcSession( 463 WebRtcSession::WebRtcSession(
438 webrtc::MediaControllerInterface* media_controller, 464 webrtc::MediaControllerInterface* media_controller,
439 rtc::Thread* network_thread, 465 rtc::Thread* network_thread,
440 rtc::Thread* worker_thread, 466 rtc::Thread* worker_thread,
441 rtc::Thread* signaling_thread, 467 rtc::Thread* signaling_thread,
442 cricket::PortAllocator* port_allocator, 468 cricket::PortAllocator* port_allocator,
443 std::unique_ptr<cricket::TransportController> transport_controller) 469 std::unique_ptr<cricket::TransportController> transport_controller,
470 std::unique_ptr<cricket::SctpTransportInternalFactory> sctp_factory)
444 : network_thread_(network_thread), 471 : network_thread_(network_thread),
445 worker_thread_(worker_thread), 472 worker_thread_(worker_thread),
446 signaling_thread_(signaling_thread), 473 signaling_thread_(signaling_thread),
447 // RFC 3264: The numeric value of the session id and version in the 474 // RFC 3264: The numeric value of the session id and version in the
448 // o line MUST be representable with a "64 bit signed integer". 475 // o line MUST be representable with a "64 bit signed integer".
449 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. 476 // Due to this constraint session id |sid_| is max limited to LLONG_MAX.
450 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)), 477 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
451 transport_controller_(std::move(transport_controller)), 478 transport_controller_(std::move(transport_controller)),
479 sctp_factory_(std::move(sctp_factory)),
452 media_controller_(media_controller), 480 media_controller_(media_controller),
453 channel_manager_(media_controller_->channel_manager()), 481 channel_manager_(media_controller_->channel_manager()),
454 ice_observer_(NULL), 482 ice_observer_(NULL),
455 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), 483 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
456 ice_connection_receiving_(true), 484 ice_connection_receiving_(true),
457 older_version_remote_peer_(false), 485 older_version_remote_peer_(false),
458 dtls_enabled_(false), 486 dtls_enabled_(false),
459 data_channel_type_(cricket::DCT_NONE), 487 data_channel_type_(cricket::DCT_NONE),
460 metrics_observer_(NULL) { 488 metrics_observer_(NULL) {
461 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); 489 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED);
462 transport_controller_->SignalConnectionState.connect( 490 transport_controller_->SignalConnectionState.connect(
463 this, &WebRtcSession::OnTransportControllerConnectionState); 491 this, &WebRtcSession::OnTransportControllerConnectionState);
464 transport_controller_->SignalReceiving.connect( 492 transport_controller_->SignalReceiving.connect(
465 this, &WebRtcSession::OnTransportControllerReceiving); 493 this, &WebRtcSession::OnTransportControllerReceiving);
466 transport_controller_->SignalGatheringState.connect( 494 transport_controller_->SignalGatheringState.connect(
467 this, &WebRtcSession::OnTransportControllerGatheringState); 495 this, &WebRtcSession::OnTransportControllerGatheringState);
468 transport_controller_->SignalCandidatesGathered.connect( 496 transport_controller_->SignalCandidatesGathered.connect(
469 this, &WebRtcSession::OnTransportControllerCandidatesGathered); 497 this, &WebRtcSession::OnTransportControllerCandidatesGathered);
470 transport_controller_->SignalCandidatesRemoved.connect( 498 transport_controller_->SignalCandidatesRemoved.connect(
471 this, &WebRtcSession::OnTransportControllerCandidatesRemoved); 499 this, &WebRtcSession::OnTransportControllerCandidatesRemoved);
472 transport_controller_->SignalDtlsHandshakeError.connect( 500 transport_controller_->SignalDtlsHandshakeError.connect(
473 this, &WebRtcSession::OnDtlsHandshakeError); 501 this, &WebRtcSession::OnTransportControllerDtlsHandshakeError);
474 } 502 }
475 503
476 WebRtcSession::~WebRtcSession() { 504 WebRtcSession::~WebRtcSession() {
477 ASSERT(signaling_thread()->IsCurrent()); 505 ASSERT(signaling_thread()->IsCurrent());
478 // Destroy video_channel_ first since it may have a pointer to the 506 // Destroy video_channel_ first since it may have a pointer to the
479 // voice_channel_. 507 // voice_channel_.
480 if (video_channel_) { 508 if (video_channel_) {
481 SignalVideoChannelDestroyed(); 509 SignalVideoChannelDestroyed();
482 channel_manager_->DestroyVideoChannel(video_channel_.release()); 510 channel_manager_->DestroyVideoChannel(video_channel_.release());
483 } 511 }
484 if (voice_channel_) { 512 if (voice_channel_) {
485 SignalVoiceChannelDestroyed(); 513 SignalVoiceChannelDestroyed();
486 channel_manager_->DestroyVoiceChannel(voice_channel_.release()); 514 channel_manager_->DestroyVoiceChannel(voice_channel_.release());
487 } 515 }
488 if (data_channel_) { 516 if (rtp_data_channel_) {
489 SignalDataChannelDestroyed(); 517 SignalDataChannelDestroyed();
490 channel_manager_->DestroyDataChannel(data_channel_.release()); 518 channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release());
519 }
520 if (sctp_transport_) {
521 SignalDataChannelDestroyed();
522 network_thread_->Invoke<void>(
523 RTC_FROM_HERE, rtc::Bind(&WebRtcSession::DestroySctpTransport_n, this));
491 } 524 }
492 #ifdef HAVE_QUIC 525 #ifdef HAVE_QUIC
493 if (quic_data_transport_) { 526 if (quic_data_transport_) {
494 quic_data_transport_.reset(); 527 quic_data_transport_.reset();
495 } 528 }
496 #endif 529 #endif
497 SignalDestroyed(); 530 SignalDestroyed();
498 531
499 LOG(LS_INFO) << "Session: " << id() << " is destroyed."; 532 LOG(LS_INFO) << "Session: " << id() << " is destroyed.";
500 } 533 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 if (options.disable_encryption) { 623 if (options.disable_encryption) {
591 webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); 624 webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED);
592 } 625 }
593 626
594 return true; 627 return true;
595 } 628 }
596 629
597 void WebRtcSession::Close() { 630 void WebRtcSession::Close() {
598 SetState(STATE_CLOSED); 631 SetState(STATE_CLOSED);
599 RemoveUnusedChannels(nullptr); 632 RemoveUnusedChannels(nullptr);
600 ASSERT(!voice_channel_); 633 RTC_DCHECK(!voice_channel_);
601 ASSERT(!video_channel_); 634 RTC_DCHECK(!video_channel_);
602 ASSERT(!data_channel_); 635 RTC_DCHECK(!rtp_data_channel_);
636 RTC_DCHECK(!sctp_transport_);
603 media_controller_->Close(); 637 media_controller_->Close();
604 } 638 }
605 639
606 cricket::BaseChannel* WebRtcSession::GetChannel( 640 cricket::BaseChannel* WebRtcSession::GetChannel(
607 const std::string& content_name) { 641 const std::string& content_name) {
608 if (voice_channel() && voice_channel()->content_name() == content_name) { 642 if (voice_channel() && voice_channel()->content_name() == content_name) {
609 return voice_channel(); 643 return voice_channel();
610 } 644 }
611 if (video_channel() && video_channel()->content_name() == content_name) { 645 if (video_channel() && video_channel()->content_name() == content_name) {
612 return video_channel(); 646 return video_channel();
613 } 647 }
614 if (data_channel() && data_channel()->content_name() == content_name) { 648 if (rtp_data_channel() &&
615 return data_channel(); 649 rtp_data_channel()->content_name() == content_name) {
650 return rtp_data_channel();
616 } 651 }
617 return nullptr; 652 return nullptr;
618 } 653 }
619 654
620 cricket::SecurePolicy WebRtcSession::SdesPolicy() const { 655 cricket::SecurePolicy WebRtcSession::SdesPolicy() const {
621 return webrtc_session_desc_factory_->SdesPolicy(); 656 return webrtc_session_desc_factory_->SdesPolicy();
622 } 657 }
623 658
624 bool WebRtcSession::GetSslRole(const std::string& transport_name, 659 bool WebRtcSession::GetSctpSslRole(rtc::SSLRole* role) {
660 if (!local_description() || !remote_description()) {
661 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get the "
662 << "SSL Role of the SCTP transport.";
663 return false;
664 }
665 if (!sctp_transport_) {
666 LOG(LS_INFO) << "Non-rejected SCTP m= section is needed to get the "
667 << "SSL Role of the SCTP transport.";
668 return false;
669 }
670
671 return transport_controller_->GetSslRole(*sctp_transport_name_, role);
672 }
673
674 bool WebRtcSession::GetSslRole(const std::string& content_name,
625 rtc::SSLRole* role) { 675 rtc::SSLRole* role) {
626 if (!local_description() || !remote_description()) { 676 if (!local_description() || !remote_description()) {
627 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get " 677 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get the "
628 << "SSL Role of the session."; 678 << "SSL Role of the session.";
629 return false; 679 return false;
630 } 680 }
631 681
632 return transport_controller_->GetSslRole(transport_name, role); 682 return transport_controller_->GetSslRole(GetTransportName(content_name),
633 } 683 role);
634
635 bool WebRtcSession::GetSslRole(const cricket::BaseChannel* channel,
636 rtc::SSLRole* role) {
637 return channel && GetSslRole(channel->transport_name(), role);
638 } 684 }
639 685
640 void WebRtcSession::CreateOffer( 686 void WebRtcSession::CreateOffer(
641 CreateSessionDescriptionObserver* observer, 687 CreateSessionDescriptionObserver* observer,
642 const PeerConnectionInterface::RTCOfferAnswerOptions& options, 688 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
643 const cricket::MediaSessionOptions& session_options) { 689 const cricket::MediaSessionOptions& session_options) {
644 webrtc_session_desc_factory_->CreateOffer(observer, options, session_options); 690 webrtc_session_desc_factory_->CreateOffer(observer, options, session_options);
645 } 691 }
646 692
647 void WebRtcSession::CreateAnswer( 693 void WebRtcSession::CreateAnswer(
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 return true; 957 return true;
912 } else if (source == cricket::CS_LOCAL) { 958 } else if (source == cricket::CS_LOCAL) {
913 return ch->PushdownLocalDescription(local_description()->description(), 959 return ch->PushdownLocalDescription(local_description()->description(),
914 action, err); 960 action, err);
915 } else { 961 } else {
916 return ch->PushdownRemoteDescription(remote_description()->description(), 962 return ch->PushdownRemoteDescription(remote_description()->description(),
917 action, err); 963 action, err);
918 } 964 }
919 }; 965 };
920 966
921 return (set_content(voice_channel()) && 967 bool ret = (set_content(voice_channel()) && set_content(video_channel()) &&
922 set_content(video_channel()) && 968 set_content(rtp_data_channel()));
923 set_content(data_channel())); 969 // Need complete offer/answer with an SCTP m= section before starting SCTP,
970 // according to https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-19
971 if (sctp_transport_ && local_description() && remote_description() &&
972 cricket::GetFirstDataContent(local_description()->description()) &&
973 cricket::GetFirstDataContent(remote_description()->description())) {
974 ret &= network_thread_->Invoke<bool>(
975 RTC_FROM_HERE,
976 rtc::Bind(&WebRtcSession::PushdownSctpParameters_n, this, source));
977 }
978 return ret;
979 }
980
981 bool WebRtcSession::PushdownSctpParameters_n(cricket::ContentSource source) {
982 RTC_DCHECK(network_thread_->IsCurrent());
983 RTC_DCHECK(local_description());
984 RTC_DCHECK(remote_description());
985 // Apply the SCTP port (which is hidden inside a DataCodec structure...)
986 // When we support "max-message-size", that would also be pushed down here.
987 return sctp_transport_->Start(
988 GetSctpPort(local_description()->description()),
989 GetSctpPort(remote_description()->description()));
924 } 990 }
925 991
926 bool WebRtcSession::PushdownTransportDescription(cricket::ContentSource source, 992 bool WebRtcSession::PushdownTransportDescription(cricket::ContentSource source,
927 cricket::ContentAction action, 993 cricket::ContentAction action,
928 std::string* error_desc) { 994 std::string* error_desc) {
929 RTC_DCHECK(signaling_thread()->IsCurrent()); 995 RTC_DCHECK(signaling_thread()->IsCurrent());
930 996
931 if (source == cricket::CS_LOCAL) { 997 if (source == cricket::CS_LOCAL) {
932 return PushdownLocalTransportDescription(local_description()->description(), 998 return PushdownLocalTransportDescription(local_description()->description(),
933 action, error_desc); 999 action, error_desc);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 } 1051 }
986 const TransportInfo* transport_info = 1052 const TransportInfo* transport_info =
987 description->GetTransportInfoByName(content_name); 1053 description->GetTransportInfoByName(content_name);
988 if (!transport_info) { 1054 if (!transport_info) {
989 return false; 1055 return false;
990 } 1056 }
991 *tdesc = transport_info->description; 1057 *tdesc = transport_info->description;
992 return true; 1058 return true;
993 } 1059 }
994 1060
995 std::unique_ptr<SessionStats> WebRtcSession::GetStats_s() {
996 ASSERT(signaling_thread()->IsCurrent());
997 ChannelNamePairs channel_name_pairs;
998 if (voice_channel()) {
999 channel_name_pairs.voice = rtc::Optional<ChannelNamePair>(ChannelNamePair(
1000 voice_channel()->content_name(), voice_channel()->transport_name()));
1001 }
1002 if (video_channel()) {
1003 channel_name_pairs.video = rtc::Optional<ChannelNamePair>(ChannelNamePair(
1004 video_channel()->content_name(), video_channel()->transport_name()));
1005 }
1006 if (data_channel()) {
1007 channel_name_pairs.data = rtc::Optional<ChannelNamePair>(ChannelNamePair(
1008 data_channel()->content_name(), data_channel()->transport_name()));
1009 }
1010 return GetStats(channel_name_pairs);
1011 }
1012
1013 std::unique_ptr<SessionStats> WebRtcSession::GetStats(
1014 const ChannelNamePairs& channel_name_pairs) {
1015 if (network_thread()->IsCurrent()) {
1016 return GetStats_n(channel_name_pairs);
1017 }
1018 return network_thread()->Invoke<std::unique_ptr<SessionStats>>(
1019 RTC_FROM_HERE,
1020 rtc::Bind(&WebRtcSession::GetStats_n, this, channel_name_pairs));
1021 }
1022
1023 bool WebRtcSession::GetLocalCertificate(
1024 const std::string& transport_name,
1025 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
1026 return transport_controller_->GetLocalCertificate(transport_name,
1027 certificate);
1028 }
1029
1030 std::unique_ptr<rtc::SSLCertificate> WebRtcSession::GetRemoteSSLCertificate(
1031 const std::string& transport_name) {
1032 return transport_controller_->GetRemoteSSLCertificate(transport_name);
1033 }
1034
1035 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) { 1061 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
1036 const std::string* first_content_name = bundle.FirstContentName(); 1062 const std::string* first_content_name = bundle.FirstContentName();
1037 if (!first_content_name) { 1063 if (!first_content_name) {
1038 LOG(LS_WARNING) << "Tried to BUNDLE with no contents."; 1064 LOG(LS_WARNING) << "Tried to BUNDLE with no contents.";
1039 return false; 1065 return false;
1040 } 1066 }
1041 const std::string& transport_name = *first_content_name; 1067 const std::string& transport_name = *first_content_name;
1042 cricket::BaseChannel* first_channel = GetChannel(transport_name);
1043 1068
1044 #ifdef HAVE_QUIC 1069 #ifdef HAVE_QUIC
1045 if (quic_data_transport_ && 1070 if (quic_data_transport_ &&
1046 bundle.HasContentName(quic_data_transport_->content_name()) && 1071 bundle.HasContentName(quic_data_transport_->content_name()) &&
1047 quic_data_transport_->transport_name() != transport_name) { 1072 quic_data_transport_->transport_name() != transport_name) {
1048 LOG(LS_ERROR) << "Unable to BUNDLE " << quic_data_transport_->content_name() 1073 LOG(LS_ERROR) << "Unable to BUNDLE " << quic_data_transport_->content_name()
1049 << " on " << transport_name << "with QUIC."; 1074 << " on " << transport_name << "with QUIC.";
1050 } 1075 }
1051 #endif 1076 #endif
1052 1077
1053 auto maybe_set_transport = [this, bundle, transport_name, 1078 auto maybe_set_transport = [this, bundle,
1054 first_channel](cricket::BaseChannel* ch) { 1079 transport_name](cricket::BaseChannel* ch) {
1055 if (!ch || !bundle.HasContentName(ch->content_name())) { 1080 if (!ch || !bundle.HasContentName(ch->content_name())) {
1056 return true; 1081 return true;
1057 } 1082 }
1058 1083
1059 if (ch->transport_name() == transport_name) { 1084 if (ch->transport_name() == transport_name) {
1060 LOG(LS_INFO) << "BUNDLE already enabled for " << ch->content_name() 1085 LOG(LS_INFO) << "BUNDLE already enabled for " << ch->content_name()
1061 << " on " << transport_name << "."; 1086 << " on " << transport_name << ".";
1062 return true; 1087 return true;
1063 } 1088 }
1064 1089
1065 if (!ch->SetTransport(transport_name)) { 1090 if (!ch->SetTransport(transport_name)) {
1066 LOG(LS_WARNING) << "Failed to enable BUNDLE for " << ch->content_name(); 1091 LOG(LS_WARNING) << "Failed to enable BUNDLE for " << ch->content_name();
1067 return false; 1092 return false;
1068 } 1093 }
1069 LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on " 1094 LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on "
1070 << transport_name << "."; 1095 << transport_name << ".";
1071 return true; 1096 return true;
1072 }; 1097 };
1073 1098
1074 if (!maybe_set_transport(voice_channel()) || 1099 if (!maybe_set_transport(voice_channel()) ||
1075 !maybe_set_transport(video_channel()) || 1100 !maybe_set_transport(video_channel()) ||
1076 !maybe_set_transport(data_channel())) { 1101 !maybe_set_transport(rtp_data_channel())) {
1077 return false; 1102 return false;
1078 } 1103 }
1104 // For SCTP, transport creation/deletion happens here instead of in the
1105 // object itself.
1106 if (sctp_transport_) {
1107 RTC_DCHECK(sctp_transport_name_);
1108 RTC_DCHECK(sctp_content_name_);
1109 if (transport_name != *sctp_transport_name_ &&
1110 bundle.HasContentName(*sctp_content_name_)) {
1111 network_thread_->Invoke<void>(
1112 RTC_FROM_HERE, rtc::Bind(&WebRtcSession::ChangeSctpTransport_n, this,
1113 transport_name));
1114 }
1115 }
1079 1116
1080 return true; 1117 return true;
1081 } 1118 }
1082 1119
1083 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) { 1120 bool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) {
1084 if (!remote_description()) { 1121 if (!remote_description()) {
1085 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added " 1122 LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added "
1086 << "without any remote session description."; 1123 << "without any remote session description.";
1087 return false; 1124 return false;
1088 } 1125 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 return true; 1278 return true;
1242 } 1279 }
1243 1280
1244 sigslot::signal0<>* WebRtcSession::GetOnDestroyedSignal() { 1281 sigslot::signal0<>* WebRtcSession::GetOnDestroyedSignal() {
1245 return &SignalDestroyed; 1282 return &SignalDestroyed;
1246 } 1283 }
1247 1284
1248 bool WebRtcSession::SendData(const cricket::SendDataParams& params, 1285 bool WebRtcSession::SendData(const cricket::SendDataParams& params,
1249 const rtc::CopyOnWriteBuffer& payload, 1286 const rtc::CopyOnWriteBuffer& payload,
1250 cricket::SendDataResult* result) { 1287 cricket::SendDataResult* result) {
1251 if (!data_channel_) { 1288 if (!rtp_data_channel_ && !sctp_transport_) {
1252 LOG(LS_ERROR) << "SendData called when data_channel_ is NULL."; 1289 LOG(LS_ERROR) << "SendData called when rtp_data_channel_ "
1290 << "and sctp_transport_ are NULL.";
1253 return false; 1291 return false;
1254 } 1292 }
1255 return data_channel_->SendData(params, payload, result); 1293 return rtp_data_channel_
1294 ? rtp_data_channel_->SendData(params, payload, result)
1295 : network_thread_->Invoke<bool>(
1296 RTC_FROM_HERE,
1297 Bind(&cricket::SctpTransportInternal::SendData,
1298 sctp_transport_.get(), params, payload, result));
1256 } 1299 }
1257 1300
1258 bool WebRtcSession::ConnectDataChannel(DataChannel* webrtc_data_channel) { 1301 bool WebRtcSession::ConnectDataChannel(DataChannel* webrtc_data_channel) {
1259 if (!data_channel_) { 1302 if (!rtp_data_channel_ && !sctp_transport_) {
1260 // Don't log an error here, because DataChannels are expected to call 1303 // Don't log an error here, because DataChannels are expected to call
1261 // ConnectDataChannel in this state. It's the only way to initially tell 1304 // ConnectDataChannel in this state. It's the only way to initially tell
1262 // whether or not the underlying transport is ready. 1305 // whether or not the underlying transport is ready.
1263 return false; 1306 return false;
1264 } 1307 }
1265 data_channel_->SignalReadyToSendData.connect(webrtc_data_channel, 1308 if (rtp_data_channel_) {
1266 &DataChannel::OnChannelReady); 1309 rtp_data_channel_->SignalReadyToSendData.connect(
1267 data_channel_->SignalDataReceived.connect(webrtc_data_channel, 1310 webrtc_data_channel, &DataChannel::OnChannelReady);
1268 &DataChannel::OnDataReceived); 1311 rtp_data_channel_->SignalDataReceived.connect(webrtc_data_channel,
1269 data_channel_->SignalStreamClosedRemotely.connect( 1312 &DataChannel::OnDataReceived);
1270 webrtc_data_channel, &DataChannel::OnStreamClosedRemotely); 1313 } else {
1314 SignalSctpReadyToSendData.connect(webrtc_data_channel,
1315 &DataChannel::OnChannelReady);
1316 SignalSctpDataReceived.connect(webrtc_data_channel,
1317 &DataChannel::OnDataReceived);
1318 SignalSctpStreamClosedRemotely.connect(
1319 webrtc_data_channel, &DataChannel::OnStreamClosedRemotely);
1320 }
1271 return true; 1321 return true;
1272 } 1322 }
1273 1323
1274 void WebRtcSession::DisconnectDataChannel(DataChannel* webrtc_data_channel) { 1324 void WebRtcSession::DisconnectDataChannel(DataChannel* webrtc_data_channel) {
1275 if (!data_channel_) { 1325 if (!rtp_data_channel_ && !sctp_transport_) {
1276 LOG(LS_ERROR) << "DisconnectDataChannel called when data_channel_ is NULL."; 1326 LOG(LS_ERROR) << "DisconnectDataChannel called when rtp_data_channel_ and "
1327 "sctp_transport_ are NULL.";
1277 return; 1328 return;
1278 } 1329 }
1279 data_channel_->SignalReadyToSendData.disconnect(webrtc_data_channel); 1330 if (rtp_data_channel_) {
1280 data_channel_->SignalDataReceived.disconnect(webrtc_data_channel); 1331 rtp_data_channel_->SignalReadyToSendData.disconnect(webrtc_data_channel);
1281 data_channel_->SignalStreamClosedRemotely.disconnect(webrtc_data_channel); 1332 rtp_data_channel_->SignalDataReceived.disconnect(webrtc_data_channel);
1333 } else {
1334 SignalSctpReadyToSendData.disconnect(webrtc_data_channel);
1335 SignalSctpDataReceived.disconnect(webrtc_data_channel);
1336 SignalSctpStreamClosedRemotely.disconnect(webrtc_data_channel);
1337 }
1282 } 1338 }
1283 1339
1284 void WebRtcSession::AddSctpDataStream(int sid) { 1340 void WebRtcSession::AddSctpDataStream(int sid) {
1285 if (!data_channel_) { 1341 if (!sctp_transport_) {
1286 LOG(LS_ERROR) << "AddDataChannelStreams called when data_channel_ is NULL."; 1342 LOG(LS_ERROR) << "AddSctpDataStream called when sctp_transport_ is NULL.";
1287 return; 1343 return;
1288 } 1344 }
1289 data_channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(sid)); 1345 network_thread_->Invoke<void>(
1290 data_channel_->AddSendStream(cricket::StreamParams::CreateLegacy(sid)); 1346 RTC_FROM_HERE, rtc::Bind(&cricket::SctpTransportInternal::OpenStream,
1347 sctp_transport_.get(), sid));
1291 } 1348 }
1292 1349
1293 void WebRtcSession::RemoveSctpDataStream(int sid) { 1350 void WebRtcSession::RemoveSctpDataStream(int sid) {
1294 if (!data_channel_) { 1351 if (!sctp_transport_) {
1295 LOG(LS_ERROR) << "RemoveDataChannelStreams called when data_channel_ is " 1352 LOG(LS_ERROR) << "RemoveSctpDataStream called when sctp_transport_ is "
1296 << "NULL."; 1353 << "NULL.";
1297 return; 1354 return;
1298 } 1355 }
1299 data_channel_->RemoveRecvStream(sid); 1356 network_thread_->Invoke<void>(
1300 data_channel_->RemoveSendStream(sid); 1357 RTC_FROM_HERE, rtc::Bind(&cricket::SctpTransportInternal::ResetStream,
1358 sctp_transport_.get(), sid));
1301 } 1359 }
1302 1360
1303 bool WebRtcSession::ReadyToSendData() const { 1361 bool WebRtcSession::ReadyToSendData() const {
1304 return data_channel_ && data_channel_->ready_to_send_data(); 1362 return (rtp_data_channel_ && rtp_data_channel_->ready_to_send_data()) ||
1363 sctp_ready_to_send_data_;
1364 }
1365
1366 std::unique_ptr<SessionStats> WebRtcSession::GetStats_s() {
1367 ASSERT(signaling_thread()->IsCurrent());
1368 ChannelNamePairs channel_name_pairs;
1369 if (voice_channel()) {
1370 channel_name_pairs.voice = rtc::Optional<ChannelNamePair>(ChannelNamePair(
1371 voice_channel()->content_name(), voice_channel()->transport_name()));
1372 }
1373 if (video_channel()) {
1374 channel_name_pairs.video = rtc::Optional<ChannelNamePair>(ChannelNamePair(
1375 video_channel()->content_name(), video_channel()->transport_name()));
1376 }
1377 if (rtp_data_channel()) {
1378 channel_name_pairs.data = rtc::Optional<ChannelNamePair>(
1379 ChannelNamePair(rtp_data_channel()->content_name(),
1380 rtp_data_channel()->transport_name()));
1381 }
1382 if (sctp_transport_) {
1383 RTC_DCHECK(sctp_content_name_);
1384 RTC_DCHECK(sctp_transport_name_);
1385 channel_name_pairs.data = rtc::Optional<ChannelNamePair>(
1386 ChannelNamePair(*sctp_content_name_, *sctp_transport_name_));
1387 }
1388 return GetStats(channel_name_pairs);
1389 }
1390
1391 std::unique_ptr<SessionStats> WebRtcSession::GetStats(
1392 const ChannelNamePairs& channel_name_pairs) {
1393 if (network_thread()->IsCurrent()) {
1394 return GetStats_n(channel_name_pairs);
1395 }
1396 return network_thread()->Invoke<std::unique_ptr<SessionStats>>(
1397 RTC_FROM_HERE,
1398 rtc::Bind(&WebRtcSession::GetStats_n, this, channel_name_pairs));
1399 }
1400
1401 bool WebRtcSession::GetLocalCertificate(
1402 const std::string& transport_name,
1403 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
1404 return transport_controller_->GetLocalCertificate(transport_name,
1405 certificate);
1406 }
1407
1408 std::unique_ptr<rtc::SSLCertificate> WebRtcSession::GetRemoteSSLCertificate(
1409 const std::string& transport_name) {
1410 return transport_controller_->GetRemoteSSLCertificate(transport_name);
1305 } 1411 }
1306 1412
1307 cricket::DataChannelType WebRtcSession::data_channel_type() const { 1413 cricket::DataChannelType WebRtcSession::data_channel_type() const {
1308 return data_channel_type_; 1414 return data_channel_type_;
1309 } 1415 }
1310 1416
1311 bool WebRtcSession::IceRestartPending(const std::string& content_name) const { 1417 bool WebRtcSession::IceRestartPending(const std::string& content_name) const {
1312 return pending_ice_restarts_.find(content_name) != 1418 return pending_ice_restarts_.find(content_name) !=
1313 pending_ice_restarts_.end(); 1419 pending_ice_restarts_.end();
1314 } 1420 }
1315 1421
1316 void WebRtcSession::SetNeedsIceRestartFlag() { 1422 void WebRtcSession::SetNeedsIceRestartFlag() {
1317 transport_controller_->SetNeedsIceRestartFlag(); 1423 transport_controller_->SetNeedsIceRestartFlag();
1318 } 1424 }
1319 1425
1320 bool WebRtcSession::NeedsIceRestart(const std::string& content_name) const { 1426 bool WebRtcSession::NeedsIceRestart(const std::string& content_name) const {
1321 return transport_controller_->NeedsIceRestart(content_name); 1427 return transport_controller_->NeedsIceRestart(content_name);
1322 } 1428 }
1323 1429
1324 void WebRtcSession::OnCertificateReady( 1430 void WebRtcSession::OnCertificateReady(
1325 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { 1431 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
1326 transport_controller_->SetLocalCertificate(certificate); 1432 transport_controller_->SetLocalCertificate(certificate);
1327 } 1433 }
1328 1434
1435 void WebRtcSession::OnDtlsSrtpSetupFailure(cricket::BaseChannel*, bool rtcp) {
1436 SetError(ERROR_TRANSPORT,
1437 rtcp ? kDtlsSrtpSetupFailureRtcp : kDtlsSrtpSetupFailureRtp);
1438 }
1439
1329 bool WebRtcSession::waiting_for_certificate_for_testing() const { 1440 bool WebRtcSession::waiting_for_certificate_for_testing() const {
1330 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); 1441 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing();
1331 } 1442 }
1332 1443
1333 const rtc::scoped_refptr<rtc::RTCCertificate>& 1444 const rtc::scoped_refptr<rtc::RTCCertificate>&
1334 WebRtcSession::certificate_for_testing() { 1445 WebRtcSession::certificate_for_testing() {
1335 return transport_controller_->certificate_for_testing(); 1446 return transport_controller_->certificate_for_testing();
1336 } 1447 }
1337 1448
1338 void WebRtcSession::SetIceConnectionState( 1449 void WebRtcSession::SetIceConnectionState(
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 } 1559 }
1449 1560
1450 if (local_description()) { 1561 if (local_description()) {
1451 mutable_local_description()->RemoveCandidates(candidates); 1562 mutable_local_description()->RemoveCandidates(candidates);
1452 } 1563 }
1453 if (ice_observer_) { 1564 if (ice_observer_) {
1454 ice_observer_->OnIceCandidatesRemoved(candidates); 1565 ice_observer_->OnIceCandidatesRemoved(candidates);
1455 } 1566 }
1456 } 1567 }
1457 1568
1458 // Enabling voice and video channel. 1569 void WebRtcSession::OnTransportControllerDtlsHandshakeError(
1570 rtc::SSLHandshakeError error) {
1571 if (metrics_observer_) {
1572 metrics_observer_->IncrementEnumCounter(
1573 webrtc::kEnumCounterDtlsHandshakeError, static_cast<int>(error),
1574 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
1575 }
1576 }
1577
1578 // Enabling voice and video (and RTP data) channel.
1459 void WebRtcSession::EnableChannels() { 1579 void WebRtcSession::EnableChannels() {
1460 if (voice_channel_ && !voice_channel_->enabled()) 1580 if (voice_channel_ && !voice_channel_->enabled())
1461 voice_channel_->Enable(true); 1581 voice_channel_->Enable(true);
1462 1582
1463 if (video_channel_ && !video_channel_->enabled()) 1583 if (video_channel_ && !video_channel_->enabled())
1464 video_channel_->Enable(true); 1584 video_channel_->Enable(true);
1465 1585
1466 if (data_channel_ && !data_channel_->enabled()) 1586 if (rtp_data_channel_ && !rtp_data_channel_->enabled())
1467 data_channel_->Enable(true); 1587 rtp_data_channel_->Enable(true);
1468 } 1588 }
1469 1589
1470 // Returns the media index for a local ice candidate given the content name. 1590 // Returns the media index for a local ice candidate given the content name.
1471 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name, 1591 bool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name,
1472 int* sdp_mline_index) { 1592 int* sdp_mline_index) {
1473 if (!local_description() || !sdp_mline_index) { 1593 if (!local_description() || !sdp_mline_index) {
1474 return false; 1594 return false;
1475 } 1595 }
1476 1596
1477 bool content_found = false; 1597 bool content_found = false;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 const cricket::ContentInfo* voice_info = 1687 const cricket::ContentInfo* voice_info =
1568 cricket::GetFirstAudioContent(desc); 1688 cricket::GetFirstAudioContent(desc);
1569 if ((!voice_info || voice_info->rejected) && voice_channel_) { 1689 if ((!voice_info || voice_info->rejected) && voice_channel_) {
1570 SignalVoiceChannelDestroyed(); 1690 SignalVoiceChannelDestroyed();
1571 channel_manager_->DestroyVoiceChannel(voice_channel_.release()); 1691 channel_manager_->DestroyVoiceChannel(voice_channel_.release());
1572 } 1692 }
1573 1693
1574 const cricket::ContentInfo* data_info = 1694 const cricket::ContentInfo* data_info =
1575 cricket::GetFirstDataContent(desc); 1695 cricket::GetFirstDataContent(desc);
1576 if (!data_info || data_info->rejected) { 1696 if (!data_info || data_info->rejected) {
1577 if (data_channel_) { 1697 if (rtp_data_channel_) {
1578 SignalDataChannelDestroyed(); 1698 SignalDataChannelDestroyed();
1579 channel_manager_->DestroyDataChannel(data_channel_.release()); 1699 channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release());
1700 }
1701 if (sctp_transport_) {
1702 SignalDataChannelDestroyed();
1703 network_thread_->Invoke<void>(
1704 RTC_FROM_HERE,
1705 rtc::Bind(&WebRtcSession::DestroySctpTransport_n, this));
1580 } 1706 }
1581 #ifdef HAVE_QUIC 1707 #ifdef HAVE_QUIC
1582 // Clean up the existing QuicDataTransport and its QuicTransportChannels. 1708 // Clean up the existing QuicDataTransport and its QuicTransportChannels.
1583 if (quic_data_transport_) { 1709 if (quic_data_transport_) {
1584 quic_data_transport_.reset(); 1710 quic_data_transport_.reset();
1585 } 1711 }
1586 #endif 1712 #endif
1587 } 1713 }
1588 } 1714 }
1589 1715
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc); 1756 const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
1631 if (video && !video->rejected && !video_channel_) { 1757 if (video && !video->rejected && !video_channel_) {
1632 if (!CreateVideoChannel(video, 1758 if (!CreateVideoChannel(video,
1633 GetBundleTransportName(video, bundle_group))) { 1759 GetBundleTransportName(video, bundle_group))) {
1634 LOG(LS_ERROR) << "Failed to create video channel."; 1760 LOG(LS_ERROR) << "Failed to create video channel.";
1635 return false; 1761 return false;
1636 } 1762 }
1637 } 1763 }
1638 1764
1639 const cricket::ContentInfo* data = cricket::GetFirstDataContent(desc); 1765 const cricket::ContentInfo* data = cricket::GetFirstDataContent(desc);
1640 if (data_channel_type_ != cricket::DCT_NONE && 1766 if (data_channel_type_ != cricket::DCT_NONE && data && !data->rejected &&
1641 data && !data->rejected && !data_channel_) { 1767 !rtp_data_channel_ && !sctp_transport_) {
1642 if (!CreateDataChannel(data, GetBundleTransportName(data, bundle_group))) { 1768 if (!CreateDataChannel(data, GetBundleTransportName(data, bundle_group))) {
1643 LOG(LS_ERROR) << "Failed to create data channel."; 1769 LOG(LS_ERROR) << "Failed to create data channel.";
1644 return false; 1770 return false;
1645 } 1771 }
1646 } 1772 }
1647 1773
1648 return true; 1774 return true;
1649 } 1775 }
1650 1776
1651 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content, 1777 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content,
1652 const std::string* bundle_transport) { 1778 const std::string* bundle_transport) {
1653 bool require_rtcp_mux = 1779 bool require_rtcp_mux =
1654 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; 1780 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire;
1655 bool create_rtcp_transport_channel = !require_rtcp_mux; 1781 bool create_rtcp_transport_channel = !require_rtcp_mux;
1656 voice_channel_.reset(channel_manager_->CreateVoiceChannel( 1782 voice_channel_.reset(channel_manager_->CreateVoiceChannel(
1657 media_controller_, transport_controller_.get(), content->name, 1783 media_controller_, transport_controller_.get(), content->name,
1658 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), 1784 bundle_transport, create_rtcp_transport_channel, SrtpRequired(),
1659 audio_options_)); 1785 audio_options_));
1660 if (!voice_channel_) { 1786 if (!voice_channel_) {
1661 return false; 1787 return false;
1662 } 1788 }
1663 if (require_rtcp_mux) { 1789 if (require_rtcp_mux) {
1664 voice_channel_->ActivateRtcpMux(); 1790 voice_channel_->ActivateRtcpMux();
1665 } 1791 }
1666 1792
1667 voice_channel_->SignalDtlsSetupFailure.connect( 1793 voice_channel_->SignalDtlsSrtpSetupFailure.connect(
1668 this, &WebRtcSession::OnDtlsSetupFailure); 1794 this, &WebRtcSession::OnDtlsSrtpSetupFailure);
1669 1795
1670 SignalVoiceChannelCreated(); 1796 SignalVoiceChannelCreated();
1671 voice_channel_->SignalSentPacket.connect(this, 1797 voice_channel_->SignalSentPacket.connect(this,
1672 &WebRtcSession::OnSentPacket_w); 1798 &WebRtcSession::OnSentPacket_w);
1673 return true; 1799 return true;
1674 } 1800 }
1675 1801
1676 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content, 1802 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content,
1677 const std::string* bundle_transport) { 1803 const std::string* bundle_transport) {
1678 bool require_rtcp_mux = 1804 bool require_rtcp_mux =
1679 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; 1805 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire;
1680 bool create_rtcp_transport_channel = !require_rtcp_mux; 1806 bool create_rtcp_transport_channel = !require_rtcp_mux;
1681 video_channel_.reset(channel_manager_->CreateVideoChannel( 1807 video_channel_.reset(channel_manager_->CreateVideoChannel(
1682 media_controller_, transport_controller_.get(), content->name, 1808 media_controller_, transport_controller_.get(), content->name,
1683 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), 1809 bundle_transport, create_rtcp_transport_channel, SrtpRequired(),
1684 video_options_)); 1810 video_options_));
1685 if (!video_channel_) { 1811 if (!video_channel_) {
1686 return false; 1812 return false;
1687 } 1813 }
1688 if (require_rtcp_mux) { 1814 if (require_rtcp_mux) {
1689 video_channel_->ActivateRtcpMux(); 1815 video_channel_->ActivateRtcpMux();
1690 } 1816 }
1691 video_channel_->SignalDtlsSetupFailure.connect( 1817 video_channel_->SignalDtlsSrtpSetupFailure.connect(
1692 this, &WebRtcSession::OnDtlsSetupFailure); 1818 this, &WebRtcSession::OnDtlsSrtpSetupFailure);
1693 1819
1694 SignalVideoChannelCreated(); 1820 SignalVideoChannelCreated();
1695 video_channel_->SignalSentPacket.connect(this, 1821 video_channel_->SignalSentPacket.connect(this,
1696 &WebRtcSession::OnSentPacket_w); 1822 &WebRtcSession::OnSentPacket_w);
1697 return true; 1823 return true;
1698 } 1824 }
1699 1825
1700 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content, 1826 bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content,
1701 const std::string* bundle_transport) { 1827 const std::string* bundle_transport) {
1828 const std::string transport_name =
1829 bundle_transport ? *bundle_transport : content->name;
1702 #ifdef HAVE_QUIC 1830 #ifdef HAVE_QUIC
1703 if (data_channel_type_ == cricket::DCT_QUIC) { 1831 if (data_channel_type_ == cricket::DCT_QUIC) {
1704 RTC_DCHECK(transport_controller_->quic()); 1832 RTC_DCHECK(transport_controller_->quic());
1705 const std::string transport_name =
1706 bundle_transport ? *bundle_transport : content->name;
1707 quic_data_transport_->SetTransport(transport_name); 1833 quic_data_transport_->SetTransport(transport_name);
1708 return true; 1834 return true;
1709 } 1835 }
1710 #endif // HAVE_QUIC 1836 #endif // HAVE_QUIC
1711 bool sctp = (data_channel_type_ == cricket::DCT_SCTP); 1837 bool sctp = (data_channel_type_ == cricket::DCT_SCTP);
1712 bool require_rtcp_mux = 1838 if (sctp) {
1713 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; 1839 if (!sctp_factory_) {
1714 bool create_rtcp_transport_channel = !sctp && !require_rtcp_mux; 1840 LOG(LS_ERROR)
1715 data_channel_.reset(channel_manager_->CreateDataChannel( 1841 << "Trying to create SCTP transport, but didn't compile with "
1716 media_controller_, transport_controller_.get(), content->name, 1842 "SCTP support (HAVE_SCTP)";
1717 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), 1843 return false;
1718 data_channel_type_)); 1844 }
1719 if (!data_channel_) { 1845 if (!network_thread_->Invoke<bool>(
1720 return false; 1846 RTC_FROM_HERE, rtc::Bind(&WebRtcSession::CreateSctpTransport_n,
1721 } 1847 this, content->name, transport_name))) {
1722 if (require_rtcp_mux) { 1848 return false;
1723 data_channel_->ActivateRtcpMux(); 1849 };
1850 } else {
1851 bool require_rtcp_mux =
1852 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire;
1853 bool create_rtcp_transport_channel = !sctp && !require_rtcp_mux;
1854 rtp_data_channel_.reset(channel_manager_->CreateRtpDataChannel(
1855 media_controller_, transport_controller_.get(), content->name,
1856 bundle_transport, create_rtcp_transport_channel, SrtpRequired()));
1857 if (!rtp_data_channel_) {
1858 return false;
1859 }
1860 if (require_rtcp_mux) {
1861 rtp_data_channel_->ActivateRtcpMux();
1862 }
1863 rtp_data_channel_->SignalDtlsSrtpSetupFailure.connect(
1864 this, &WebRtcSession::OnDtlsSrtpSetupFailure);
1865 rtp_data_channel_->SignalSentPacket.connect(this,
1866 &WebRtcSession::OnSentPacket_w);
1724 } 1867 }
1725 1868
1726 if (sctp) {
1727 data_channel_->SignalDataReceived.connect(
1728 this, &WebRtcSession::OnDataChannelMessageReceived);
1729 }
1730
1731 data_channel_->SignalDtlsSetupFailure.connect(
1732 this, &WebRtcSession::OnDtlsSetupFailure);
1733
1734 SignalDataChannelCreated(); 1869 SignalDataChannelCreated();
1735 data_channel_->SignalSentPacket.connect(this, &WebRtcSession::OnSentPacket_w);
1736 return true; 1870 return true;
1737 } 1871 }
1738 1872
1739 std::unique_ptr<SessionStats> WebRtcSession::GetStats_n( 1873 std::unique_ptr<SessionStats> WebRtcSession::GetStats_n(
1740 const ChannelNamePairs& channel_name_pairs) { 1874 const ChannelNamePairs& channel_name_pairs) {
1741 ASSERT(network_thread()->IsCurrent()); 1875 ASSERT(network_thread()->IsCurrent());
1742 std::unique_ptr<SessionStats> session_stats(new SessionStats()); 1876 std::unique_ptr<SessionStats> session_stats(new SessionStats());
1743 for (const auto channel_name_pair : { &channel_name_pairs.voice, 1877 for (const auto channel_name_pair : { &channel_name_pairs.voice,
1744 &channel_name_pairs.video, 1878 &channel_name_pairs.video,
1745 &channel_name_pairs.data }) { 1879 &channel_name_pairs.data }) {
1746 if (*channel_name_pair) { 1880 if (*channel_name_pair) {
1747 cricket::TransportStats transport_stats; 1881 cricket::TransportStats transport_stats;
1748 if (!transport_controller_->GetStats((*channel_name_pair)->transport_name, 1882 if (!transport_controller_->GetStats((*channel_name_pair)->transport_name,
1749 &transport_stats)) { 1883 &transport_stats)) {
1750 return nullptr; 1884 return nullptr;
1751 } 1885 }
1752 session_stats->proxy_to_transport[(*channel_name_pair)->content_name] = 1886 session_stats->proxy_to_transport[(*channel_name_pair)->content_name] =
1753 (*channel_name_pair)->transport_name; 1887 (*channel_name_pair)->transport_name;
1754 session_stats->transport_stats[(*channel_name_pair)->transport_name] = 1888 session_stats->transport_stats[(*channel_name_pair)->transport_name] =
1755 std::move(transport_stats); 1889 std::move(transport_stats);
1756 } 1890 }
1757 } 1891 }
1758 return session_stats; 1892 return session_stats;
1759 } 1893 }
1760 1894
1761 void WebRtcSession::OnDtlsSetupFailure(cricket::BaseChannel*, bool rtcp) { 1895 bool WebRtcSession::CreateSctpTransport_n(const std::string& content_name,
1762 SetError(ERROR_TRANSPORT, 1896 const std::string& transport_name) {
1763 rtcp ? kDtlsSetupFailureRtcp : kDtlsSetupFailureRtp); 1897 RTC_DCHECK(network_thread_->IsCurrent());
1898 RTC_DCHECK(sctp_factory_);
1899 cricket::TransportChannel* tc =
1900 transport_controller_->CreateTransportChannel_n(
1901 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
1902 sctp_transport_ = sctp_factory_->CreateSctpTransport(tc);
1903 RTC_DCHECK(sctp_transport_);
1904 sctp_invoker_.reset(new rtc::AsyncInvoker());
1905 sctp_transport_->SignalReadyToSendData.connect(
1906 this, &WebRtcSession::OnSctpTransportReadyToSendData_n);
1907 sctp_transport_->SignalDataReceived.connect(
1908 this, &WebRtcSession::OnSctpTransportDataReceived_n);
1909 sctp_transport_->SignalStreamClosedRemotely.connect(
1910 this, &WebRtcSession::OnSctpStreamClosedRemotely_n);
1911 sctp_transport_name_ = rtc::Optional<std::string>(transport_name);
1912 sctp_content_name_ = rtc::Optional<std::string>(content_name);
1913 return true;
1764 } 1914 }
1765 1915
1766 void WebRtcSession::OnDataChannelMessageReceived( 1916 void WebRtcSession::ChangeSctpTransport_n(const std::string& transport_name) {
1767 cricket::DataChannel* channel, 1917 RTC_DCHECK(network_thread_->IsCurrent());
1918 RTC_DCHECK(sctp_transport_);
1919 RTC_DCHECK(sctp_transport_name_);
1920 std::string old_sctp_transport_name = *sctp_transport_name_;
1921 sctp_transport_name_ = rtc::Optional<std::string>(transport_name);
1922 cricket::TransportChannel* tc =
1923 transport_controller_->CreateTransportChannel_n(
1924 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
1925 sctp_transport_->SetTransportChannel(tc);
1926 transport_controller_->DestroyTransportChannel_n(
1927 old_sctp_transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
1928 }
1929
1930 void WebRtcSession::DestroySctpTransport_n() {
1931 RTC_DCHECK(network_thread_->IsCurrent());
1932 sctp_transport_.reset(nullptr);
1933 sctp_content_name_.reset();
1934 sctp_transport_name_.reset();
1935 sctp_invoker_.reset(nullptr);
1936 sctp_ready_to_send_data_ = false;
1937 }
1938
1939 void WebRtcSession::OnSctpTransportReadyToSendData_n() {
1940 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP);
1941 RTC_DCHECK(network_thread_->IsCurrent());
1942 sctp_invoker_->AsyncInvoke<void>(
1943 RTC_FROM_HERE, signaling_thread_,
1944 rtc::Bind(&WebRtcSession::OnSctpTransportReadyToSendData_s, this, true));
1945 }
1946
1947 void WebRtcSession::OnSctpTransportReadyToSendData_s(bool ready) {
1948 RTC_DCHECK(signaling_thread_->IsCurrent());
1949 sctp_ready_to_send_data_ = ready;
1950 SignalSctpReadyToSendData(ready);
1951 }
1952
1953 void WebRtcSession::OnSctpTransportDataReceived_n(
1768 const cricket::ReceiveDataParams& params, 1954 const cricket::ReceiveDataParams& params,
1769 const rtc::CopyOnWriteBuffer& payload) { 1955 const rtc::CopyOnWriteBuffer& payload) {
1770 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP); 1956 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP);
1957 RTC_DCHECK(network_thread_->IsCurrent());
1958 sctp_invoker_->AsyncInvoke<void>(
1959 RTC_FROM_HERE, signaling_thread_,
1960 rtc::Bind(&WebRtcSession::OnSctpTransportDataReceived_s, this, params,
1961 payload));
1962 }
1963
1964 void WebRtcSession::OnSctpTransportDataReceived_s(
1965 const cricket::ReceiveDataParams& params,
1966 const rtc::CopyOnWriteBuffer& payload) {
1967 RTC_DCHECK(signaling_thread_->IsCurrent());
1771 if (params.type == cricket::DMT_CONTROL && IsOpenMessage(payload)) { 1968 if (params.type == cricket::DMT_CONTROL && IsOpenMessage(payload)) {
1772 // Received OPEN message; parse and signal that a new data channel should 1969 // Received OPEN message; parse and signal that a new data channel should
1773 // be created. 1970 // be created.
1774 std::string label; 1971 std::string label;
1775 InternalDataChannelInit config; 1972 InternalDataChannelInit config;
1776 config.id = params.ssrc; 1973 config.id = params.ssrc;
1777 if (!ParseDataChannelOpenMessage(payload, &label, &config)) { 1974 if (!ParseDataChannelOpenMessage(payload, &label, &config)) {
1778 LOG(LS_WARNING) << "Failed to parse the OPEN message for sid " 1975 LOG(LS_WARNING) << "Failed to parse the OPEN message for sid "
1779 << params.ssrc; 1976 << params.ssrc;
1780 return; 1977 return;
1781 } 1978 }
1782 config.open_handshake_role = InternalDataChannelInit::kAcker; 1979 config.open_handshake_role = InternalDataChannelInit::kAcker;
1783 SignalDataChannelOpenMessage(label, config); 1980 SignalDataChannelOpenMessage(label, config);
1981 } else {
1982 // Otherwise just forward the signal.
1983 SignalSctpDataReceived(params, payload);
1784 } 1984 }
1785 // Otherwise ignore the message. 1985 }
1986
1987 void WebRtcSession::OnSctpStreamClosedRemotely_n(int sid) {
1988 RTC_DCHECK(data_channel_type_ == cricket::DCT_SCTP);
1989 RTC_DCHECK(network_thread_->IsCurrent());
1990 sctp_invoker_->AsyncInvoke<void>(
1991 RTC_FROM_HERE, signaling_thread_,
1992 rtc::Bind(&sigslot::signal1<int>::operator(),
1993 &SignalSctpStreamClosedRemotely, sid));
1786 } 1994 }
1787 1995
1788 // Returns false if bundle is enabled and rtcp_mux is disabled. 1996 // Returns false if bundle is enabled and rtcp_mux is disabled.
1789 bool WebRtcSession::ValidateBundleSettings(const SessionDescription* desc) { 1997 bool WebRtcSession::ValidateBundleSettings(const SessionDescription* desc) {
1790 bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE); 1998 bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE);
1791 if (!bundle_enabled) 1999 if (!bundle_enabled)
1792 return true; 2000 return true;
1793 2001
1794 const cricket::ContentGroup* bundle_group = 2002 const cricket::ContentGroup* bundle_group =
1795 desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); 2003 desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 void WebRtcSession::ReportTransportStats() { 2177 void WebRtcSession::ReportTransportStats() {
1970 // Use a set so we don't report the same stats twice if two channels share 2178 // Use a set so we don't report the same stats twice if two channels share
1971 // a transport. 2179 // a transport.
1972 std::set<std::string> transport_names; 2180 std::set<std::string> transport_names;
1973 if (voice_channel()) { 2181 if (voice_channel()) {
1974 transport_names.insert(voice_channel()->transport_name()); 2182 transport_names.insert(voice_channel()->transport_name());
1975 } 2183 }
1976 if (video_channel()) { 2184 if (video_channel()) {
1977 transport_names.insert(video_channel()->transport_name()); 2185 transport_names.insert(video_channel()->transport_name());
1978 } 2186 }
1979 if (data_channel()) { 2187 if (rtp_data_channel()) {
1980 transport_names.insert(data_channel()->transport_name()); 2188 transport_names.insert(rtp_data_channel()->transport_name());
2189 }
2190 if (sctp_transport_name_) {
2191 transport_names.insert(*sctp_transport_name_);
1981 } 2192 }
1982 for (const auto& name : transport_names) { 2193 for (const auto& name : transport_names) {
1983 cricket::TransportStats stats; 2194 cricket::TransportStats stats;
1984 if (transport_controller_->GetStats(name, &stats)) { 2195 if (transport_controller_->GetStats(name, &stats)) {
1985 ReportBestConnectionState(stats); 2196 ReportBestConnectionState(stats);
1986 ReportNegotiatedCiphers(stats); 2197 ReportNegotiatedCiphers(stats);
1987 } 2198 }
1988 } 2199 }
1989 } 2200 }
1990 // Walk through the ConnectionInfos to gather best connection usage 2201 // Walk through the ConnectionInfos to gather best connection usage
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 const std::string WebRtcSession::GetTransportName( 2298 const std::string WebRtcSession::GetTransportName(
2088 const std::string& content_name) { 2299 const std::string& content_name) {
2089 cricket::BaseChannel* channel = GetChannel(content_name); 2300 cricket::BaseChannel* channel = GetChannel(content_name);
2090 if (!channel) { 2301 if (!channel) {
2091 #ifdef HAVE_QUIC 2302 #ifdef HAVE_QUIC
2092 if (data_channel_type_ == cricket::DCT_QUIC && quic_data_transport_ && 2303 if (data_channel_type_ == cricket::DCT_QUIC && quic_data_transport_ &&
2093 content_name == quic_data_transport_->transport_name()) { 2304 content_name == quic_data_transport_->transport_name()) {
2094 return quic_data_transport_->transport_name(); 2305 return quic_data_transport_->transport_name();
2095 } 2306 }
2096 #endif 2307 #endif
2308 if (sctp_transport_) {
2309 RTC_DCHECK(sctp_content_name_);
2310 RTC_DCHECK(sctp_transport_name_);
2311 if (content_name == *sctp_content_name_) {
2312 return *sctp_transport_name_;
2313 }
2314 }
2097 // Return an empty string if failed to retrieve the transport name. 2315 // Return an empty string if failed to retrieve the transport name.
2098 return ""; 2316 return "";
2099 } 2317 }
2100 return channel->transport_name(); 2318 return channel->transport_name();
2101 } 2319 }
2102 2320
2103 void WebRtcSession::OnDtlsHandshakeError(rtc::SSLHandshakeError error) {
2104 if (metrics_observer_) {
2105 metrics_observer_->IncrementEnumCounter(
2106 webrtc::kEnumCounterDtlsHandshakeError, static_cast<int>(error),
2107 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
2108 }
2109 }
2110 } // namespace webrtc 2321 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/api/webrtcsession.h ('k') | webrtc/api/webrtcsession_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698