OLD | NEW |
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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 if (offer_mdesc->type() != answer_mdesc->type()) { | 158 if (offer_mdesc->type() != answer_mdesc->type()) { |
159 return false; | 159 return false; |
160 } | 160 } |
161 } | 161 } |
162 return true; | 162 return true; |
163 } | 163 } |
164 | 164 |
165 // Checks that each non-rejected content has SDES crypto keys or a DTLS | 165 // Checks that each non-rejected content has SDES crypto keys or a DTLS |
166 // fingerprint. Mismatches, such as replying with a DTLS fingerprint to SDES | 166 // fingerprint. Mismatches, such as replying with a DTLS fingerprint to SDES |
167 // keys, will be caught in Transport negotiation, and backstopped by Channel's | 167 // keys, will be caught in Transport negotiation, and backstopped by Channel's |
168 // |secure_required| check. | 168 // |srtp_required| check. |
169 static bool VerifyCrypto(const SessionDescription* desc, | 169 static bool VerifyCrypto(const SessionDescription* desc, |
170 bool dtls_enabled, | 170 bool dtls_enabled, |
171 std::string* error) { | 171 std::string* error) { |
172 const ContentInfos& contents = desc->contents(); | 172 const ContentInfos& contents = desc->contents(); |
173 for (size_t index = 0; index < contents.size(); ++index) { | 173 for (size_t index = 0; index < contents.size(); ++index) { |
174 const ContentInfo* cinfo = &contents[index]; | 174 const ContentInfo* cinfo = &contents[index]; |
175 if (cinfo->rejected) { | 175 if (cinfo->rejected) { |
176 continue; | 176 continue; |
177 } | 177 } |
178 | 178 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 } | 224 } |
225 if (tinfo->description.ice_ufrag.empty() || | 225 if (tinfo->description.ice_ufrag.empty() || |
226 tinfo->description.ice_pwd.empty()) { | 226 tinfo->description.ice_pwd.empty()) { |
227 LOG(LS_ERROR) << "Session description must have ice ufrag and pwd."; | 227 LOG(LS_ERROR) << "Session description must have ice ufrag and pwd."; |
228 return false; | 228 return false; |
229 } | 229 } |
230 } | 230 } |
231 return true; | 231 return true; |
232 } | 232 } |
233 | 233 |
234 // Forces |sdesc->crypto_required| to the appropriate state based on the | |
235 // current security policy, to ensure a failure occurs if there is an error | |
236 // in crypto negotiation. | |
237 // Called when processing the local session description. | |
238 static void UpdateSessionDescriptionSecurePolicy(cricket::CryptoType type, | |
239 SessionDescription* sdesc) { | |
240 if (!sdesc) { | |
241 return; | |
242 } | |
243 | |
244 // Updating the |crypto_required_| in MediaContentDescription to the | |
245 // appropriate state based on the current security policy. | |
246 for (cricket::ContentInfos::iterator iter = sdesc->contents().begin(); | |
247 iter != sdesc->contents().end(); ++iter) { | |
248 if (cricket::IsMediaContent(&*iter)) { | |
249 MediaContentDescription* mdesc = | |
250 static_cast<MediaContentDescription*> (iter->description); | |
251 if (mdesc) { | |
252 mdesc->set_crypto_required(type); | |
253 } | |
254 } | |
255 } | |
256 } | |
257 | |
258 static bool GetAudioSsrcByTrackId(const SessionDescription* session_description, | 234 static bool GetAudioSsrcByTrackId(const SessionDescription* session_description, |
259 const std::string& track_id, | 235 const std::string& track_id, |
260 uint32_t* ssrc) { | 236 uint32_t* ssrc) { |
261 const cricket::ContentInfo* audio_info = | 237 const cricket::ContentInfo* audio_info = |
262 cricket::GetFirstAudioContent(session_description); | 238 cricket::GetFirstAudioContent(session_description); |
263 if (!audio_info) { | 239 if (!audio_info) { |
264 LOG(LS_ERROR) << "Audio not used in this call"; | 240 LOG(LS_ERROR) << "Audio not used in this call"; |
265 return false; | 241 return false; |
266 } | 242 } |
267 | 243 |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 } | 610 } |
635 if (video_channel() && video_channel()->content_name() == content_name) { | 611 if (video_channel() && video_channel()->content_name() == content_name) { |
636 return video_channel(); | 612 return video_channel(); |
637 } | 613 } |
638 if (data_channel() && data_channel()->content_name() == content_name) { | 614 if (data_channel() && data_channel()->content_name() == content_name) { |
639 return data_channel(); | 615 return data_channel(); |
640 } | 616 } |
641 return nullptr; | 617 return nullptr; |
642 } | 618 } |
643 | 619 |
644 void WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) { | |
645 webrtc_session_desc_factory_->SetSdesPolicy(secure_policy); | |
646 } | |
647 | |
648 cricket::SecurePolicy WebRtcSession::SdesPolicy() const { | 620 cricket::SecurePolicy WebRtcSession::SdesPolicy() const { |
649 return webrtc_session_desc_factory_->SdesPolicy(); | 621 return webrtc_session_desc_factory_->SdesPolicy(); |
650 } | 622 } |
651 | 623 |
652 bool WebRtcSession::GetSslRole(const std::string& transport_name, | 624 bool WebRtcSession::GetSslRole(const std::string& transport_name, |
653 rtc::SSLRole* role) { | 625 rtc::SSLRole* role) { |
654 if (!local_desc_ || !remote_desc_) { | 626 if (!local_desc_ || !remote_desc_) { |
655 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get " | 627 LOG(LS_INFO) << "Local and Remote descriptions must be applied to get " |
656 << "SSL Role of the session."; | 628 << "SSL Role of the session."; |
657 return false; | 629 return false; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 return false; | 662 return false; |
691 } | 663 } |
692 | 664 |
693 // Update the initial_offerer flag if this session is the initial_offerer. | 665 // Update the initial_offerer flag if this session is the initial_offerer. |
694 Action action = GetAction(desc->type()); | 666 Action action = GetAction(desc->type()); |
695 if (state() == STATE_INIT && action == kOffer) { | 667 if (state() == STATE_INIT && action == kOffer) { |
696 initial_offerer_ = true; | 668 initial_offerer_ = true; |
697 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); | 669 transport_controller_->SetIceRole(cricket::ICEROLE_CONTROLLING); |
698 } | 670 } |
699 | 671 |
700 cricket::SecurePolicy sdes_policy = | |
701 webrtc_session_desc_factory_->SdesPolicy(); | |
702 cricket::CryptoType crypto_required = dtls_enabled_ ? | |
703 cricket::CT_DTLS : (sdes_policy == cricket::SEC_REQUIRED ? | |
704 cricket::CT_SDES : cricket::CT_NONE); | |
705 // Update the MediaContentDescription crypto settings as per the policy set. | |
706 UpdateSessionDescriptionSecurePolicy(crypto_required, desc->description()); | |
707 | |
708 local_desc_.reset(desc_temp.release()); | 672 local_desc_.reset(desc_temp.release()); |
709 | 673 |
710 // Transport and Media channels will be created only when offer is set. | 674 // Transport and Media channels will be created only when offer is set. |
711 if (action == kOffer && !CreateChannels(local_desc_->description())) { | 675 if (action == kOffer && !CreateChannels(local_desc_->description())) { |
712 // TODO(mallinath) - Handle CreateChannel failure, as new local description | 676 // TODO(mallinath) - Handle CreateChannel failure, as new local description |
713 // is applied. Restore back to old description. | 677 // is applied. Restore back to old description. |
714 return BadLocalSdp(desc->type(), kCreateChannelFailed, err_desc); | 678 return BadLocalSdp(desc->type(), kCreateChannelFailed, err_desc); |
715 } | 679 } |
716 | 680 |
717 // Remove unused channels if MediaContentDescription is rejected. | 681 // Remove unused channels if MediaContentDescription is rejected. |
(...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 return true; | 1620 return true; |
1657 } | 1621 } |
1658 | 1622 |
1659 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content, | 1623 bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content, |
1660 const std::string* bundle_transport) { | 1624 const std::string* bundle_transport) { |
1661 bool require_rtcp_mux = | 1625 bool require_rtcp_mux = |
1662 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; | 1626 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; |
1663 bool create_rtcp_transport_channel = !require_rtcp_mux; | 1627 bool create_rtcp_transport_channel = !require_rtcp_mux; |
1664 voice_channel_.reset(channel_manager_->CreateVoiceChannel( | 1628 voice_channel_.reset(channel_manager_->CreateVoiceChannel( |
1665 media_controller_, transport_controller_.get(), content->name, | 1629 media_controller_, transport_controller_.get(), content->name, |
1666 bundle_transport, create_rtcp_transport_channel, audio_options_)); | 1630 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), |
| 1631 audio_options_)); |
1667 if (!voice_channel_) { | 1632 if (!voice_channel_) { |
1668 return false; | 1633 return false; |
1669 } | 1634 } |
1670 if (require_rtcp_mux) { | 1635 if (require_rtcp_mux) { |
1671 voice_channel_->ActivateRtcpMux(); | 1636 voice_channel_->ActivateRtcpMux(); |
1672 } | 1637 } |
1673 | 1638 |
1674 voice_channel_->SignalDtlsSetupFailure.connect( | 1639 voice_channel_->SignalDtlsSetupFailure.connect( |
1675 this, &WebRtcSession::OnDtlsSetupFailure); | 1640 this, &WebRtcSession::OnDtlsSetupFailure); |
1676 | 1641 |
1677 SignalVoiceChannelCreated(); | 1642 SignalVoiceChannelCreated(); |
1678 voice_channel_->SignalSentPacket.connect(this, | 1643 voice_channel_->SignalSentPacket.connect(this, |
1679 &WebRtcSession::OnSentPacket_w); | 1644 &WebRtcSession::OnSentPacket_w); |
1680 return true; | 1645 return true; |
1681 } | 1646 } |
1682 | 1647 |
1683 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content, | 1648 bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content, |
1684 const std::string* bundle_transport) { | 1649 const std::string* bundle_transport) { |
1685 bool require_rtcp_mux = | 1650 bool require_rtcp_mux = |
1686 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; | 1651 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; |
1687 bool create_rtcp_transport_channel = !require_rtcp_mux; | 1652 bool create_rtcp_transport_channel = !require_rtcp_mux; |
1688 video_channel_.reset(channel_manager_->CreateVideoChannel( | 1653 video_channel_.reset(channel_manager_->CreateVideoChannel( |
1689 media_controller_, transport_controller_.get(), content->name, | 1654 media_controller_, transport_controller_.get(), content->name, |
1690 bundle_transport, create_rtcp_transport_channel, video_options_)); | 1655 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), |
| 1656 video_options_)); |
1691 if (!video_channel_) { | 1657 if (!video_channel_) { |
1692 return false; | 1658 return false; |
1693 } | 1659 } |
1694 if (require_rtcp_mux) { | 1660 if (require_rtcp_mux) { |
1695 video_channel_->ActivateRtcpMux(); | 1661 video_channel_->ActivateRtcpMux(); |
1696 } | 1662 } |
1697 video_channel_->SignalDtlsSetupFailure.connect( | 1663 video_channel_->SignalDtlsSetupFailure.connect( |
1698 this, &WebRtcSession::OnDtlsSetupFailure); | 1664 this, &WebRtcSession::OnDtlsSetupFailure); |
1699 | 1665 |
1700 SignalVideoChannelCreated(); | 1666 SignalVideoChannelCreated(); |
(...skipping 11 matching lines...) Expand all Loading... |
1712 bundle_transport ? *bundle_transport : content->name; | 1678 bundle_transport ? *bundle_transport : content->name; |
1713 quic_data_transport_->SetTransport(transport_name); | 1679 quic_data_transport_->SetTransport(transport_name); |
1714 return true; | 1680 return true; |
1715 } | 1681 } |
1716 #endif // HAVE_QUIC | 1682 #endif // HAVE_QUIC |
1717 bool sctp = (data_channel_type_ == cricket::DCT_SCTP); | 1683 bool sctp = (data_channel_type_ == cricket::DCT_SCTP); |
1718 bool require_rtcp_mux = | 1684 bool require_rtcp_mux = |
1719 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; | 1685 rtcp_mux_policy_ == PeerConnectionInterface::kRtcpMuxPolicyRequire; |
1720 bool create_rtcp_transport_channel = !sctp && !require_rtcp_mux; | 1686 bool create_rtcp_transport_channel = !sctp && !require_rtcp_mux; |
1721 data_channel_.reset(channel_manager_->CreateDataChannel( | 1687 data_channel_.reset(channel_manager_->CreateDataChannel( |
1722 transport_controller_.get(), media_controller_, content->name, | 1688 media_controller_, transport_controller_.get(), content->name, |
1723 bundle_transport, create_rtcp_transport_channel, data_channel_type_)); | 1689 bundle_transport, create_rtcp_transport_channel, SrtpRequired(), |
| 1690 data_channel_type_)); |
1724 if (!data_channel_) { | 1691 if (!data_channel_) { |
1725 return false; | 1692 return false; |
1726 } | 1693 } |
1727 if (require_rtcp_mux) { | 1694 if (require_rtcp_mux) { |
1728 data_channel_->ActivateRtcpMux(); | 1695 data_channel_->ActivateRtcpMux(); |
1729 } | 1696 } |
1730 | 1697 |
1731 if (sctp) { | 1698 if (sctp) { |
1732 data_channel_->SignalDataReceived.connect( | 1699 data_channel_->SignalDataReceived.connect( |
1733 this, &WebRtcSession::OnDataChannelMessageReceived); | 1700 this, &WebRtcSession::OnDataChannelMessageReceived); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1921 cricket::ContentInfo content = | 1888 cricket::ContentInfo content = |
1922 current_remote_desc->description()->contents()[mediacontent_index]; | 1889 current_remote_desc->description()->contents()[mediacontent_index]; |
1923 | 1890 |
1924 const std::string transport_name = GetTransportName(content.name); | 1891 const std::string transport_name = GetTransportName(content.name); |
1925 if (transport_name.empty()) { | 1892 if (transport_name.empty()) { |
1926 return false; | 1893 return false; |
1927 } | 1894 } |
1928 return transport_controller_->ReadyForRemoteCandidates(transport_name); | 1895 return transport_controller_->ReadyForRemoteCandidates(transport_name); |
1929 } | 1896 } |
1930 | 1897 |
| 1898 bool WebRtcSession::SrtpRequired() const { |
| 1899 return dtls_enabled_ || |
| 1900 webrtc_session_desc_factory_->SdesPolicy() == cricket::SEC_REQUIRED; |
| 1901 } |
| 1902 |
1931 void WebRtcSession::OnTransportControllerGatheringState( | 1903 void WebRtcSession::OnTransportControllerGatheringState( |
1932 cricket::IceGatheringState state) { | 1904 cricket::IceGatheringState state) { |
1933 ASSERT(signaling_thread()->IsCurrent()); | 1905 ASSERT(signaling_thread()->IsCurrent()); |
1934 if (state == cricket::kIceGatheringGathering) { | 1906 if (state == cricket::kIceGatheringGathering) { |
1935 if (ice_observer_) { | 1907 if (ice_observer_) { |
1936 ice_observer_->OnIceGatheringChange( | 1908 ice_observer_->OnIceGatheringChange( |
1937 PeerConnectionInterface::kIceGatheringGathering); | 1909 PeerConnectionInterface::kIceGatheringGathering); |
1938 } | 1910 } |
1939 } else if (state == cricket::kIceGatheringComplete) { | 1911 } else if (state == cricket::kIceGatheringComplete) { |
1940 if (ice_observer_) { | 1912 if (ice_observer_) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2079 } | 2051 } |
2080 | 2052 |
2081 void WebRtcSession::OnDtlsHandshakeError(rtc::SSLHandshakeError error) { | 2053 void WebRtcSession::OnDtlsHandshakeError(rtc::SSLHandshakeError error) { |
2082 if (metrics_observer_) { | 2054 if (metrics_observer_) { |
2083 metrics_observer_->IncrementEnumCounter( | 2055 metrics_observer_->IncrementEnumCounter( |
2084 webrtc::kEnumCounterDtlsHandshakeError, static_cast<int>(error), | 2056 webrtc::kEnumCounterDtlsHandshakeError, static_cast<int>(error), |
2085 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE)); | 2057 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE)); |
2086 } | 2058 } |
2087 } | 2059 } |
2088 } // namespace webrtc | 2060 } // namespace webrtc |
OLD | NEW |