| Index: webrtc/pc/channel.cc
|
| diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc
|
| index 00f78b36c981e7440ed369b76b1f8ae69d3d5a9a..e612aaece60d7dccb851b20c5814c06f71c2cf33 100644
|
| --- a/webrtc/pc/channel.cc
|
| +++ b/webrtc/pc/channel.cc
|
| @@ -8,6 +8,8 @@
|
| * be found in the AUTHORS file in the root of the source tree.
|
| */
|
|
|
| +#include <algorithm>
|
| +#include <iterator>
|
| #include <utility>
|
|
|
| #include "webrtc/pc/channel.h"
|
| @@ -46,20 +48,6 @@ struct SendPacketMessageData : public rtc::MessageData {
|
| rtc::PacketOptions options;
|
| };
|
|
|
| -#if defined(ENABLE_EXTERNAL_AUTH)
|
| -// Returns the named header extension if found among all extensions,
|
| -// nullptr otherwise.
|
| -const webrtc::RtpExtension* FindHeaderExtension(
|
| - const std::vector<webrtc::RtpExtension>& extensions,
|
| - const std::string& uri) {
|
| - for (const auto& extension : extensions) {
|
| - if (extension.uri == uri)
|
| - return &extension;
|
| - }
|
| - return nullptr;
|
| -}
|
| -#endif
|
| -
|
| } // namespace
|
|
|
| enum {
|
| @@ -130,6 +118,7 @@ static const MediaContentDescription* GetContentDescription(
|
| template <class Codec>
|
| void RtpParametersFromMediaDescription(
|
| const MediaContentDescriptionImpl<Codec>* desc,
|
| + const RtpHeaderExtensions& extensions,
|
| RtpParameters<Codec>* params) {
|
| // TODO(pthatcher): Remove this once we're sure no one will give us
|
| // a description without codecs (currently a CA_UPDATE with just
|
| @@ -140,7 +129,7 @@ void RtpParametersFromMediaDescription(
|
| // TODO(pthatcher): See if we really need
|
| // rtp_header_extensions_set() and remove it if we don't.
|
| if (desc->rtp_header_extensions_set()) {
|
| - params->extensions = desc->rtp_header_extensions();
|
| + params->extensions = extensions;
|
| }
|
| params->rtcp.reduced_size = desc->rtcp_reduced_size();
|
| }
|
| @@ -148,8 +137,9 @@ void RtpParametersFromMediaDescription(
|
| template <class Codec>
|
| void RtpSendParametersFromMediaDescription(
|
| const MediaContentDescriptionImpl<Codec>* desc,
|
| + const RtpHeaderExtensions& extensions,
|
| RtpSendParameters<Codec>* send_params) {
|
| - RtpParametersFromMediaDescription(desc, send_params);
|
| + RtpParametersFromMediaDescription(desc, extensions, send_params);
|
| send_params->max_bandwidth_bps = desc->bandwidth();
|
| }
|
|
|
| @@ -998,16 +988,30 @@ bool BaseChannel::SetupDtlsSrtp_n(bool rtcp) {
|
| recv_key = &server_write_key;
|
| }
|
|
|
| - if (rtcp) {
|
| - ret = srtp_filter_.SetRtcpParams(selected_crypto_suite, &(*send_key)[0],
|
| - static_cast<int>(send_key->size()),
|
| - selected_crypto_suite, &(*recv_key)[0],
|
| - static_cast<int>(recv_key->size()));
|
| + if (!srtp_filter_.IsActive()) {
|
| + if (rtcp) {
|
| + ret = srtp_filter_.SetRtcpParams(selected_crypto_suite, &(*send_key)[0],
|
| + static_cast<int>(send_key->size()),
|
| + selected_crypto_suite, &(*recv_key)[0],
|
| + static_cast<int>(recv_key->size()));
|
| + } else {
|
| + ret = srtp_filter_.SetRtpParams(selected_crypto_suite, &(*send_key)[0],
|
| + static_cast<int>(send_key->size()),
|
| + selected_crypto_suite, &(*recv_key)[0],
|
| + static_cast<int>(recv_key->size()));
|
| + }
|
| } else {
|
| - ret = srtp_filter_.SetRtpParams(selected_crypto_suite, &(*send_key)[0],
|
| - static_cast<int>(send_key->size()),
|
| - selected_crypto_suite, &(*recv_key)[0],
|
| - static_cast<int>(recv_key->size()));
|
| + if (rtcp) {
|
| + // RTCP doesn't need to be updated because UpdateRtpParams is only used
|
| + // to update the set of encrypted RTP header extension IDs.
|
| + ret = true;
|
| + } else {
|
| + ret = srtp_filter_.UpdateRtpParams(
|
| + selected_crypto_suite,
|
| + &(*send_key)[0], static_cast<int>(send_key->size()),
|
| + selected_crypto_suite,
|
| + &(*recv_key)[0], static_cast<int>(recv_key->size()));
|
| + }
|
| }
|
|
|
| if (!ret) {
|
| @@ -1055,26 +1059,39 @@ bool BaseChannel::SetRtpTransportParameters(
|
| const MediaContentDescription* content,
|
| ContentAction action,
|
| ContentSource src,
|
| + const RtpHeaderExtensions& extensions,
|
| std::string* error_desc) {
|
| if (action == CA_UPDATE) {
|
| // These parameters never get changed by a CA_UDPATE.
|
| return true;
|
| }
|
|
|
| + std::vector<int> encrypted_extension_ids;
|
| + for (const webrtc::RtpExtension& extension : extensions) {
|
| + if (extension.encrypt) {
|
| + LOG(LS_INFO) << "Using " << (src == CS_LOCAL ? "local" : "remote")
|
| + << " encrypted extension: " << extension.ToString();
|
| + encrypted_extension_ids.push_back(extension.id);
|
| + }
|
| + }
|
| +
|
| // Cache srtp_required_ for belt and suspenders check on SendPacket
|
| return network_thread_->Invoke<bool>(
|
| RTC_FROM_HERE, Bind(&BaseChannel::SetRtpTransportParameters_n, this,
|
| - content, action, src, error_desc));
|
| + content, action, src, encrypted_extension_ids,
|
| + error_desc));
|
| }
|
|
|
| bool BaseChannel::SetRtpTransportParameters_n(
|
| const MediaContentDescription* content,
|
| ContentAction action,
|
| ContentSource src,
|
| + const std::vector<int>& encrypted_extension_ids,
|
| std::string* error_desc) {
|
| RTC_DCHECK(network_thread_->IsCurrent());
|
|
|
| - if (!SetSrtp_n(content->cryptos(), action, src, error_desc)) {
|
| + if (!SetSrtp_n(content->cryptos(), action, src, encrypted_extension_ids,
|
| + error_desc)) {
|
| return false;
|
| }
|
|
|
| @@ -1101,6 +1118,7 @@ bool BaseChannel::CheckSrtpConfig_n(const std::vector<CryptoParams>& cryptos,
|
| bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
|
| ContentAction action,
|
| ContentSource src,
|
| + const std::vector<int>& encrypted_extension_ids,
|
| std::string* error_desc) {
|
| TRACE_EVENT0("webrtc", "BaseChannel::SetSrtp_w");
|
| if (action == CA_UPDATE) {
|
| @@ -1113,6 +1131,7 @@ bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
|
| if (!ret) {
|
| return false;
|
| }
|
| + srtp_filter_.SetEncryptedHeaderExtensionIds(src, encrypted_extension_ids);
|
| switch (action) {
|
| case CA_OFFER:
|
| // If DTLS is already active on the channel, we could be renegotiating
|
| @@ -1138,6 +1157,14 @@ bool BaseChannel::SetSrtp_n(const std::vector<CryptoParams>& cryptos,
|
| default:
|
| break;
|
| }
|
| + // Only update SRTP filter if using DTLS. SDES is handled internally
|
| + // by the SRTP filter.
|
| + // TODO(jbauch): Only update if encrypted extension ids have changed.
|
| + if (ret && dtls_keyed_ && rtp_dtls_transport_ &&
|
| + rtp_dtls_transport_->dtls_state() == DTLS_TRANSPORT_CONNECTED) {
|
| + bool rtcp = false;
|
| + ret = SetupDtlsSrtp_n(rtcp);
|
| + }
|
| if (!ret) {
|
| SafeSetError("Failed to setup SRTP filter.", error_desc);
|
| return false;
|
| @@ -1369,6 +1396,23 @@ bool BaseChannel::UpdateRemoteStreams_w(
|
| return ret;
|
| }
|
|
|
| +RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
|
| + const RtpHeaderExtensions& extensions) {
|
| + if (!rtp_dtls_transport_ ||
|
| + !rtp_dtls_transport_->crypto_options()
|
| + .enable_encrypted_rtp_header_extensions) {
|
| + RtpHeaderExtensions filtered;
|
| + auto pred = [](const webrtc::RtpExtension& extension) {
|
| + return !extension.encrypt;
|
| + };
|
| + std::copy_if(extensions.begin(), extensions.end(),
|
| + std::back_inserter(filtered), pred);
|
| + return filtered;
|
| + }
|
| +
|
| + return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
|
| +}
|
| +
|
| void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension_w(
|
| const std::vector<webrtc::RtpExtension>& extensions) {
|
| // Absolute Send Time extension id is used only with external auth,
|
| @@ -1376,7 +1420,8 @@ void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension_w(
|
| // something that is not used.
|
| #if defined(ENABLE_EXTERNAL_AUTH)
|
| const webrtc::RtpExtension* send_time_extension =
|
| - FindHeaderExtension(extensions, webrtc::RtpExtension::kAbsSendTimeUri);
|
| + webrtc::RtpExtension::FindHeaderExtensionByUri(
|
| + extensions, webrtc::RtpExtension::kAbsSendTimeUri);
|
| int rtp_abs_sendtime_extn_id =
|
| send_time_extension ? send_time_extension->id : -1;
|
| invoker_.AsyncInvoke<void>(
|
| @@ -1724,12 +1769,16 @@ bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content,
|
| return false;
|
| }
|
|
|
| - if (!SetRtpTransportParameters(content, action, CS_LOCAL, error_desc)) {
|
| + RtpHeaderExtensions rtp_header_extensions =
|
| + GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
|
| +
|
| + if (!SetRtpTransportParameters(content, action, CS_LOCAL,
|
| + rtp_header_extensions, error_desc)) {
|
| return false;
|
| }
|
|
|
| AudioRecvParameters recv_params = last_recv_params_;
|
| - RtpParametersFromMediaDescription(audio, &recv_params);
|
| + RtpParametersFromMediaDescription(audio, rtp_header_extensions, &recv_params);
|
| if (!media_channel()->SetRecvParameters(recv_params)) {
|
| SafeSetError("Failed to set local audio description recv parameters.",
|
| error_desc);
|
| @@ -1769,12 +1818,17 @@ bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| return false;
|
| }
|
|
|
| - if (!SetRtpTransportParameters(content, action, CS_REMOTE, error_desc)) {
|
| + RtpHeaderExtensions rtp_header_extensions =
|
| + GetFilteredRtpHeaderExtensions(audio->rtp_header_extensions());
|
| +
|
| + if (!SetRtpTransportParameters(content, action, CS_REMOTE,
|
| + rtp_header_extensions, error_desc)) {
|
| return false;
|
| }
|
|
|
| AudioSendParameters send_params = last_send_params_;
|
| - RtpSendParametersFromMediaDescription(audio, &send_params);
|
| + RtpSendParametersFromMediaDescription(audio, rtp_header_extensions,
|
| + &send_params);
|
| if (audio->agc_minus_10db()) {
|
| send_params.options.adjust_agc_delta = rtc::Optional<int>(kAgcMinus10db);
|
| }
|
| @@ -1797,7 +1851,7 @@ bool VoiceChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| }
|
|
|
| if (audio->rtp_header_extensions_set()) {
|
| - MaybeCacheRtpAbsSendTimeHeaderExtension_w(audio->rtp_header_extensions());
|
| + MaybeCacheRtpAbsSendTimeHeaderExtension_w(rtp_header_extensions);
|
| }
|
|
|
| set_remote_content_direction(content->direction());
|
| @@ -2002,12 +2056,16 @@ bool VideoChannel::SetLocalContent_w(const MediaContentDescription* content,
|
| return false;
|
| }
|
|
|
| - if (!SetRtpTransportParameters(content, action, CS_LOCAL, error_desc)) {
|
| + RtpHeaderExtensions rtp_header_extensions =
|
| + GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
|
| +
|
| + if (!SetRtpTransportParameters(content, action, CS_LOCAL,
|
| + rtp_header_extensions, error_desc)) {
|
| return false;
|
| }
|
|
|
| VideoRecvParameters recv_params = last_recv_params_;
|
| - RtpParametersFromMediaDescription(video, &recv_params);
|
| + RtpParametersFromMediaDescription(video, rtp_header_extensions, &recv_params);
|
| if (!media_channel()->SetRecvParameters(recv_params)) {
|
| SafeSetError("Failed to set local video description recv parameters.",
|
| error_desc);
|
| @@ -2047,12 +2105,17 @@ bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| return false;
|
| }
|
|
|
| - if (!SetRtpTransportParameters(content, action, CS_REMOTE, error_desc)) {
|
| + RtpHeaderExtensions rtp_header_extensions =
|
| + GetFilteredRtpHeaderExtensions(video->rtp_header_extensions());
|
| +
|
| + if (!SetRtpTransportParameters(content, action, CS_REMOTE,
|
| + rtp_header_extensions, error_desc)) {
|
| return false;
|
| }
|
|
|
| VideoSendParameters send_params = last_send_params_;
|
| - RtpSendParametersFromMediaDescription(video, &send_params);
|
| + RtpSendParametersFromMediaDescription(video, rtp_header_extensions,
|
| + &send_params);
|
| if (video->conference_mode()) {
|
| send_params.conference_mode = true;
|
| }
|
| @@ -2076,7 +2139,7 @@ bool VideoChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| }
|
|
|
| if (video->rtp_header_extensions_set()) {
|
| - MaybeCacheRtpAbsSendTimeHeaderExtension_w(video->rtp_header_extensions());
|
| + MaybeCacheRtpAbsSendTimeHeaderExtension_w(rtp_header_extensions);
|
| }
|
|
|
| set_remote_content_direction(content->direction());
|
| @@ -2197,12 +2260,16 @@ bool RtpDataChannel::SetLocalContent_w(const MediaContentDescription* content,
|
| return false;
|
| }
|
|
|
| - if (!SetRtpTransportParameters(content, action, CS_LOCAL, error_desc)) {
|
| + RtpHeaderExtensions rtp_header_extensions =
|
| + GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
|
| +
|
| + if (!SetRtpTransportParameters(content, action, CS_LOCAL,
|
| + rtp_header_extensions, error_desc)) {
|
| return false;
|
| }
|
|
|
| DataRecvParameters recv_params = last_recv_params_;
|
| - RtpParametersFromMediaDescription(data, &recv_params);
|
| + RtpParametersFromMediaDescription(data, rtp_header_extensions, &recv_params);
|
| if (!media_channel()->SetRecvParameters(recv_params)) {
|
| SafeSetError("Failed to set remote data description recv parameters.",
|
| error_desc);
|
| @@ -2251,13 +2318,18 @@ bool RtpDataChannel::SetRemoteContent_w(const MediaContentDescription* content,
|
| return false;
|
| }
|
|
|
| + RtpHeaderExtensions rtp_header_extensions =
|
| + GetFilteredRtpHeaderExtensions(data->rtp_header_extensions());
|
| +
|
| LOG(LS_INFO) << "Setting remote data description";
|
| - if (!SetRtpTransportParameters(content, action, CS_REMOTE, error_desc)) {
|
| + if (!SetRtpTransportParameters(content, action, CS_REMOTE,
|
| + rtp_header_extensions, error_desc)) {
|
| return false;
|
| }
|
|
|
| DataSendParameters send_params = last_send_params_;
|
| - RtpSendParametersFromMediaDescription<DataCodec>(data, &send_params);
|
| + RtpSendParametersFromMediaDescription<DataCodec>(data, rtp_header_extensions,
|
| + &send_params);
|
| if (!media_channel()->SetSendParameters(send_params)) {
|
| SafeSetError("Failed to set remote data description send parameters.",
|
| error_desc);
|
|
|