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

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

Issue 1671173002: Track pending ICE restarts independently for different media sections. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Merging with master. Created 4 years, 10 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 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 return cricket::CF_RELAY; 450 return cricket::CF_RELAY;
451 case PeerConnectionInterface::kNoHost: 451 case PeerConnectionInterface::kNoHost:
452 return (cricket::CF_ALL & ~cricket::CF_HOST); 452 return (cricket::CF_ALL & ~cricket::CF_HOST);
453 case PeerConnectionInterface::kAll: 453 case PeerConnectionInterface::kAll:
454 return cricket::CF_ALL; 454 return cricket::CF_ALL;
455 default: ASSERT(false); 455 default: ASSERT(false);
456 } 456 }
457 return cricket::CF_NONE; 457 return cricket::CF_NONE;
458 } 458 }
459 459
460 // Help class used to remember if a a remote peer has requested ice restart by 460 // Returns true if |new_desc| requests an ICE restart (i.e., new ufrag/pwd).
461 // by sending a description with new ice ufrag and password. 461 bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc,
462 class IceRestartAnswerLatch { 462 const SessionDescriptionInterface* new_desc,
463 public: 463 const std::string& content_name) {
464 IceRestartAnswerLatch() : ice_restart_(false) { } 464 if (!old_desc) {
465
466 // Returns true if CheckForRemoteIceRestart has been called with a new session
467 // description where ice password and ufrag has changed since last time
468 // Reset() was called.
469 bool Get() const {
470 return ice_restart_;
471 }
472
473 void Reset() {
474 if (ice_restart_) {
475 ice_restart_ = false;
476 }
477 }
478
479 // This method has two purposes: 1. Return whether |new_desc| requests
480 // an ICE restart (i.e., new ufrag/pwd). 2. If it requests an ICE restart
481 // and it is an OFFER, remember this in |ice_restart_| so that the next
482 // Local Answer will be created with new ufrag and pwd.
483 bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc,
484 const SessionDescriptionInterface* new_desc) {
485 if (!old_desc) {
486 return false;
487 }
488 const SessionDescription* new_sd = new_desc->description();
489 const SessionDescription* old_sd = old_desc->description();
490 const ContentInfos& contents = new_sd->contents();
491 for (size_t index = 0; index < contents.size(); ++index) {
492 const ContentInfo* cinfo = &contents[index];
493 if (cinfo->rejected) {
494 continue;
495 }
496 // If the content isn't rejected, check if ufrag and password has
497 // changed.
498 const cricket::TransportDescription* new_transport_desc =
499 new_sd->GetTransportDescriptionByName(cinfo->name);
500 const cricket::TransportDescription* old_transport_desc =
501 old_sd->GetTransportDescriptionByName(cinfo->name);
502 if (!new_transport_desc || !old_transport_desc) {
503 // No transport description exist. This is not an ice restart.
504 continue;
505 }
506 if (cricket::IceCredentialsChanged(old_transport_desc->ice_ufrag,
507 old_transport_desc->ice_pwd,
508 new_transport_desc->ice_ufrag,
509 new_transport_desc->ice_pwd)) {
510 LOG(LS_INFO) << "Remote peer request ice restart.";
511 if (new_desc->type() == SessionDescriptionInterface::kOffer) {
512 ice_restart_ = true;
513 }
514 return true;
515 }
516 }
517 return false; 465 return false;
518 } 466 }
519 467 const SessionDescription* new_sd = new_desc->description();
520 private: 468 const SessionDescription* old_sd = old_desc->description();
521 bool ice_restart_; 469 const ContentInfo* cinfo = new_sd->GetContentByName(content_name);
522 }; 470 if (!cinfo || cinfo->rejected) {
471 return false;
472 }
473 // If the content isn't rejected, check if ufrag and password has changed.
474 const cricket::TransportDescription* new_transport_desc =
475 new_sd->GetTransportDescriptionByName(content_name);
476 const cricket::TransportDescription* old_transport_desc =
477 old_sd->GetTransportDescriptionByName(content_name);
478 if (!new_transport_desc || !old_transport_desc) {
479 // No transport description exists. This is not an ICE restart.
480 return false;
481 }
482 if (cricket::IceCredentialsChanged(
483 old_transport_desc->ice_ufrag, old_transport_desc->ice_pwd,
484 new_transport_desc->ice_ufrag, new_transport_desc->ice_pwd)) {
485 LOG(LS_INFO) << "Remote peer requests ICE restart for " << content_name
486 << ".";
487 return true;
488 }
489 return false;
490 }
523 491
524 WebRtcSession::WebRtcSession(webrtc::MediaControllerInterface* media_controller, 492 WebRtcSession::WebRtcSession(webrtc::MediaControllerInterface* media_controller,
525 rtc::Thread* signaling_thread, 493 rtc::Thread* signaling_thread,
526 rtc::Thread* worker_thread, 494 rtc::Thread* worker_thread,
527 cricket::PortAllocator* port_allocator) 495 cricket::PortAllocator* port_allocator)
528 : signaling_thread_(signaling_thread), 496 : signaling_thread_(signaling_thread),
529 worker_thread_(worker_thread), 497 worker_thread_(worker_thread),
530 port_allocator_(port_allocator), 498 port_allocator_(port_allocator),
531 // RFC 3264: The numeric value of the session id and version in the 499 // RFC 3264: The numeric value of the session id and version in the
532 // o line MUST be representable with a "64 bit signed integer". 500 // o line MUST be representable with a "64 bit signed integer".
533 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. 501 // Due to this constraint session id |sid_| is max limited to LLONG_MAX.
534 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)), 502 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
535 transport_controller_(new cricket::TransportController(signaling_thread, 503 transport_controller_(new cricket::TransportController(signaling_thread,
536 worker_thread, 504 worker_thread,
537 port_allocator)), 505 port_allocator)),
538 media_controller_(media_controller), 506 media_controller_(media_controller),
539 channel_manager_(media_controller_->channel_manager()), 507 channel_manager_(media_controller_->channel_manager()),
540 ice_observer_(NULL), 508 ice_observer_(NULL),
541 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), 509 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
542 ice_connection_receiving_(true), 510 ice_connection_receiving_(true),
543 older_version_remote_peer_(false), 511 older_version_remote_peer_(false),
544 dtls_enabled_(false), 512 dtls_enabled_(false),
545 data_channel_type_(cricket::DCT_NONE), 513 data_channel_type_(cricket::DCT_NONE),
546 ice_restart_latch_(new IceRestartAnswerLatch),
547 metrics_observer_(NULL) { 514 metrics_observer_(NULL) {
548 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); 515 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED);
549 transport_controller_->SignalConnectionState.connect( 516 transport_controller_->SignalConnectionState.connect(
550 this, &WebRtcSession::OnTransportControllerConnectionState); 517 this, &WebRtcSession::OnTransportControllerConnectionState);
551 transport_controller_->SignalReceiving.connect( 518 transport_controller_->SignalReceiving.connect(
552 this, &WebRtcSession::OnTransportControllerReceiving); 519 this, &WebRtcSession::OnTransportControllerReceiving);
553 transport_controller_->SignalGatheringState.connect( 520 transport_controller_->SignalGatheringState.connect(
554 this, &WebRtcSession::OnTransportControllerGatheringState); 521 this, &WebRtcSession::OnTransportControllerGatheringState);
555 transport_controller_->SignalCandidatesGathered.connect( 522 transport_controller_->SignalCandidatesGathered.connect(
556 this, &WebRtcSession::OnTransportControllerCandidatesGathered); 523 this, &WebRtcSession::OnTransportControllerCandidatesGathered);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 } 652 }
686 653
687 void WebRtcSession::Close() { 654 void WebRtcSession::Close() {
688 SetState(STATE_CLOSED); 655 SetState(STATE_CLOSED);
689 RemoveUnusedChannels(nullptr); 656 RemoveUnusedChannels(nullptr);
690 ASSERT(!voice_channel_); 657 ASSERT(!voice_channel_);
691 ASSERT(!video_channel_); 658 ASSERT(!video_channel_);
692 ASSERT(!data_channel_); 659 ASSERT(!data_channel_);
693 } 660 }
694 661
662 cricket::BaseChannel* WebRtcSession::GetChannel(
663 const std::string& content_name) {
664 if (voice_channel() && voice_channel()->content_name() == content_name) {
665 return voice_channel();
666 }
667 if (video_channel() && video_channel()->content_name() == content_name) {
668 return video_channel();
669 }
670 if (data_channel() && data_channel()->content_name() == content_name) {
671 return data_channel();
672 }
673 return nullptr;
674 }
675
695 void WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) { 676 void WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) {
696 webrtc_session_desc_factory_->SetSdesPolicy(secure_policy); 677 webrtc_session_desc_factory_->SetSdesPolicy(secure_policy);
697 } 678 }
698 679
699 cricket::SecurePolicy WebRtcSession::SdesPolicy() const { 680 cricket::SecurePolicy WebRtcSession::SdesPolicy() const {
700 return webrtc_session_desc_factory_->SdesPolicy(); 681 return webrtc_session_desc_factory_->SdesPolicy();
701 } 682 }
702 683
703 bool WebRtcSession::GetSslRole(const std::string& transport_name, 684 bool WebRtcSession::GetSslRole(const std::string& transport_name,
704 rtc::SSLRole* role) { 685 rtc::SSLRole* role) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 753
773 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) { 754 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) {
774 return false; 755 return false;
775 } 756 }
776 757
777 if (remote_desc_) { 758 if (remote_desc_) {
778 // Now that we have a local description, we can push down remote candidates. 759 // Now that we have a local description, we can push down remote candidates.
779 UseCandidatesInSessionDescription(remote_desc_.get()); 760 UseCandidatesInSessionDescription(remote_desc_.get());
780 } 761 }
781 762
763 pending_ice_restarts_.clear();
764
782 if (error() != ERROR_NONE) { 765 if (error() != ERROR_NONE) {
783 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); 766 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc);
784 } 767 }
785 return true; 768 return true;
786 } 769 }
787 770
788 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc, 771 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
789 std::string* err_desc) { 772 std::string* err_desc) {
790 ASSERT(signaling_thread()->IsCurrent()); 773 ASSERT(signaling_thread()->IsCurrent());
791 774
(...skipping 23 matching lines...) Expand all
815 // NOTE: Candidates allocation will be initiated only when SetLocalDescription 798 // NOTE: Candidates allocation will be initiated only when SetLocalDescription
816 // is called. 799 // is called.
817 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) { 800 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) {
818 return false; 801 return false;
819 } 802 }
820 803
821 if (local_desc_ && !UseCandidatesInSessionDescription(desc)) { 804 if (local_desc_ && !UseCandidatesInSessionDescription(desc)) {
822 return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc); 805 return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc);
823 } 806 }
824 807
825 // Check if this new SessionDescription contains new ice ufrag and password 808 if (old_remote_desc) {
826 // that indicates the remote peer requests ice restart. 809 for (const cricket::ContentInfo& content :
827 bool ice_restart = 810 old_remote_desc->description()->contents()) {
828 ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), desc); 811 // Check if this new SessionDescription contains new ICE ufrag and
829 // We retain all received candidates only if ICE is not restarted. 812 // password that indicates the remote peer requests an ICE restart.
830 // When ICE is restarted, all previous candidates belong to an old generation 813 // TODO(deadbeef): When we start storing both the current and pending
831 // and should not be kept. 814 // remote description, this should reset pending_ice_restarts and compare
832 // TODO(deadbeef): This goes against the W3C spec which says the remote 815 // against the current description.
833 // description should only contain candidates from the last set remote 816 if (CheckForRemoteIceRestart(old_remote_desc.get(), desc, content.name)) {
834 // description plus any candidates added since then. We should remove this 817 if (action == kOffer) {
835 // once we're sure it won't break anything. 818 pending_ice_restarts_.insert(content.name);
836 if (!ice_restart) { 819 }
837 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( 820 } else {
838 old_remote_desc.get(), desc); 821 // We retain all received candidates only if ICE is not restarted.
822 // When ICE is restarted, all previous candidates belong to an old
823 // generation and should not be kept.
824 // TODO(deadbeef): This goes against the W3C spec which says the remote
825 // description should only contain candidates from the last set remote
826 // description plus any candidates added since then. We should remove
827 // this once we're sure it won't break anything.
828 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
829 old_remote_desc.get(), content.name, desc);
830 }
831 }
839 } 832 }
840 833
841 if (error() != ERROR_NONE) { 834 if (error() != ERROR_NONE) {
842 return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc); 835 return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc);
843 } 836 }
844 837
845 // Set the the ICE connection state to connecting since the connection may 838 // Set the the ICE connection state to connecting since the connection may
846 // become writable with peer reflexive candidates before any remote candidate 839 // become writable with peer reflexive candidates before any remote candidate
847 // is signaled. 840 // is signaled.
848 // TODO(pthatcher): This is a short-term solution for crbug/446908. A real fix 841 // TODO(pthatcher): This is a short-term solution for crbug/446908. A real fix
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 return transport_controller_->GetLocalCertificate(transport_name, 1080 return transport_controller_->GetLocalCertificate(transport_name,
1088 certificate); 1081 certificate);
1089 } 1082 }
1090 1083
1091 bool WebRtcSession::GetRemoteSSLCertificate(const std::string& transport_name, 1084 bool WebRtcSession::GetRemoteSSLCertificate(const std::string& transport_name,
1092 rtc::SSLCertificate** cert) { 1085 rtc::SSLCertificate** cert) {
1093 ASSERT(signaling_thread()->IsCurrent()); 1086 ASSERT(signaling_thread()->IsCurrent());
1094 return transport_controller_->GetRemoteSSLCertificate(transport_name, cert); 1087 return transport_controller_->GetRemoteSSLCertificate(transport_name, cert);
1095 } 1088 }
1096 1089
1097 cricket::BaseChannel* WebRtcSession::GetChannel(
1098 const std::string& content_name) {
1099 if (voice_channel() && voice_channel()->content_name() == content_name) {
1100 return voice_channel();
1101 }
1102 if (video_channel() && video_channel()->content_name() == content_name) {
1103 return video_channel();
1104 }
1105 if (data_channel() && data_channel()->content_name() == content_name) {
1106 return data_channel();
1107 }
1108 return nullptr;
1109 }
1110
1111 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) { 1090 bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
1112 const std::string* first_content_name = bundle.FirstContentName(); 1091 const std::string* first_content_name = bundle.FirstContentName();
1113 if (!first_content_name) { 1092 if (!first_content_name) {
1114 LOG(LS_WARNING) << "Tried to BUNDLE with no contents."; 1093 LOG(LS_WARNING) << "Tried to BUNDLE with no contents.";
1115 return false; 1094 return false;
1116 } 1095 }
1117 const std::string& transport_name = *first_content_name; 1096 const std::string& transport_name = *first_content_name;
1118 cricket::BaseChannel* first_channel = GetChannel(transport_name); 1097 cricket::BaseChannel* first_channel = GetChannel(transport_name);
1119 1098
1120 auto maybe_set_transport = [this, bundle, transport_name, 1099 auto maybe_set_transport = [this, bundle, transport_name,
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 } 1404 }
1426 1405
1427 bool WebRtcSession::ReadyToSendData() const { 1406 bool WebRtcSession::ReadyToSendData() const {
1428 return data_channel_ && data_channel_->ready_to_send_data(); 1407 return data_channel_ && data_channel_->ready_to_send_data();
1429 } 1408 }
1430 1409
1431 cricket::DataChannelType WebRtcSession::data_channel_type() const { 1410 cricket::DataChannelType WebRtcSession::data_channel_type() const {
1432 return data_channel_type_; 1411 return data_channel_type_;
1433 } 1412 }
1434 1413
1435 bool WebRtcSession::IceRestartPending() const { 1414 bool WebRtcSession::IceRestartPending(const std::string& content_name) const {
1436 return ice_restart_latch_->Get(); 1415 return pending_ice_restarts_.find(content_name) !=
1437 } 1416 pending_ice_restarts_.end();
1438
1439 void WebRtcSession::ResetIceRestartLatch() {
1440 ice_restart_latch_->Reset();
1441 } 1417 }
1442 1418
1443 void WebRtcSession::OnCertificateReady( 1419 void WebRtcSession::OnCertificateReady(
1444 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { 1420 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
1445 transport_controller_->SetLocalCertificate(certificate); 1421 transport_controller_->SetLocalCertificate(certificate);
1446 } 1422 }
1447 1423
1448 bool WebRtcSession::waiting_for_certificate_for_testing() const { 1424 bool WebRtcSession::waiting_for_certificate_for_testing() const {
1449 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); 1425 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing();
1450 } 1426 }
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 } 2119 }
2144 } 2120 }
2145 2121
2146 void WebRtcSession::OnSentPacket_w(cricket::TransportChannel* channel, 2122 void WebRtcSession::OnSentPacket_w(cricket::TransportChannel* channel,
2147 const rtc::SentPacket& sent_packet) { 2123 const rtc::SentPacket& sent_packet) {
2148 RTC_DCHECK(worker_thread()->IsCurrent()); 2124 RTC_DCHECK(worker_thread()->IsCurrent());
2149 media_controller_->call_w()->OnSentPacket(sent_packet); 2125 media_controller_->call_w()->OnSentPacket(sent_packet);
2150 } 2126 }
2151 2127
2152 } // namespace webrtc 2128 } // 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