Chromium Code Reviews| Index: webrtc/pc/mediasession.cc |
| diff --git a/webrtc/pc/mediasession.cc b/webrtc/pc/mediasession.cc |
| index dbd32566d523d3d67d8ca3be8fee17e7190fcf9f..8eed1af469bc04a341f8d5bb37cb01501381625e 100644 |
| --- a/webrtc/pc/mediasession.cc |
| +++ b/webrtc/pc/mediasession.cc |
| @@ -932,33 +932,69 @@ static void FindCodecsToOffer( |
| static bool FindByUri(const RtpHeaderExtensions& extensions, |
| const webrtc::RtpExtension& ext_to_match, |
| webrtc::RtpExtension* found_extension) { |
| + // We assume that all URIs are given in a canonical format. |
| + const webrtc::RtpExtension* found = |
| + webrtc::RtpExtension::FindHeaderExtensionByUri(extensions, |
| + ext_to_match.uri); |
| + if (!found) { |
| + return false; |
| + } |
| + if (found_extension) { |
| + *found_extension = *found; |
| + } |
| + return true; |
| +} |
| + |
| +static bool FindByUriWithEncryptionPreference( |
| + const RtpHeaderExtensions& extensions, |
| + const webrtc::RtpExtension& ext_to_match, bool encryption_preference, |
| + webrtc::RtpExtension* found_extension) { |
| + const webrtc::RtpExtension* regular_extension = nullptr; |
| for (RtpHeaderExtensions::const_iterator it = extensions.begin(); |
| it != extensions.end(); ++it) { |
| // We assume that all URIs are given in a canonical format. |
| if (it->uri == ext_to_match.uri) { |
| - if (found_extension != NULL) { |
| + if (!found_extension) { |
| + return true; |
| + } |
| + if (!encryption_preference || it->encrypt) { |
| *found_extension = *it; |
| + return true; |
| } |
| - return true; |
| + regular_extension = &(*it); |
| } |
| } |
| + if (regular_extension) { |
| + *found_extension = *regular_extension; |
| + return true; |
| + } |
| return false; |
| } |
| -// Iterates through |offered_extensions|, adding each one to |all_extensions| |
| -// and |used_ids|, and resolving ID conflicts. If an offered extension has the |
| -// same URI as one in |all_extensions|, it will re-use the same ID and won't be |
| -// treated as a conflict. |
| +// Iterates through |offered_extensions|, adding each one to |
| +// |regular_extensions| (or |encrypted_extensions| if encrypted) and |used_ids|, |
| +// and resolving ID conflicts. |
| +// If an offered extension has the same URI as one in |regular_extensions| or |
| +// |encrypted_extensions|, it will re-use the same ID and won't be treated as |
| +// a conflict. |
| static void FindAndSetRtpHdrExtUsed(RtpHeaderExtensions* offered_extensions, |
| - RtpHeaderExtensions* all_extensions, |
| + RtpHeaderExtensions* regular_extensions, |
| + RtpHeaderExtensions* encrypted_extensions, |
| UsedRtpHeaderExtensionIds* used_ids) { |
| for (auto& extension : *offered_extensions) { |
| webrtc::RtpExtension existing; |
| - if (FindByUri(*all_extensions, extension, &existing)) { |
| + if ((extension.encrypt && |
| + FindByUri(*encrypted_extensions, extension, &existing)) || |
| + (!extension.encrypt && |
| + FindByUri(*regular_extensions, extension, &existing))) { |
| extension.id = existing.id; |
| } else { |
| used_ids->FindAndSetIdUsed(&extension); |
| - all_extensions->push_back(extension); |
| + if (extension.encrypt) { |
| + encrypted_extensions->push_back(extension); |
| + } else { |
| + regular_extensions->push_back(extension); |
| + } |
| } |
| } |
| } |
| @@ -984,15 +1020,47 @@ static void FindRtpHdrExtsToOffer( |
| } |
| } |
| +static void AddEncryptedVersionsOfHdrExts(RtpHeaderExtensions* extensions, |
| + RtpHeaderExtensions* all_extensions, |
| + UsedRtpHeaderExtensionIds* used_ids) { |
| + RtpHeaderExtensions encrypted_extensions; |
| + for (const webrtc::RtpExtension& extension : *extensions) { |
| + webrtc::RtpExtension existing; |
| + // Don't add encrypted extensions again that were already included in a |
| + // previous offer or regular extensions that are also included as encrypted |
| + // extensions. |
| + if (extension.encrypt || |
| + !webrtc::RtpExtension::IsEncryptionSupported(extension.uri) || |
| + (FindByUriWithEncryptionPreference(*extensions, extension, true, |
| + &existing) && existing.encrypt)) { |
| + continue; |
| + } |
| + |
| + if (FindByUri(*all_extensions, extension, &existing)) { |
| + encrypted_extensions.push_back(existing); |
| + } else { |
| + webrtc::RtpExtension encrypted(extension); |
| + encrypted.encrypt = true; |
| + used_ids->FindAndSetIdUsed(&encrypted); |
| + all_extensions->push_back(encrypted); |
| + encrypted_extensions.push_back(encrypted); |
| + } |
| + } |
| + extensions->insert(extensions->end(), encrypted_extensions.begin(), |
| + encrypted_extensions.end()); |
|
Taylor Brandstetter
2017/04/01 00:28:59
I still think this code could be simplified... But
joachim
2017/04/17 10:46:09
Acknowledged.
|
| +} |
| + |
| static void NegotiateRtpHeaderExtensions( |
| const RtpHeaderExtensions& local_extensions, |
| const RtpHeaderExtensions& offered_extensions, |
| + bool enable_encrypted_rtp_header_extensions, |
| RtpHeaderExtensions* negotiated_extenstions) { |
| RtpHeaderExtensions::const_iterator ours; |
| for (ours = local_extensions.begin(); |
| ours != local_extensions.end(); ++ours) { |
| webrtc::RtpExtension theirs; |
| - if (FindByUri(offered_extensions, *ours, &theirs)) { |
| + if (FindByUriWithEncryptionPreference(offered_extensions, *ours, |
| + enable_encrypted_rtp_header_extensions, &theirs)) { |
| // We respond with their RTP header extension id. |
| negotiated_extenstions->push_back(theirs); |
| } |
| @@ -1027,6 +1095,7 @@ static bool CreateMediaContentAnswer( |
| const SecurePolicy& sdes_policy, |
| const CryptoParamsVec* current_cryptos, |
| const RtpHeaderExtensions& local_rtp_extenstions, |
| + bool enable_encrypted_rtp_header_extensions, |
| StreamParamsVec* current_streams, |
| bool add_legacy_stream, |
| bool bundle_enabled, |
| @@ -1038,6 +1107,7 @@ static bool CreateMediaContentAnswer( |
| RtpHeaderExtensions negotiated_rtp_extensions; |
| NegotiateRtpHeaderExtensions(local_rtp_extenstions, |
| offer->rtp_header_extensions(), |
| + enable_encrypted_rtp_header_extensions, |
| &negotiated_rtp_extensions); |
| answer->set_rtp_header_extensions(negotiated_rtp_extensions); |
| @@ -1576,7 +1646,8 @@ void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer( |
| // All header extensions allocated from the same range to avoid potential |
| // issues when using BUNDLE. |
| UsedRtpHeaderExtensionIds used_ids; |
| - RtpHeaderExtensions all_extensions; |
| + RtpHeaderExtensions all_regular_extensions; |
| + RtpHeaderExtensions all_encrypted_extensions; |
| audio_extensions->clear(); |
| video_extensions->clear(); |
| @@ -1589,22 +1660,32 @@ void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer( |
| GetFirstAudioContentDescription(current_description); |
| if (audio) { |
| *audio_extensions = audio->rtp_header_extensions(); |
| - FindAndSetRtpHdrExtUsed(audio_extensions, &all_extensions, &used_ids); |
| + FindAndSetRtpHdrExtUsed(audio_extensions, &all_regular_extensions, |
| + &all_encrypted_extensions, &used_ids); |
| } |
| const VideoContentDescription* video = |
| GetFirstVideoContentDescription(current_description); |
| if (video) { |
| *video_extensions = video->rtp_header_extensions(); |
| - FindAndSetRtpHdrExtUsed(video_extensions, &all_extensions, &used_ids); |
| + FindAndSetRtpHdrExtUsed(video_extensions, &all_regular_extensions, |
| + &all_encrypted_extensions, &used_ids); |
| } |
| } |
| // Add our default RTP header extensions that are not in |
| // |current_description|. |
| FindRtpHdrExtsToOffer(audio_rtp_header_extensions(), audio_extensions, |
| - &all_extensions, &used_ids); |
| + &all_regular_extensions, &used_ids); |
| FindRtpHdrExtsToOffer(video_rtp_header_extensions(), video_extensions, |
| - &all_extensions, &used_ids); |
| + &all_regular_extensions, &used_ids); |
| + // TODO(jbauch): Support adding encrypted header extensions to existing |
| + // sessions. |
| + if (enable_encrypted_rtp_header_extensions_ && !current_description) { |
| + AddEncryptedVersionsOfHdrExts(audio_extensions, &all_encrypted_extensions, |
| + &used_ids); |
| + AddEncryptedVersionsOfHdrExts(video_extensions, &all_encrypted_extensions, |
| + &used_ids); |
| + } |
| } |
| bool MediaSessionDescriptionFactory::AddTransportOffer( |
| @@ -1878,6 +1959,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( |
| sdes_policy, |
| GetCryptos(GetFirstAudioContentDescription(current_description)), |
| audio_rtp_extensions_, |
| + enable_encrypted_rtp_header_extensions_, |
| current_streams, |
| add_legacy_, |
| bundle_enabled, |
| @@ -1934,6 +2016,7 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( |
| sdes_policy, |
| GetCryptos(GetFirstVideoContentDescription(current_description)), |
| video_rtp_extensions_, |
| + enable_encrypted_rtp_header_extensions_, |
| current_streams, |
| add_legacy_, |
| bundle_enabled, |
| @@ -1995,6 +2078,7 @@ bool MediaSessionDescriptionFactory::AddDataContentForAnswer( |
| sdes_policy, |
| GetCryptos(GetFirstDataContentDescription(current_description)), |
| RtpHeaderExtensions(), |
| + enable_encrypted_rtp_header_extensions_, |
| current_streams, |
| add_legacy_, |
| bundle_enabled, |