diff options
Diffstat (limited to 'talk/session/media/mediasession.cc')
-rw-r--r-- | talk/session/media/mediasession.cc | 161 |
1 files changed, 112 insertions, 49 deletions
diff --git a/talk/session/media/mediasession.cc b/talk/session/media/mediasession.cc index 7413026092..24f01b4463 100644 --- a/talk/session/media/mediasession.cc +++ b/talk/session/media/mediasession.cc @@ -50,6 +50,17 @@ static const uint32_t kMaxSctpSid = 1023; namespace { const char kInline[] = "inline:"; + +void GetSupportedCryptoSuiteNames(void (*func)(std::vector<int>*), + std::vector<std::string>* names) { +#ifdef HAVE_SRTP + std::vector<int> crypto_suites; + func(&crypto_suites); + for (const auto crypto : crypto_suites) { + names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); + } +#endif +} } namespace cricket { @@ -152,30 +163,50 @@ bool FindMatchingCrypto(const CryptoParamsVec& cryptos, } // For audio, HMAC 32 is prefered because of the low overhead. -void GetSupportedAudioCryptoSuites( - std::vector<std::string>* crypto_suites) { +void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { #ifdef HAVE_SRTP - crypto_suites->push_back(rtc::CS_AES_CM_128_HMAC_SHA1_32); - crypto_suites->push_back(rtc::CS_AES_CM_128_HMAC_SHA1_80); + crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); + crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); #endif } -void GetSupportedVideoCryptoSuites( - std::vector<std::string>* crypto_suites) { - GetDefaultSrtpCryptoSuiteNames(crypto_suites); +void GetSupportedAudioCryptoSuiteNames( + std::vector<std::string>* crypto_suite_names) { + GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, + crypto_suite_names); +} + +void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites) { + GetDefaultSrtpCryptoSuites(crypto_suites); +} + +void GetSupportedVideoCryptoSuiteNames( + std::vector<std::string>* crypto_suite_names) { + GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, + crypto_suite_names); } -void GetSupportedDataCryptoSuites( - std::vector<std::string>* crypto_suites) { - GetDefaultSrtpCryptoSuiteNames(crypto_suites); +void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites) { + GetDefaultSrtpCryptoSuites(crypto_suites); } -void GetDefaultSrtpCryptoSuiteNames(std::vector<std::string>* crypto_suites) { +void GetSupportedDataCryptoSuiteNames( + std::vector<std::string>* crypto_suite_names) { + GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, + crypto_suite_names); +} + +void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { #ifdef HAVE_SRTP - crypto_suites->push_back(rtc::CS_AES_CM_128_HMAC_SHA1_80); + crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); #endif } +void GetDefaultSrtpCryptoSuiteNames( + std::vector<std::string>* crypto_suite_names) { + GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); +} + // For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is // tolerated unless bundle is enabled because it is low overhead. Pick the // crypto in the list that is supported. @@ -518,8 +549,8 @@ static bool AddStreamParams( // Updates the transport infos of the |sdesc| according to the given // |bundle_group|. The transport infos of the content names within the -// |bundle_group| should be updated to use the ufrag and pwd of the first -// content within the |bundle_group|. +// |bundle_group| should be updated to use the ufrag, pwd and DTLS role of the +// first content within the |bundle_group|. static bool UpdateTransportInfoForBundle(const ContentGroup& bundle_group, SessionDescription* sdesc) { // The bundle should not be empty. @@ -540,6 +571,8 @@ static bool UpdateTransportInfoForBundle(const ContentGroup& bundle_group, selected_transport_info->description.ice_ufrag; const std::string& selected_pwd = selected_transport_info->description.ice_pwd; + ConnectionRole selected_connection_role = + selected_transport_info->description.connection_role; for (TransportInfos::iterator it = sdesc->transport_infos().begin(); it != sdesc->transport_infos().end(); ++it) { @@ -547,6 +580,7 @@ static bool UpdateTransportInfoForBundle(const ContentGroup& bundle_group, it->content_name != selected_content_name) { it->description.ice_ufrag = selected_ufrag; it->description.ice_pwd = selected_pwd; + it->description.connection_role = selected_connection_role; } } return true; @@ -602,6 +636,11 @@ static void PruneCryptos(const CryptoParamsVec& filter, target_cryptos->end()); } +static bool IsRtpProtocol(const std::string& protocol) { + return protocol.empty() || + (protocol.find(cricket::kMediaProtocolRtpPrefix) != std::string::npos); +} + static bool IsRtpContent(SessionDescription* sdesc, const std::string& content_name) { bool is_rtp = false; @@ -612,9 +651,7 @@ static bool IsRtpContent(SessionDescription* sdesc, if (!media_desc) { return false; } - is_rtp = media_desc->protocol().empty() || - (media_desc->protocol().find(cricket::kMediaProtocolRtpPrefix) != - std::string::npos); + is_rtp = IsRtpProtocol(media_desc->protocol()); } return is_rtp; } @@ -726,6 +763,11 @@ static bool CreateMediaContentOffer( offer->set_crypto_required(CT_SDES); } offer->set_rtcp_mux(options.rtcp_mux_enabled); + // TODO(deadbeef): Once we're sure this works correctly, enable it in + // CreateOffer. + // if (offer->type() == cricket::MEDIA_TYPE_VIDEO) { + // offer->set_rtcp_reduced_size(true); + // } offer->set_multistream(options.is_muc); offer->set_rtp_header_extensions(rtp_extensions); @@ -1004,6 +1046,11 @@ static bool CreateMediaContentAnswer( answer->set_rtp_header_extensions(negotiated_rtp_extensions); answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); + // TODO(deadbeef): Once we're sure this works correctly, enable it in + // CreateAnswer. + // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { + // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); + // } if (sdes_policy != SEC_DISABLED) { CryptoParams crypto; @@ -1036,12 +1083,16 @@ static bool CreateMediaContentAnswer( answer->set_direction(MD_RECVONLY); break; case MD_RECVONLY: - answer->set_direction(answer->streams().empty() ? MD_INACTIVE - : MD_SENDONLY); + answer->set_direction(IsRtpProtocol(answer->protocol()) && + answer->streams().empty() + ? MD_INACTIVE + : MD_SENDONLY); break; case MD_SENDRECV: - answer->set_direction(answer->streams().empty() ? MD_RECVONLY - : MD_SENDRECV); + answer->set_direction(IsRtpProtocol(answer->protocol()) && + answer->streams().empty() + ? MD_RECVONLY + : MD_SENDRECV); break; default: RTC_DCHECK(false && "MediaContentDescription has unexpected direction."); @@ -1508,13 +1559,18 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer( const AudioCodecs& audio_codecs, StreamParamsVec* current_streams, SessionDescription* desc) const { + const ContentInfo* current_audio_content = + GetFirstAudioContent(current_description); + std::string content_name = + current_audio_content ? current_audio_content->name : CN_AUDIO; + cricket::SecurePolicy sdes_policy = - IsDtlsActive(CN_AUDIO, current_description) ? - cricket::SEC_DISABLED : secure(); + IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED + : secure(); scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); std::vector<std::string> crypto_suites; - GetSupportedAudioCryptoSuites(&crypto_suites); + GetSupportedAudioCryptoSuiteNames(&crypto_suites); if (!CreateMediaContentOffer( options, audio_codecs, @@ -1546,8 +1602,8 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer( } } - desc->AddContent(CN_AUDIO, NS_JINGLE_RTP, audio.release()); - if (!AddTransportOffer(CN_AUDIO, options.transport_options, + desc->AddContent(content_name, NS_JINGLE_RTP, audio.release()); + if (!AddTransportOffer(content_name, options.audio_transport_options, current_description, desc)) { return false; } @@ -1562,13 +1618,18 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( const VideoCodecs& video_codecs, StreamParamsVec* current_streams, SessionDescription* desc) const { + const ContentInfo* current_video_content = + GetFirstVideoContent(current_description); + std::string content_name = + current_video_content ? current_video_content->name : CN_VIDEO; + cricket::SecurePolicy sdes_policy = - IsDtlsActive(CN_VIDEO, current_description) ? - cricket::SEC_DISABLED : secure(); + IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED + : secure(); scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); std::vector<std::string> crypto_suites; - GetSupportedVideoCryptoSuites(&crypto_suites); + GetSupportedVideoCryptoSuiteNames(&crypto_suites); if (!CreateMediaContentOffer( options, video_codecs, @@ -1601,8 +1662,8 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( } } - desc->AddContent(CN_VIDEO, NS_JINGLE_RTP, video.release()); - if (!AddTransportOffer(CN_VIDEO, options.transport_options, + desc->AddContent(content_name, NS_JINGLE_RTP, video.release()); + if (!AddTransportOffer(content_name, options.video_transport_options, current_description, desc)) { return false; } @@ -1623,9 +1684,14 @@ bool MediaSessionDescriptionFactory::AddDataContentForOffer( FilterDataCodecs(data_codecs, is_sctp); + const ContentInfo* current_data_content = + GetFirstDataContent(current_description); + std::string content_name = + current_data_content ? current_data_content->name : CN_DATA; + cricket::SecurePolicy sdes_policy = - IsDtlsActive(CN_DATA, current_description) ? - cricket::SEC_DISABLED : secure(); + IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED + : secure(); std::vector<std::string> crypto_suites; if (is_sctp) { // SDES doesn't make sense for SCTP, so we disable it, and we only @@ -1638,7 +1704,7 @@ bool MediaSessionDescriptionFactory::AddDataContentForOffer( data->set_protocol( secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); } else { - GetSupportedDataCryptoSuites(&crypto_suites); + GetSupportedDataCryptoSuiteNames(&crypto_suites); } if (!CreateMediaContentOffer( @@ -1655,13 +1721,13 @@ bool MediaSessionDescriptionFactory::AddDataContentForOffer( } if (is_sctp) { - desc->AddContent(CN_DATA, NS_JINGLE_DRAFT_SCTP, data.release()); + desc->AddContent(content_name, NS_JINGLE_DRAFT_SCTP, data.release()); } else { data->set_bandwidth(options.data_bandwidth); SetMediaProtocol(secure_transport, data.get()); - desc->AddContent(CN_DATA, NS_JINGLE_RTP, data.release()); + desc->AddContent(content_name, NS_JINGLE_RTP, data.release()); } - if (!AddTransportOffer(CN_DATA, options.transport_options, + if (!AddTransportOffer(content_name, options.data_transport_options, current_description, desc)) { return false; } @@ -1676,10 +1742,9 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( SessionDescription* answer) const { const ContentInfo* audio_content = GetFirstAudioContent(offer); - scoped_ptr<TransportDescription> audio_transport( - CreateTransportAnswer(audio_content->name, offer, - options.transport_options, - current_description)); + scoped_ptr<TransportDescription> audio_transport(CreateTransportAnswer( + audio_content->name, offer, options.audio_transport_options, + current_description)); if (!audio_transport) { return false; } @@ -1735,10 +1800,9 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( StreamParamsVec* current_streams, SessionDescription* answer) const { const ContentInfo* video_content = GetFirstVideoContent(offer); - scoped_ptr<TransportDescription> video_transport( - CreateTransportAnswer(video_content->name, offer, - options.transport_options, - current_description)); + scoped_ptr<TransportDescription> video_transport(CreateTransportAnswer( + video_content->name, offer, options.video_transport_options, + current_description)); if (!video_transport) { return false; } @@ -1791,10 +1855,9 @@ bool MediaSessionDescriptionFactory::AddDataContentForAnswer( StreamParamsVec* current_streams, SessionDescription* answer) const { const ContentInfo* data_content = GetFirstDataContent(offer); - scoped_ptr<TransportDescription> data_transport( - CreateTransportAnswer(data_content->name, offer, - options.transport_options, - current_description)); + scoped_ptr<TransportDescription> data_transport(CreateTransportAnswer( + data_content->name, offer, options.data_transport_options, + current_description)); if (!data_transport) { return false; } |