Chromium Code Reviews| 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 |