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

Side by Side Diff: talk/app/webrtc/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: Revising some comments. 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
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 return cricket::CF_RELAY; 467 return cricket::CF_RELAY;
468 case PeerConnectionInterface::kNoHost: 468 case PeerConnectionInterface::kNoHost:
469 return (cricket::CF_ALL & ~cricket::CF_HOST); 469 return (cricket::CF_ALL & ~cricket::CF_HOST);
470 case PeerConnectionInterface::kAll: 470 case PeerConnectionInterface::kAll:
471 return cricket::CF_ALL; 471 return cricket::CF_ALL;
472 default: ASSERT(false); 472 default: ASSERT(false);
473 } 473 }
474 return cricket::CF_NONE; 474 return cricket::CF_NONE;
475 } 475 }
476 476
477 // Help class used to remember if a a remote peer has requested ice restart by 477 // Helper class used to remember if a remote peer has requested an ICE restart
478 // by sending a description with new ice ufrag and password. 478 // by sending a description with a new ICE ufrag and password.
479 class IceRestartAnswerLatch { 479 class IceRestartAnswerLatch {
480 public: 480 public:
481 IceRestartAnswerLatch() : ice_restart_(false) { } 481 IceRestartAnswerLatch(cricket::MediaType media_type)
482 : ice_restart_(false), media_type_(media_type) {}
482 483
483 // Returns true if CheckForRemoteIceRestart has been called with a new session 484 // Returns true if CheckForRemoteIceRestart has been called with a new session
484 // description where ice password and ufrag has changed since last time 485 // description where the ICE password and ufrag has changed since last time
485 // Reset() was called. 486 // Reset() was called.
486 bool Get() const { 487 bool Get() const {
487 return ice_restart_; 488 return ice_restart_;
488 } 489 }
489 490
490 void Reset() { 491 void Reset() { ice_restart_ = false; }
491 if (ice_restart_) {
492 ice_restart_ = false;
493 }
494 }
495 492
496 // This method has two purposes: 1. Return whether |new_desc| requests 493 // This method has two purposes: 1. Return whether |new_desc| requests
497 // an ICE restart (i.e., new ufrag/pwd). 2. If it requests an ICE restart 494 // an ICE restart (i.e., new ufrag/pwd). 2. If it requests an ICE restart
498 // and it is an OFFER, remember this in |ice_restart_| so that the next 495 // and it is an OFFER, remember this in |ice_restart_| so that the next
499 // Local Answer will be created with new ufrag and pwd. 496 // Local Answer will be created with new ufrag and pwd.
500 bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc, 497 bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc,
501 const SessionDescriptionInterface* new_desc) { 498 const SessionDescriptionInterface* new_desc) {
502 if (!old_desc) { 499 if (!old_desc) {
503 return false; 500 return false;
504 } 501 }
505 const SessionDescription* new_sd = new_desc->description(); 502 const SessionDescription* new_sd = new_desc->description();
506 const SessionDescription* old_sd = old_desc->description(); 503 const SessionDescription* old_sd = old_desc->description();
507 const ContentInfos& contents = new_sd->contents(); 504 const ContentInfo* cinfo =
508 for (size_t index = 0; index < contents.size(); ++index) { 505 GetFirstMediaContent(new_sd->contents(), media_type_);
509 const ContentInfo* cinfo = &contents[index]; 506 if (!cinfo || cinfo->rejected) {
510 if (cinfo->rejected) { 507 return false;
511 continue; 508 }
509 // If the content isn't rejected, check if ufrag and password has changed.
510 const cricket::TransportDescription* new_transport_desc =
511 new_sd->GetTransportDescriptionByName(cinfo->name);
512 const cricket::TransportDescription* old_transport_desc =
513 old_sd->GetTransportDescriptionByName(cinfo->name);
514 if (!new_transport_desc || !old_transport_desc) {
515 // No transport description exists. This is not an ICE restart.
516 return false;
517 }
518 if (cricket::IceCredentialsChanged(
519 old_transport_desc->ice_ufrag, old_transport_desc->ice_pwd,
520 new_transport_desc->ice_ufrag, new_transport_desc->ice_pwd)) {
521 LOG(LS_INFO) << "Remote peer request ice restart.";
522 if (new_desc->type() == SessionDescriptionInterface::kOffer) {
523 ice_restart_ = true;
512 } 524 }
513 // If the content isn't rejected, check if ufrag and password has 525 return true;
514 // changed.
515 const cricket::TransportDescription* new_transport_desc =
516 new_sd->GetTransportDescriptionByName(cinfo->name);
517 const cricket::TransportDescription* old_transport_desc =
518 old_sd->GetTransportDescriptionByName(cinfo->name);
519 if (!new_transport_desc || !old_transport_desc) {
520 // No transport description exist. This is not an ice restart.
521 continue;
522 }
523 if (cricket::IceCredentialsChanged(old_transport_desc->ice_ufrag,
524 old_transport_desc->ice_pwd,
525 new_transport_desc->ice_ufrag,
526 new_transport_desc->ice_pwd)) {
527 LOG(LS_INFO) << "Remote peer request ice restart.";
528 if (new_desc->type() == SessionDescriptionInterface::kOffer) {
529 ice_restart_ = true;
530 }
531 return true;
532 }
533 } 526 }
534 return false; 527 return false;
535 } 528 }
536 529
537 private: 530 private:
538 bool ice_restart_; 531 bool ice_restart_;
532 cricket::MediaType media_type_;
539 }; 533 };
540 534
541 WebRtcSession::WebRtcSession(webrtc::MediaControllerInterface* media_controller, 535 WebRtcSession::WebRtcSession(webrtc::MediaControllerInterface* media_controller,
542 rtc::Thread* signaling_thread, 536 rtc::Thread* signaling_thread,
543 rtc::Thread* worker_thread, 537 rtc::Thread* worker_thread,
544 cricket::PortAllocator* port_allocator) 538 cricket::PortAllocator* port_allocator)
545 : signaling_thread_(signaling_thread), 539 : signaling_thread_(signaling_thread),
546 worker_thread_(worker_thread), 540 worker_thread_(worker_thread),
547 port_allocator_(port_allocator), 541 port_allocator_(port_allocator),
548 // RFC 3264: The numeric value of the session id and version in the 542 // RFC 3264: The numeric value of the session id and version in the
549 // o line MUST be representable with a "64 bit signed integer". 543 // o line MUST be representable with a "64 bit signed integer".
550 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. 544 // Due to this constraint session id |sid_| is max limited to LLONG_MAX.
551 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)), 545 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
552 transport_controller_(new cricket::TransportController(signaling_thread, 546 transport_controller_(new cricket::TransportController(signaling_thread,
553 worker_thread, 547 worker_thread,
554 port_allocator)), 548 port_allocator)),
555 media_controller_(media_controller), 549 media_controller_(media_controller),
556 channel_manager_(media_controller_->channel_manager()), 550 channel_manager_(media_controller_->channel_manager()),
557 ice_observer_(NULL), 551 ice_observer_(NULL),
558 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), 552 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
559 ice_connection_receiving_(true), 553 ice_connection_receiving_(true),
560 older_version_remote_peer_(false), 554 older_version_remote_peer_(false),
561 dtls_enabled_(false), 555 dtls_enabled_(false),
562 data_channel_type_(cricket::DCT_NONE), 556 data_channel_type_(cricket::DCT_NONE),
563 ice_restart_latch_(new IceRestartAnswerLatch), 557 audio_ice_restart_latch_(
558 new IceRestartAnswerLatch(cricket::MEDIA_TYPE_AUDIO)),
559 video_ice_restart_latch_(
560 new IceRestartAnswerLatch(cricket::MEDIA_TYPE_VIDEO)),
561 data_ice_restart_latch_(
562 new IceRestartAnswerLatch(cricket::MEDIA_TYPE_DATA)),
564 metrics_observer_(NULL) { 563 metrics_observer_(NULL) {
565 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); 564 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED);
566 transport_controller_->SignalConnectionState.connect( 565 transport_controller_->SignalConnectionState.connect(
567 this, &WebRtcSession::OnTransportControllerConnectionState); 566 this, &WebRtcSession::OnTransportControllerConnectionState);
568 transport_controller_->SignalReceiving.connect( 567 transport_controller_->SignalReceiving.connect(
569 this, &WebRtcSession::OnTransportControllerReceiving); 568 this, &WebRtcSession::OnTransportControllerReceiving);
570 transport_controller_->SignalGatheringState.connect( 569 transport_controller_->SignalGatheringState.connect(
571 this, &WebRtcSession::OnTransportControllerGatheringState); 570 this, &WebRtcSession::OnTransportControllerGatheringState);
572 transport_controller_->SignalCandidatesGathered.connect( 571 transport_controller_->SignalCandidatesGathered.connect(
573 this, &WebRtcSession::OnTransportControllerCandidatesGathered); 572 this, &WebRtcSession::OnTransportControllerCandidatesGathered);
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 804
806 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) { 805 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) {
807 return false; 806 return false;
808 } 807 }
809 808
810 if (remote_desc_) { 809 if (remote_desc_) {
811 // Now that we have a local description, we can push down remote candidates. 810 // Now that we have a local description, we can push down remote candidates.
812 UseCandidatesInSessionDescription(remote_desc_.get()); 811 UseCandidatesInSessionDescription(remote_desc_.get());
813 } 812 }
814 813
814 audio_ice_restart_latch_->Reset();
815 video_ice_restart_latch_->Reset();
816 data_ice_restart_latch_->Reset();
817
815 if (error() != ERROR_NONE) { 818 if (error() != ERROR_NONE) {
816 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); 819 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc);
817 } 820 }
818 return true; 821 return true;
819 } 822 }
820 823
821 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc, 824 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
822 std::string* err_desc) { 825 std::string* err_desc) {
823 ASSERT(signaling_thread()->IsCurrent()); 826 ASSERT(signaling_thread()->IsCurrent());
824 827
(...skipping 25 matching lines...) Expand all
850 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) { 853 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) {
851 return false; 854 return false;
852 } 855 }
853 856
854 if (local_desc_ && !UseCandidatesInSessionDescription(desc)) { 857 if (local_desc_ && !UseCandidatesInSessionDescription(desc)) {
855 return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc); 858 return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc);
856 } 859 }
857 860
858 // Check if this new SessionDescription contains new ice ufrag and password 861 // Check if this new SessionDescription contains new ice ufrag and password
859 // that indicates the remote peer requests ice restart. 862 // that indicates the remote peer requests ice restart.
860 bool ice_restart = 863 // TODO(deadbeef): When we start storing both the current and pending remote
861 ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), desc); 864 // description, this should reset the latch and compare against the current
862 // We retain all received candidates only if ICE is not restarted. 865 // description.
863 // When ICE is restarted, all previous candidates belong to an old generation 866 if (!audio_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(),
864 // and should not be kept. 867 desc)) {
865 // TODO(deadbeef): This goes against the W3C spec which says the remote 868 // We retain all received candidates only if ICE is not restarted.
866 // description should only contain candidates from the last set remote 869 // When ICE is restarted, all previous candidates belong to an old
867 // description plus any candidates added since then. We should remove this 870 // generation
honghaiz3 2016/02/10 01:01:48 This and the next line can be merged.
Taylor Brandstetter 2016/02/10 21:18:32 Done.
868 // once we're sure it won't break anything. 871 // and should not be kept.
869 if (!ice_restart) { 872 // TODO(deadbeef): This goes against the W3C spec which says the remote
873 // description should only contain candidates from the last set remote
874 // description plus any candidates added since then. We should remove this
875 // once we're sure it won't break anything.
870 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( 876 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
871 old_remote_desc.get(), desc); 877 old_remote_desc.get(), cricket::MEDIA_TYPE_AUDIO, desc);
878 }
879 if (!video_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(),
880 desc)) {
881 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
882 old_remote_desc.get(), cricket::MEDIA_TYPE_VIDEO, desc);
883 }
884 if (!data_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(),
885 desc)) {
886 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
887 old_remote_desc.get(), cricket::MEDIA_TYPE_DATA, desc);
872 } 888 }
873 889
874 if (error() != ERROR_NONE) { 890 if (error() != ERROR_NONE) {
875 return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc); 891 return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc);
876 } 892 }
877 893
878 // Set the the ICE connection state to connecting since the connection may 894 // Set the the ICE connection state to connecting since the connection may
879 // become writable with peer reflexive candidates before any remote candidate 895 // become writable with peer reflexive candidates before any remote candidate
880 // is signaled. 896 // is signaled.
881 // TODO(pthatcher): This is a short-term solution for crbug/446908. A real fix 897 // TODO(pthatcher): This is a short-term solution for crbug/446908. A real fix
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 } 1474 }
1459 1475
1460 bool WebRtcSession::ReadyToSendData() const { 1476 bool WebRtcSession::ReadyToSendData() const {
1461 return data_channel_ && data_channel_->ready_to_send_data(); 1477 return data_channel_ && data_channel_->ready_to_send_data();
1462 } 1478 }
1463 1479
1464 cricket::DataChannelType WebRtcSession::data_channel_type() const { 1480 cricket::DataChannelType WebRtcSession::data_channel_type() const {
1465 return data_channel_type_; 1481 return data_channel_type_;
1466 } 1482 }
1467 1483
1468 bool WebRtcSession::IceRestartPending() const { 1484 bool WebRtcSession::AudioIceRestartPending() const {
1469 return ice_restart_latch_->Get(); 1485 return audio_ice_restart_latch_->Get();
1470 } 1486 }
1471 1487
1472 void WebRtcSession::ResetIceRestartLatch() { 1488 bool WebRtcSession::VideoIceRestartPending() const {
1473 ice_restart_latch_->Reset(); 1489 return video_ice_restart_latch_->Get();
1490 }
1491
1492 bool WebRtcSession::DataIceRestartPending() const {
1493 return data_ice_restart_latch_->Get();
1474 } 1494 }
1475 1495
1476 void WebRtcSession::OnCertificateReady( 1496 void WebRtcSession::OnCertificateReady(
1477 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { 1497 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
1478 transport_controller_->SetLocalCertificate(certificate); 1498 transport_controller_->SetLocalCertificate(certificate);
1479 } 1499 }
1480 1500
1481 bool WebRtcSession::waiting_for_certificate_for_testing() const { 1501 bool WebRtcSession::waiting_for_certificate_for_testing() const {
1482 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); 1502 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing();
1483 } 1503 }
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 } 2197 }
2178 } 2198 }
2179 2199
2180 void WebRtcSession::OnSentPacket_w(cricket::TransportChannel* channel, 2200 void WebRtcSession::OnSentPacket_w(cricket::TransportChannel* channel,
2181 const rtc::SentPacket& sent_packet) { 2201 const rtc::SentPacket& sent_packet) {
2182 RTC_DCHECK(worker_thread()->IsCurrent()); 2202 RTC_DCHECK(worker_thread()->IsCurrent());
2183 media_controller_->call_w()->OnSentPacket(sent_packet); 2203 media_controller_->call_w()->OnSentPacket(sent_packet);
2184 } 2204 }
2185 2205
2186 } // namespace webrtc 2206 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698