OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |