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 a remote peer has requested ICE restart by |
478 // by sending a description with new ice ufrag and password. | 478 // by sending a description with 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 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 bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc, | 493 bool CheckForRemoteIceRestart(const SessionDescriptionInterface* old_desc, |
497 const SessionDescriptionInterface* new_desc) { | 494 const SessionDescriptionInterface* new_desc) { |
498 if (!old_desc || new_desc->type() != SessionDescriptionInterface::kOffer) { | 495 if (!old_desc || new_desc->type() != SessionDescriptionInterface::kOffer) { |
499 return false; | 496 return false; |
500 } | 497 } |
501 const SessionDescription* new_sd = new_desc->description(); | 498 const SessionDescription* new_sd = new_desc->description(); |
502 const SessionDescription* old_sd = old_desc->description(); | 499 const SessionDescription* old_sd = old_desc->description(); |
503 const ContentInfos& contents = new_sd->contents(); | 500 const ContentInfo* cinfo = |
504 for (size_t index = 0; index < contents.size(); ++index) { | 501 GetFirstMediaContent(new_sd->contents(), media_type_); |
505 const ContentInfo* cinfo = &contents[index]; | 502 if (!cinfo || cinfo->rejected) { |
506 if (cinfo->rejected) { | 503 return false; |
507 continue; | 504 } |
508 } | 505 // If the content isn't rejected, check if ufrag and password has changed. |
509 // If the content isn't rejected, check if ufrag and password has | 506 const cricket::TransportDescription* new_transport_desc = |
510 // changed. | 507 new_sd->GetTransportDescriptionByName(cinfo->name); |
511 const cricket::TransportDescription* new_transport_desc = | 508 const cricket::TransportDescription* old_transport_desc = |
512 new_sd->GetTransportDescriptionByName(cinfo->name); | 509 old_sd->GetTransportDescriptionByName(cinfo->name); |
513 const cricket::TransportDescription* old_transport_desc = | 510 if (!new_transport_desc || !old_transport_desc) { |
514 old_sd->GetTransportDescriptionByName(cinfo->name); | 511 // No transport description exists. This is not an ICE restart. |
515 if (!new_transport_desc || !old_transport_desc) { | 512 return false; |
516 // No transport description exist. This is not an ice restart. | 513 } |
517 continue; | 514 if (cricket::IceCredentialsChanged( |
518 } | 515 old_transport_desc->ice_ufrag, old_transport_desc->ice_pwd, |
519 if (cricket::IceCredentialsChanged(old_transport_desc->ice_ufrag, | 516 new_transport_desc->ice_ufrag, new_transport_desc->ice_pwd)) { |
520 old_transport_desc->ice_pwd, | 517 LOG(LS_INFO) << "Remote peer requested ICE restart for media type: " |
521 new_transport_desc->ice_ufrag, | 518 << media_type_; |
522 new_transport_desc->ice_pwd)) { | 519 ice_restart_ = true; |
523 LOG(LS_INFO) << "Remote peer request ice restart."; | 520 return true; |
524 ice_restart_ = true; | |
525 return true; | |
526 } | |
527 } | 521 } |
528 return false; | 522 return false; |
529 } | 523 } |
530 | 524 |
531 private: | 525 private: |
532 bool ice_restart_; | 526 bool ice_restart_; |
| 527 cricket::MediaType media_type_; |
533 }; | 528 }; |
534 | 529 |
535 WebRtcSession::WebRtcSession(webrtc::MediaControllerInterface* media_controller, | 530 WebRtcSession::WebRtcSession(webrtc::MediaControllerInterface* media_controller, |
536 rtc::Thread* signaling_thread, | 531 rtc::Thread* signaling_thread, |
537 rtc::Thread* worker_thread, | 532 rtc::Thread* worker_thread, |
538 cricket::PortAllocator* port_allocator) | 533 cricket::PortAllocator* port_allocator) |
539 : signaling_thread_(signaling_thread), | 534 : signaling_thread_(signaling_thread), |
540 worker_thread_(worker_thread), | 535 worker_thread_(worker_thread), |
541 port_allocator_(port_allocator), | 536 port_allocator_(port_allocator), |
542 // RFC 3264: The numeric value of the session id and version in the | 537 // RFC 3264: The numeric value of the session id and version in the |
543 // o line MUST be representable with a "64 bit signed integer". | 538 // o line MUST be representable with a "64 bit signed integer". |
544 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. | 539 // Due to this constraint session id |sid_| is max limited to LLONG_MAX. |
545 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)), | 540 sid_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)), |
546 transport_controller_(new cricket::TransportController(signaling_thread, | 541 transport_controller_(new cricket::TransportController(signaling_thread, |
547 worker_thread, | 542 worker_thread, |
548 port_allocator)), | 543 port_allocator)), |
549 media_controller_(media_controller), | 544 media_controller_(media_controller), |
550 channel_manager_(media_controller_->channel_manager()), | 545 channel_manager_(media_controller_->channel_manager()), |
551 ice_observer_(NULL), | 546 ice_observer_(NULL), |
552 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), | 547 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), |
553 ice_connection_receiving_(true), | 548 ice_connection_receiving_(true), |
554 older_version_remote_peer_(false), | 549 older_version_remote_peer_(false), |
555 dtls_enabled_(false), | 550 dtls_enabled_(false), |
556 data_channel_type_(cricket::DCT_NONE), | 551 data_channel_type_(cricket::DCT_NONE), |
557 ice_restart_latch_(new IceRestartAnswerLatch), | 552 audio_ice_restart_latch_( |
| 553 new IceRestartAnswerLatch(cricket::MEDIA_TYPE_AUDIO)), |
| 554 video_ice_restart_latch_( |
| 555 new IceRestartAnswerLatch(cricket::MEDIA_TYPE_VIDEO)), |
| 556 data_ice_restart_latch_( |
| 557 new IceRestartAnswerLatch(cricket::MEDIA_TYPE_DATA)), |
558 metrics_observer_(NULL) { | 558 metrics_observer_(NULL) { |
559 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); | 559 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLED); |
560 transport_controller_->SignalConnectionState.connect( | 560 transport_controller_->SignalConnectionState.connect( |
561 this, &WebRtcSession::OnTransportControllerConnectionState); | 561 this, &WebRtcSession::OnTransportControllerConnectionState); |
562 transport_controller_->SignalReceiving.connect( | 562 transport_controller_->SignalReceiving.connect( |
563 this, &WebRtcSession::OnTransportControllerReceiving); | 563 this, &WebRtcSession::OnTransportControllerReceiving); |
564 transport_controller_->SignalGatheringState.connect( | 564 transport_controller_->SignalGatheringState.connect( |
565 this, &WebRtcSession::OnTransportControllerGatheringState); | 565 this, &WebRtcSession::OnTransportControllerGatheringState); |
566 transport_controller_->SignalCandidatesGathered.connect( | 566 transport_controller_->SignalCandidatesGathered.connect( |
567 this, &WebRtcSession::OnTransportControllerCandidatesGathered); | 567 this, &WebRtcSession::OnTransportControllerCandidatesGathered); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 | 828 |
829 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) { | 829 if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) { |
830 return false; | 830 return false; |
831 } | 831 } |
832 | 832 |
833 if (remote_desc_) { | 833 if (remote_desc_) { |
834 // Now that we have a local description, we can push down remote candidates. | 834 // Now that we have a local description, we can push down remote candidates. |
835 UseCandidatesInSessionDescription(remote_desc_.get()); | 835 UseCandidatesInSessionDescription(remote_desc_.get()); |
836 } | 836 } |
837 | 837 |
| 838 audio_ice_restart_latch_->Reset(); |
| 839 video_ice_restart_latch_->Reset(); |
| 840 data_ice_restart_latch_->Reset(); |
| 841 |
838 if (error() != ERROR_NONE) { | 842 if (error() != ERROR_NONE) { |
839 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); | 843 return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc); |
840 } | 844 } |
841 return true; | 845 return true; |
842 } | 846 } |
843 | 847 |
844 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc, | 848 bool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc, |
845 std::string* err_desc) { | 849 std::string* err_desc) { |
846 ASSERT(signaling_thread()->IsCurrent()); | 850 ASSERT(signaling_thread()->IsCurrent()); |
847 | 851 |
(...skipping 23 matching lines...) Expand all Loading... |
871 // NOTE: Candidates allocation will be initiated only when SetLocalDescription | 875 // NOTE: Candidates allocation will be initiated only when SetLocalDescription |
872 // is called. | 876 // is called. |
873 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) { | 877 if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) { |
874 return false; | 878 return false; |
875 } | 879 } |
876 | 880 |
877 if (local_desc_ && !UseCandidatesInSessionDescription(desc)) { | 881 if (local_desc_ && !UseCandidatesInSessionDescription(desc)) { |
878 return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc); | 882 return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc); |
879 } | 883 } |
880 | 884 |
| 885 audio_ice_restart_latch_->Reset(); |
| 886 video_ice_restart_latch_->Reset(); |
| 887 data_ice_restart_latch_->Reset(); |
| 888 |
881 // Check if this new SessionDescription contains new ice ufrag and password | 889 // Check if this new SessionDescription contains new ice ufrag and password |
882 // that indicates the remote peer requests ice restart. | 890 // that indicates the remote peer requests ice restart. |
883 bool ice_restart = | 891 if (!audio_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), |
884 ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), desc); | 892 desc)) { |
885 // We retain all received candidates only if ICE is not restarted. | 893 // We retain all received candidates only if ICE is not restarted. |
886 // When ICE is restarted, all previous candidates belong to an old generation | 894 // When ICE is restarted, all previous candidates belong to an old |
887 // and should not be kept. | 895 // generation |
888 // TODO(deadbeef): This goes against the W3C spec which says the remote | 896 // and should not be kept. |
889 // description should only contain candidates from the last set remote | 897 // TODO(deadbeef): This goes against the W3C spec which says the remote |
890 // description plus any candidates added since then. We should remove this | 898 // description should only contain candidates from the last set remote |
891 // once we're sure it won't break anything. | 899 // description plus any candidates added since then. We should remove this |
892 if (!ice_restart) { | 900 // once we're sure it won't break anything. |
893 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( | 901 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
894 old_remote_desc.get(), desc); | 902 old_remote_desc.get(), cricket::MEDIA_TYPE_AUDIO, desc); |
| 903 } |
| 904 if (!video_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), |
| 905 desc)) { |
| 906 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
| 907 old_remote_desc.get(), cricket::MEDIA_TYPE_VIDEO, desc); |
| 908 } |
| 909 if (!data_ice_restart_latch_->CheckForRemoteIceRestart(old_remote_desc.get(), |
| 910 desc)) { |
| 911 WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
| 912 old_remote_desc.get(), cricket::MEDIA_TYPE_DATA, desc); |
895 } | 913 } |
896 | 914 |
897 if (error() != ERROR_NONE) { | 915 if (error() != ERROR_NONE) { |
898 return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc); | 916 return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc); |
899 } | 917 } |
900 | 918 |
901 // Set the the ICE connection state to connecting since the connection may | 919 // Set the the ICE connection state to connecting since the connection may |
902 // become writable with peer reflexive candidates before any remote candidate | 920 // become writable with peer reflexive candidates before any remote candidate |
903 // is signaled. | 921 // is signaled. |
904 // TODO(pthatcher): This is a short-term solution for crbug/446908. A real fix | 922 // TODO(pthatcher): This is a short-term solution for crbug/446908. A real fix |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1468 } | 1486 } |
1469 | 1487 |
1470 bool WebRtcSession::ReadyToSendData() const { | 1488 bool WebRtcSession::ReadyToSendData() const { |
1471 return data_channel_ && data_channel_->ready_to_send_data(); | 1489 return data_channel_ && data_channel_->ready_to_send_data(); |
1472 } | 1490 } |
1473 | 1491 |
1474 cricket::DataChannelType WebRtcSession::data_channel_type() const { | 1492 cricket::DataChannelType WebRtcSession::data_channel_type() const { |
1475 return data_channel_type_; | 1493 return data_channel_type_; |
1476 } | 1494 } |
1477 | 1495 |
1478 bool WebRtcSession::IceRestartPending() const { | 1496 bool WebRtcSession::AudioIceRestartPending() const { |
1479 return ice_restart_latch_->Get(); | 1497 return audio_ice_restart_latch_->Get(); |
1480 } | 1498 } |
1481 | 1499 |
1482 void WebRtcSession::ResetIceRestartLatch() { | 1500 bool WebRtcSession::VideoIceRestartPending() const { |
1483 ice_restart_latch_->Reset(); | 1501 return video_ice_restart_latch_->Get(); |
| 1502 } |
| 1503 |
| 1504 bool WebRtcSession::DataIceRestartPending() const { |
| 1505 return data_ice_restart_latch_->Get(); |
1484 } | 1506 } |
1485 | 1507 |
1486 void WebRtcSession::OnCertificateReady( | 1508 void WebRtcSession::OnCertificateReady( |
1487 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { | 1509 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
1488 transport_controller_->SetLocalCertificate(certificate); | 1510 transport_controller_->SetLocalCertificate(certificate); |
1489 } | 1511 } |
1490 | 1512 |
1491 bool WebRtcSession::waiting_for_certificate_for_testing() const { | 1513 bool WebRtcSession::waiting_for_certificate_for_testing() const { |
1492 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); | 1514 return webrtc_session_desc_factory_->waiting_for_certificate_for_testing(); |
1493 } | 1515 } |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2188 } | 2210 } |
2189 } | 2211 } |
2190 | 2212 |
2191 void WebRtcSession::OnSentPacket_w(cricket::TransportChannel* channel, | 2213 void WebRtcSession::OnSentPacket_w(cricket::TransportChannel* channel, |
2192 const rtc::SentPacket& sent_packet) { | 2214 const rtc::SentPacket& sent_packet) { |
2193 RTC_DCHECK(worker_thread()->IsCurrent()); | 2215 RTC_DCHECK(worker_thread()->IsCurrent()); |
2194 media_controller_->call_w()->OnSentPacket(sent_packet); | 2216 media_controller_->call_w()->OnSentPacket(sent_packet); |
2195 } | 2217 } |
2196 | 2218 |
2197 } // namespace webrtc | 2219 } // namespace webrtc |
OLD | NEW |