diff options
Diffstat (limited to 'third_party/libwebrtc/pc')
40 files changed, 793 insertions, 2727 deletions
diff --git a/third_party/libwebrtc/pc/BUILD.gn b/third_party/libwebrtc/pc/BUILD.gn index e351748485..6f21d00bc9 100644 --- a/third_party/libwebrtc/pc/BUILD.gn +++ b/third_party/libwebrtc/pc/BUILD.gn @@ -87,6 +87,7 @@ rtc_source_set("channel") { "../media:rtp_utils", "../media:stream_params", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:dtls_transport_internal", "../p2p:rtc_p2p", "../rtc_base:async_packet_socket", "../rtc_base:checks", @@ -134,6 +135,8 @@ rtc_source_set("dtls_srtp_transport") { "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", "../api:rtc_error", + "../p2p:dtls_transport_internal", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:buffer", "../rtc_base:checks", @@ -157,6 +160,8 @@ rtc_source_set("dtls_transport") { "../api:make_ref_counted", "../api:scoped_refptr", "../api:sequence_checker", + "../p2p:dtls_transport", + "../p2p:dtls_transport_internal", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:logging", @@ -213,7 +218,6 @@ rtc_source_set("jsep_transport") { ":rtp_transport_internal", ":sctp_transport", ":session_description", - ":srtp_filter", ":srtp_transport", ":transport_stats", "../api:array_view", @@ -225,7 +229,14 @@ rtc_source_set("jsep_transport") { "../api:sequence_checker", "../api/transport:datagram_transport_interface", "../media:rtc_data_sctp_transport_internal", + "../p2p:dtls_transport", + "../p2p:dtls_transport_internal", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", "../rtc_base:event_tracer", @@ -249,6 +260,7 @@ rtc_source_set("jsep_transport_collection") { ":session_description", "../api:libjingle_peerconnection_api", "../api:sequence_checker", + "../p2p:p2p_constants", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:logging", @@ -295,7 +307,19 @@ rtc_source_set("jsep_transport_controller") { "../api/transport:enums", "../api/transport:sctp_transport_factory_interface", "../media:rtc_data_sctp_transport_internal", + "../p2p:connection", + "../p2p:dtls_transport", + "../p2p:dtls_transport_factory", + "../p2p:dtls_transport_internal", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", + "../p2p:packet_transport_internal", + "../p2p:port", + "../p2p:port_allocator", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:callback_list", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", @@ -347,7 +371,12 @@ rtc_source_set("media_session") { "../media:rtc_media_base", "../media:rtc_sdp_video_format_utils", "../media:stream_params", + "../p2p:ice_credentials_iterator", + "../p2p:p2p_constants", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_description_factory", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:ssl", @@ -396,6 +425,7 @@ rtc_source_set("peer_connection_proxy") { deps = [ ":proxy", "../api:libjingle_peerconnection_api", + "../api/transport:bandwidth_estimation_settings", ] } @@ -459,6 +489,7 @@ rtc_source_set("rtp_transport") { "../media:rtc_media_base", "../media:rtp_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:async_packet_socket", "../rtc_base:checks", @@ -484,6 +515,7 @@ rtc_source_set("rtp_transport_internal") { deps = [ ":session_description", "../call:rtp_receiver", + "../p2p:ice_transport_internal", "../p2p:rtc_p2p", "../rtc_base:callback_list", "../rtc_base:network_route", @@ -505,6 +537,7 @@ rtc_source_set("sctp_transport") { "../api:sequence_checker", "../api/transport:datagram_transport_interface", "../media:rtc_data_sctp_transport_internal", + "../p2p:dtls_transport_internal", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:logging", @@ -539,29 +572,6 @@ rtc_source_set("sctp_utils") { ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } -rtc_source_set("srtp_filter") { - visibility = [ ":*" ] - sources = [ - "srtp_filter.cc", - "srtp_filter.h", - ] - deps = [ - ":session_description", - "../api:array_view", - "../api:libjingle_peerconnection_api", - "../api:sequence_checker", - "../rtc_base:buffer", - "../rtc_base:logging", - "../rtc_base:ssl", - "../rtc_base:zero_memory", - "../rtc_base/third_party/base64", - ] - absl_deps = [ - "//third_party/abseil-cpp/absl/strings", - "//third_party/abseil-cpp/absl/types:optional", - ] -} - rtc_source_set("srtp_session") { visibility = [ ":*" ] sources = [ @@ -608,6 +618,7 @@ rtc_source_set("srtp_transport") { "../media:rtc_media_base", "../media:rtp_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:async_packet_socket", "../rtc_base:buffer", @@ -636,6 +647,10 @@ rtc_source_set("transport_stats") { deps = [ "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", + "../p2p:connection", + "../p2p:dtls_transport_internal", + "../p2p:ice_transport_internal", + "../p2p:port", "../p2p:rtc_p2p", "../rtc_base:ssl", ] @@ -693,6 +708,8 @@ rtc_source_set("session_description") { "../media:rtc_media_base", "../media:stream_params", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:socket_address", "../rtc_base:stringutils", @@ -802,6 +819,7 @@ rtc_library("connection_context") { "../api/transport:sctp_transport_factory_interface", "../media:rtc_data_sctp_transport_factory", "../media:rtc_media_base", + "../p2p:basic_packet_socket_factory", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:macromagic", @@ -911,6 +929,11 @@ rtc_source_set("rtc_stats_collector") { "../modules/audio_device", "../modules/audio_processing:audio_processing_statistics", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:connection", + "../p2p:connection_info", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:port", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:event_tracer", @@ -945,6 +968,7 @@ rtc_source_set("rtc_stats_traversal") { "../api:scoped_refptr", "../rtc_base:checks", ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } rtc_source_set("sdp_offer_answer") { @@ -1003,7 +1027,16 @@ rtc_source_set("sdp_offer_answer") { "../media:rid_description", "../media:rtc_media_base", "../media:stream_params", + "../p2p:connection", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", + "../p2p:port", + "../p2p:port_allocator", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_description_factory", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:event_tracer", "../rtc_base:logging", @@ -1108,7 +1141,18 @@ rtc_source_set("peer_connection") { "../media:rtc_media_config", "../media:stream_params", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:basic_async_resolver_factory", + "../p2p:connection", + "../p2p:connection_info", + "../p2p:dtls_transport_internal", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", + "../p2p:port", + "../p2p:port_allocator", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", "../rtc_base:event_tracer", @@ -1164,6 +1208,7 @@ rtc_source_set("sdp_utils") { ":session_description", "../api:libjingle_peerconnection_api", "../p2p:rtc_p2p", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base/system:rtc_export", ] @@ -1199,6 +1244,11 @@ rtc_source_set("legacy_stats_collector") { "../media:media_channel", "../media:rtc_media_base", "../modules/audio_processing:audio_processing_statistics", + "../p2p:connection", + "../p2p:connection_info", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:port", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:event_tracer", @@ -1272,7 +1322,15 @@ rtc_source_set("webrtc_sdp") { "../media:rtc_media_base", "../media:rtp_utils", "../media:stream_params", + "../p2p:candidate_pair_interface", + "../p2p:connection", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:port", + "../p2p:port_interface", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:ip_address", "../rtc_base:logging", @@ -1307,6 +1365,8 @@ rtc_source_set("webrtc_session_description_factory") { "../api:sequence_checker", "../api/task_queue", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_description_factory", "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:rtc_certificate_generator", @@ -1333,6 +1393,10 @@ rtc_library("ice_server_parsing") { deps = [ "../api:libjingle_peerconnection_api", "../api:rtc_error", + "../p2p:connection", + "../p2p:port", + "../p2p:port_allocator", + "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:ip_address", @@ -1395,6 +1459,11 @@ rtc_source_set("peer_connection_factory") { "../call:rtp_interfaces", "../call:rtp_sender", "../media:rtc_media_base", + "../p2p:basic_packet_socket_factory", + "../p2p:basic_port_allocator", + "../p2p:connection", + "../p2p:default_ice_transport_factory", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../pc:audio_track", "../pc:connection_context", @@ -1955,7 +2024,6 @@ if (rtc_include_tests && !build_with_chromium) { "rtp_transport_unittest.cc", "sctp_transport_unittest.cc", "session_description_unittest.cc", - "srtp_filter_unittest.cc", "srtp_session_unittest.cc", "srtp_transport_unittest.cc", "test/rtp_transport_test_util.h", @@ -1990,7 +2058,6 @@ if (rtc_include_tests && !build_with_chromium) { ":rtp_transport_internal", ":sctp_transport", ":session_description", - ":srtp_filter", ":srtp_session", ":srtp_transport", ":used_ids", @@ -2025,10 +2092,18 @@ if (rtc_include_tests && !build_with_chromium) { "../media:rtc_media_base", "../media:rtc_media_tests_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:candidate_pair_interface", + "../p2p:dtls_transport_factory", + "../p2p:dtls_transport_internal", "../p2p:fake_ice_transport", "../p2p:fake_port_allocator", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", "../p2p:p2p_test_utils", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", + "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:async_packet_socket", "../rtc_base:buffer", "../rtc_base:byte_order", @@ -2110,7 +2185,11 @@ if (rtc_include_tests && !build_with_chromium) { "../media:rtc_media_tests_utils", "../modules/audio_device:audio_device_api", "../modules/audio_processing:api", + "../p2p:basic_port_allocator", + "../p2p:connection", "../p2p:p2p_test_utils", + "../p2p:port_allocator", + "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:gunit_helpers", @@ -2161,8 +2240,11 @@ if (rtc_include_tests && !build_with_chromium) { "../api:libjingle_peerconnection_api", "../api:scoped_refptr", "../api/units:time_delta", + "../p2p:connection", "../p2p:p2p_server_utils", "../p2p:p2p_test_utils", + "../p2p:port_allocator", + "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:gunit_helpers", "../rtc_base:logging", @@ -2342,8 +2424,19 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_device:audio_device_api", "../modules/audio_processing:audio_processing_statistics", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:basic_port_allocator", + "../p2p:connection", + "../p2p:connection_info", + "../p2p:dtls_transport_internal", "../p2p:fake_port_allocator", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", "../p2p:p2p_server_utils", + "../p2p:port", + "../p2p:port_allocator", + "../p2p:port_interface", + "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:byte_buffer", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", @@ -2552,10 +2645,17 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_processing:audio_processing_statistics", "../modules/audio_processing:audioproc_test_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:basic_port_allocator", + "../p2p:connection", "../p2p:fake_ice_transport", "../p2p:fake_port_allocator", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", "../p2p:p2p_server_utils", "../p2p:p2p_test_utils", + "../p2p:port", + "../p2p:port_allocator", + "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:gunit_helpers", @@ -2702,8 +2802,10 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_processing", "../modules/audio_processing:api", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:connection", "../p2p:fake_port_allocator", "../p2p:p2p_test_utils", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:gunit_helpers", diff --git a/third_party/libwebrtc/pc/dtls_srtp_transport.h b/third_party/libwebrtc/pc/dtls_srtp_transport.h index 995809ed4b..654eb2f628 100644 --- a/third_party/libwebrtc/pc/dtls_srtp_transport.h +++ b/third_party/libwebrtc/pc/dtls_srtp_transport.h @@ -16,7 +16,6 @@ #include <vector> #include "absl/types/optional.h" -#include "api/crypto_params.h" #include "api/dtls_transport_interface.h" #include "api/rtc_error.h" #include "p2p/base/dtls_transport_internal.h" diff --git a/third_party/libwebrtc/pc/jsep_transport.cc b/third_party/libwebrtc/pc/jsep_transport.cc index 2398a0ad2d..faff4e8cf4 100644 --- a/third_party/libwebrtc/pc/jsep_transport.cc +++ b/third_party/libwebrtc/pc/jsep_transport.cc @@ -36,12 +36,10 @@ JsepTransportDescription::JsepTransportDescription() {} JsepTransportDescription::JsepTransportDescription( bool rtcp_mux_enabled, - const std::vector<CryptoParams>& cryptos, const std::vector<int>& encrypted_header_extension_ids, int rtp_abs_sendtime_extn_id, const TransportDescription& transport_desc) : rtcp_mux_enabled(rtcp_mux_enabled), - cryptos(cryptos), encrypted_header_extension_ids(encrypted_header_extension_ids), rtp_abs_sendtime_extn_id(rtp_abs_sendtime_extn_id), transport_desc(transport_desc) {} @@ -49,7 +47,6 @@ JsepTransportDescription::JsepTransportDescription( JsepTransportDescription::JsepTransportDescription( const JsepTransportDescription& from) : rtcp_mux_enabled(from.rtcp_mux_enabled), - cryptos(from.cryptos), encrypted_header_extension_ids(from.encrypted_header_extension_ids), rtp_abs_sendtime_extn_id(from.rtp_abs_sendtime_extn_id), transport_desc(from.transport_desc) {} @@ -62,7 +59,6 @@ JsepTransportDescription& JsepTransportDescription::operator=( return *this; } rtcp_mux_enabled = from.rtcp_mux_enabled; - cryptos = from.cryptos; encrypted_header_extension_ids = from.encrypted_header_extension_ids; rtp_abs_sendtime_extn_id = from.rtp_abs_sendtime_extn_id; transport_desc = from.transport_desc; @@ -167,17 +163,7 @@ webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription( "Failed to setup RTCP mux."); } - // If doing SDES, setup the SDES crypto parameters. - if (sdes_transport_) { - RTC_DCHECK(!unencrypted_rtp_transport_); - RTC_DCHECK(!dtls_srtp_transport_); - if (!SetSdes(jsep_description.cryptos, - jsep_description.encrypted_header_extension_ids, type, - ContentSource::CS_LOCAL)) { - return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, - "Failed to setup SDES crypto parameters."); - } - } else if (dtls_srtp_transport_) { + if (dtls_srtp_transport_) { RTC_DCHECK(!unencrypted_rtp_transport_); RTC_DCHECK(!sdes_transport_); dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds( @@ -254,19 +240,7 @@ webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription( "Failed to setup RTCP mux."); } - // If doing SDES, setup the SDES crypto parameters. - if (sdes_transport_) { - RTC_DCHECK(!unencrypted_rtp_transport_); - RTC_DCHECK(!dtls_srtp_transport_); - if (!SetSdes(jsep_description.cryptos, - jsep_description.encrypted_header_extension_ids, type, - ContentSource::CS_REMOTE)) { - return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, - "Failed to setup SDES crypto parameters."); - } - sdes_transport_->CacheRtpAbsSendTimeHeaderExtension( - jsep_description.rtp_abs_sendtime_extn_id); - } else if (dtls_srtp_transport_) { + if (dtls_srtp_transport_) { RTC_DCHECK(!unencrypted_rtp_transport_); RTC_DCHECK(!sdes_transport_); dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds( @@ -474,51 +448,6 @@ void JsepTransport::ActivateRtcpMux() { rtcp_mux_active_callback_(); } -bool JsepTransport::SetSdes(const std::vector<CryptoParams>& cryptos, - const std::vector<int>& encrypted_extension_ids, - webrtc::SdpType type, - ContentSource source) { - RTC_DCHECK_RUN_ON(network_thread_); - bool ret = false; - ret = sdes_negotiator_.Process(cryptos, type, source); - if (!ret) { - return ret; - } - - if (source == ContentSource::CS_LOCAL) { - recv_extension_ids_ = encrypted_extension_ids; - } else { - send_extension_ids_ = encrypted_extension_ids; - } - - // If setting an SDES answer succeeded, apply the negotiated parameters - // to the SRTP transport. - if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) { - if (sdes_negotiator_.send_crypto_suite() && - sdes_negotiator_.recv_crypto_suite()) { - RTC_DCHECK(send_extension_ids_); - RTC_DCHECK(recv_extension_ids_); - ret = sdes_transport_->SetRtpParams( - *(sdes_negotiator_.send_crypto_suite()), - sdes_negotiator_.send_key().data(), - static_cast<int>(sdes_negotiator_.send_key().size()), - *(send_extension_ids_), *(sdes_negotiator_.recv_crypto_suite()), - sdes_negotiator_.recv_key().data(), - static_cast<int>(sdes_negotiator_.recv_key().size()), - *(recv_extension_ids_)); - } else { - RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES."; - if (type == SdpType::kAnswer) { - // Explicitly reset the `sdes_transport_` if no crypto param is - // provided in the answer. No need to call `ResetParams()` for - // `sdes_negotiator_` because it resets the params inside `SetAnswer`. - sdes_transport_->ResetParams(); - } - } - } - return ret; -} - webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters( SdpType local_description_type) { RTC_DCHECK_RUN_ON(network_thread_); diff --git a/third_party/libwebrtc/pc/jsep_transport.h b/third_party/libwebrtc/pc/jsep_transport.h index f2643070a1..af0c797fc8 100644 --- a/third_party/libwebrtc/pc/jsep_transport.h +++ b/third_party/libwebrtc/pc/jsep_transport.h @@ -19,7 +19,6 @@ #include "absl/types/optional.h" #include "api/candidate.h" -#include "api/crypto_params.h" #include "api/ice_transport_interface.h" #include "api/jsep.h" #include "api/rtc_error.h" @@ -40,7 +39,6 @@ #include "pc/rtp_transport_internal.h" #include "pc/sctp_transport.h" #include "pc/session_description.h" -#include "pc/srtp_filter.h" #include "pc/srtp_transport.h" #include "pc/transport_stats.h" #include "rtc_base/checks.h" @@ -59,7 +57,6 @@ struct JsepTransportDescription { JsepTransportDescription(); JsepTransportDescription( bool rtcp_mux_enabled, - const std::vector<CryptoParams>& cryptos, const std::vector<int>& encrypted_header_extension_ids, int rtp_abs_sendtime_extn_id, const TransportDescription& transport_description); @@ -69,7 +66,6 @@ struct JsepTransportDescription { JsepTransportDescription& operator=(const JsepTransportDescription& from); bool rtcp_mux_enabled = true; - std::vector<CryptoParams> cryptos; std::vector<int> encrypted_header_extension_ids; int rtp_abs_sendtime_extn_id = -1; // TODO(zhihuang): Add the ICE and DTLS related variables and methods from @@ -243,11 +239,6 @@ class JsepTransport { void ActivateRtcpMux() RTC_RUN_ON(network_thread_); - bool SetSdes(const std::vector<CryptoParams>& cryptos, - const std::vector<int>& encrypted_extension_ids, - webrtc::SdpType type, - ContentSource source); - // Negotiates and sets the DTLS parameters based on the current local and // remote transport description, such as the DTLS role to use, and whether // DTLS should be activated. @@ -310,7 +301,6 @@ class JsepTransport { const rtc::scoped_refptr<webrtc::SctpTransport> sctp_transport_; - SrtpFilter sdes_negotiator_ RTC_GUARDED_BY(network_thread_); RtcpMuxFilter rtcp_mux_negotiator_ RTC_GUARDED_BY(network_thread_); // Cache the encrypted header extension IDs for SDES negoitation. diff --git a/third_party/libwebrtc/pc/jsep_transport_controller.cc b/third_party/libwebrtc/pc/jsep_transport_controller.cc index d5d1cd24a9..d5eb0c633d 100644 --- a/third_party/libwebrtc/pc/jsep_transport_controller.cc +++ b/third_party/libwebrtc/pc/jsep_transport_controller.cc @@ -55,6 +55,7 @@ JsepTransportController::JsepTransportController( }), config_(std::move(config)), active_reset_srtp_params_(config.active_reset_srtp_params), + ice_tiebreaker_(port_allocator ? port_allocator->ice_tiebreaker() : 0), bundles_(config.bundle_policy) { // The `transport_observer` is assumed to be non-null. RTC_DCHECK(config_.transport_observer); @@ -62,9 +63,6 @@ JsepTransportController::JsepTransportController( RTC_DCHECK(config_.ice_transport_factory); RTC_DCHECK(config_.on_dtls_handshake_error_); RTC_DCHECK(config_.field_trials); - if (port_allocator_) { - port_allocator_->SetIceTiebreaker(ice_tiebreaker_); - } } JsepTransportController::~JsepTransportController() { @@ -951,8 +949,8 @@ JsepTransportController::CreateJsepTransportDescription( : content_desc->rtcp_mux(); return cricket::JsepTransportDescription( - rtcp_mux_enabled, content_desc->cryptos(), encrypted_extension_ids, - rtp_abs_sendtime_extn_id, transport_info.description); + rtcp_mux_enabled, encrypted_extension_ids, rtp_abs_sendtime_extn_id, + transport_info.description); } std::vector<int> JsepTransportController::GetEncryptedHeaderExtensionIds( @@ -1058,12 +1056,6 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( if (transport) { return RTCError::OK(); } - const cricket::MediaContentDescription* content_desc = - content_info.media_description(); - if (certificate_ && !content_desc->cryptos().empty()) { - return RTCError(RTCErrorType::INVALID_PARAMETER, - "SDES and DTLS-SRTP cannot be enabled at the same time."); - } rtc::scoped_refptr<IceTransportInterface> ice = CreateIceTransport(content_info.name, /*rtcp=*/false); @@ -1090,10 +1082,6 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( << "Creating UnencryptedRtpTransport, becayse encryption is disabled."; unencrypted_rtp_transport = CreateUnencryptedRtpTransport( content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get()); - } else if (!content_desc->cryptos().empty()) { - sdes_transport = CreateSdesTransport( - content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get()); - RTC_LOG(LS_INFO) << "Creating SdesTransport."; } else { RTC_LOG(LS_INFO) << "Creating DtlsSrtpTransport."; dtls_srtp_transport = CreateDtlsSrtpTransport( @@ -1214,7 +1202,7 @@ void JsepTransportController::OnTransportCandidateGathered_n( cricket::IceTransportInternal* transport, const cricket::Candidate& candidate) { // We should never signal peer-reflexive candidates. - if (candidate.type() == cricket::PRFLX_PORT_TYPE) { + if (candidate.is_prflx()) { RTC_DCHECK_NOTREACHED(); return; } diff --git a/third_party/libwebrtc/pc/jsep_transport_controller.h b/third_party/libwebrtc/pc/jsep_transport_controller.h index 448844ac79..7f06c22969 100644 --- a/third_party/libwebrtc/pc/jsep_transport_controller.h +++ b/third_party/libwebrtc/pc/jsep_transport_controller.h @@ -507,7 +507,7 @@ class JsepTransportController : public sigslot::has_slots<> { cricket::IceConfig ice_config_; cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING; - uint64_t ice_tiebreaker_ = rtc::CreateRandomId64(); + uint64_t ice_tiebreaker_; rtc::scoped_refptr<rtc::RTCCertificate> certificate_; BundleManager bundles_; diff --git a/third_party/libwebrtc/pc/jsep_transport_unittest.cc b/third_party/libwebrtc/pc/jsep_transport_unittest.cc index f057d37a0d..18dd2d8896 100644 --- a/third_party/libwebrtc/pc/jsep_transport_unittest.cc +++ b/third_party/libwebrtc/pc/jsep_transport_unittest.cc @@ -48,11 +48,6 @@ static const char kIceUfrag2[] = "U002"; static const char kIcePwd2[] = "TESTIEPWD00000000000002"; static const char kTransportName[] = "Test Transport"; -enum class SrtpMode { - kSdes, - kDtlsSrtp, -}; - struct NegotiateRoleParams { ConnectionRole local_role; ConnectionRole remote_role; @@ -110,8 +105,7 @@ class JsepTransport2Test : public ::testing::Test, public sigslot::has_slots<> { // Create a new JsepTransport with a FakeDtlsTransport and a // FakeIceTransport. - std::unique_ptr<JsepTransport> CreateJsepTransport2(bool rtcp_mux_enabled, - SrtpMode srtp_mode) { + std::unique_ptr<JsepTransport> CreateJsepTransport2(bool rtcp_mux_enabled) { auto ice_internal = std::make_unique<FakeIceTransport>( kTransportName, ICE_CANDIDATE_COMPONENT_RTP); auto rtp_dtls_transport = @@ -131,19 +125,8 @@ class JsepTransport2Test : public ::testing::Test, public sigslot::has_slots<> { std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport; std::unique_ptr<webrtc::SrtpTransport> sdes_transport; std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport; - switch (srtp_mode) { - case SrtpMode::kSdes: - sdes_transport = CreateSdesTransport(rtp_dtls_transport.get(), - rtcp_dtls_transport.get()); - sdes_transport_ = sdes_transport.get(); - break; - case SrtpMode::kDtlsSrtp: dtls_srtp_transport = CreateDtlsSrtpTransport( rtp_dtls_transport.get(), rtcp_dtls_transport.get()); - break; - default: - RTC_DCHECK_NOTREACHED(); - } auto jsep_transport = std::make_unique<JsepTransport>( kTransportName, /*local_certificate=*/nullptr, std::move(ice), @@ -205,7 +188,7 @@ class JsepTransport2WithRtcpMux : public JsepTransport2Test, // This test verifies the ICE parameters are properly applied to the transports. TEST_P(JsepTransport2WithRtcpMux, SetIceParameters) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); JsepTransportDescription jsep_description; jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1); @@ -251,7 +234,7 @@ TEST_P(JsepTransport2WithRtcpMux, SetIceParameters) { // Similarly, test DTLS parameters are properly applied to the transports. TEST_P(JsepTransport2WithRtcpMux, SetDtlsParameters) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); // Create certificates. rtc::scoped_refptr<rtc::RTCCertificate> local_cert = @@ -302,7 +285,7 @@ TEST_P(JsepTransport2WithRtcpMux, SetDtlsParameters) { // CONNECTIONROLE_PASSIVE, expecting SSL_CLIENT role. TEST_P(JsepTransport2WithRtcpMux, SetDtlsParametersWithPassiveAnswer) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); // Create certificates. rtc::scoped_refptr<rtc::RTCCertificate> local_cert = @@ -354,7 +337,7 @@ TEST_P(JsepTransport2WithRtcpMux, SetDtlsParametersWithPassiveAnswer) { // only starts returning "false" once an ICE restart has been initiated. TEST_P(JsepTransport2WithRtcpMux, NeedsIceRestart) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); // Use the same JsepTransportDescription for both offer and answer. JsepTransportDescription description; @@ -399,7 +382,7 @@ TEST_P(JsepTransport2WithRtcpMux, NeedsIceRestart) { TEST_P(JsepTransport2WithRtcpMux, GetStats) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); size_t expected_stats_size = rtcp_mux_enabled ? 1u : 2u; TransportStats stats; @@ -415,7 +398,7 @@ TEST_P(JsepTransport2WithRtcpMux, GetStats) { // certificate matches the fingerprint. TEST_P(JsepTransport2WithRtcpMux, VerifyCertificateFingerprint) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); EXPECT_FALSE( jsep_transport_->VerifyCertificateFingerprint(nullptr, nullptr).ok()); @@ -489,8 +472,7 @@ TEST_P(JsepTransport2WithRtcpMux, ValidDtlsRoleNegotiation) { }; for (auto& param : valid_client_params) { - jsep_transport_ = - CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); local_description.transport_desc.connection_role = param.local_role; @@ -535,8 +517,7 @@ TEST_P(JsepTransport2WithRtcpMux, ValidDtlsRoleNegotiation) { }; for (auto& param : valid_server_params) { - jsep_transport_ = - CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); local_description.transport_desc.connection_role = param.local_role; @@ -607,8 +588,7 @@ TEST_P(JsepTransport2WithRtcpMux, InvalidDtlsRoleNegotiation) { SdpType::kPrAnswer}}; for (auto& param : duplicate_params) { - jsep_transport_ = - CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); local_description.transport_desc.connection_role = param.local_role; @@ -658,8 +638,7 @@ TEST_P(JsepTransport2WithRtcpMux, InvalidDtlsRoleNegotiation) { SdpType::kPrAnswer}}; for (auto& param : offerer_without_actpass_params) { - jsep_transport_ = - CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); local_description.transport_desc.connection_role = param.local_role; @@ -705,7 +684,7 @@ TEST_F(JsepTransport2Test, ValidDtlsReofferFromAnswerer) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription local_offer = @@ -752,7 +731,7 @@ TEST_F(JsepTransport2Test, InvalidDtlsReofferFromAnswerer) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription local_offer = @@ -798,7 +777,7 @@ TEST_F(JsepTransport2Test, RemoteOfferWithCurrentNegotiatedDtlsRole) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription remote_desc = @@ -843,7 +822,7 @@ TEST_F(JsepTransport2Test, RemoteOfferThatChangesNegotiatedDtlsRole) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription remote_desc = @@ -890,7 +869,7 @@ TEST_F(JsepTransport2Test, RemoteOfferThatChangesFingerprintAndDtlsRole) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing2", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription remote_desc = @@ -943,7 +922,7 @@ TEST_F(JsepTransport2Test, DtlsSetupWithLegacyAsAnswerer) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription remote_desc = @@ -975,8 +954,7 @@ TEST_F(JsepTransport2Test, DtlsSetupWithLegacyAsAnswerer) { // Tests that when the RTCP mux is successfully negotiated, the RTCP transport // will be destroyed and the SignalRtpMuxActive will be fired. TEST_F(JsepTransport2Test, RtcpMuxNegotiation) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/false); JsepTransportDescription local_desc; local_desc.rtcp_mux_enabled = true; ASSERT_NE(nullptr, jsep_transport_->rtcp_dtls_transport()); @@ -998,8 +976,7 @@ TEST_F(JsepTransport2Test, RtcpMuxNegotiation) { EXPECT_TRUE(signal_rtcp_mux_active_received_); // The remote side doesn't support RTCP-mux. - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/false); signal_rtcp_mux_active_received_ = false; remote_desc.rtcp_mux_enabled = false; ASSERT_TRUE( @@ -1015,87 +992,10 @@ TEST_F(JsepTransport2Test, RtcpMuxNegotiation) { EXPECT_FALSE(signal_rtcp_mux_active_received_); } -TEST_F(JsepTransport2Test, SdesNegotiation) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes); - ASSERT_TRUE(sdes_transport_); - EXPECT_FALSE(sdes_transport_->IsSrtpActive()); - - JsepTransportDescription offer_desc; - offer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_32, "inline:" + rtc::CreateRandomString(40), - std::string())); - ASSERT_TRUE( - jsep_transport_ - ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer) - .ok()); - - JsepTransportDescription answer_desc; - answer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_32, "inline:" + rtc::CreateRandomString(40), - std::string())); - ASSERT_TRUE( - jsep_transport_ - ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer) - .ok()); - EXPECT_TRUE(sdes_transport_->IsSrtpActive()); -} - -TEST_F(JsepTransport2Test, SdesNegotiationWithEmptyCryptosInAnswer) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes); - ASSERT_TRUE(sdes_transport_); - EXPECT_FALSE(sdes_transport_->IsSrtpActive()); - - JsepTransportDescription offer_desc; - offer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_32, "inline:" + rtc::CreateRandomString(40), - std::string())); - ASSERT_TRUE( - jsep_transport_ - ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer) - .ok()); - - JsepTransportDescription answer_desc; - ASSERT_TRUE( - jsep_transport_ - ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer) - .ok()); - // SRTP is not active because the crypto parameter is answer is empty. - EXPECT_FALSE(sdes_transport_->IsSrtpActive()); -} - -TEST_F(JsepTransport2Test, SdesNegotiationWithMismatchedCryptos) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes); - ASSERT_TRUE(sdes_transport_); - EXPECT_FALSE(sdes_transport_->IsSrtpActive()); - - JsepTransportDescription offer_desc; - offer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_32, "inline:" + rtc::CreateRandomString(40), - std::string())); - ASSERT_TRUE( - jsep_transport_ - ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer) - .ok()); - - JsepTransportDescription answer_desc; - answer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_80, "inline:" + rtc::CreateRandomString(40), - std::string())); - // Expected to fail because the crypto parameters don't match. - ASSERT_FALSE( - jsep_transport_ - ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer) - .ok()); -} - // Tests that the remote candidates can be added to the transports after both // local and remote descriptions are set. TEST_F(JsepTransport2Test, AddRemoteCandidates) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true); auto fake_ice_transport = static_cast<FakeIceTransport*>( jsep_transport_->rtp_dtls_transport()->ice_transport()); @@ -1119,7 +1019,6 @@ TEST_F(JsepTransport2Test, AddRemoteCandidates) { } enum class Scenario { - kSdes, kDtlsBeforeCallerSendOffer, kDtlsBeforeCallerSetAnswer, kDtlsAfterCallerSetAnswer, @@ -1131,9 +1030,9 @@ class JsepTransport2HeaderExtensionTest protected: JsepTransport2HeaderExtensionTest() {} - void CreateJsepTransportPair(SrtpMode mode) { - jsep_transport1_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode); - jsep_transport2_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode); + void CreateJsepTransportPair() { + jsep_transport1_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true); + jsep_transport2_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true); auto fake_dtls1 = static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport()); @@ -1145,14 +1044,12 @@ class JsepTransport2HeaderExtensionTest fake_dtls2->fake_ice_transport()->SignalReadPacket.connect( this, &JsepTransport2HeaderExtensionTest::OnReadPacket2); - if (mode == SrtpMode::kDtlsSrtp) { auto cert1 = rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT)); jsep_transport1_->rtp_dtls_transport()->SetLocalCertificate(cert1); auto cert2 = rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT)); jsep_transport2_->rtp_dtls_transport()->SetLocalCertificate(cert2); - } } void OnReadPacket1(rtc::PacketTransportInternal* transport, @@ -1239,17 +1136,10 @@ class JsepTransport2HeaderExtensionTest TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) { Scenario scenario = std::get<0>(GetParam()); bool use_gcm = std::get<1>(GetParam()); - SrtpMode mode = SrtpMode ::kDtlsSrtp; - if (scenario == Scenario::kSdes) { - mode = SrtpMode::kSdes; - } - CreateJsepTransportPair(mode); + CreateJsepTransportPair(); recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[0]); recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[1]); - cricket::CryptoParams sdes_param(1, rtc::kCsAesCm128HmacSha1_80, - "inline:" + rtc::CreateRandomString(40), - std::string()); if (use_gcm) { auto fake_dtls1 = static_cast<FakeDtlsTransport*>(jsep_transport1_->rtp_dtls_transport()); @@ -1266,9 +1156,6 @@ TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) { JsepTransportDescription offer_desc; offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_; - if (scenario == Scenario::kSdes) { - offer_desc.cryptos.push_back(sdes_param); - } ASSERT_TRUE( jsep_transport1_ ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer) @@ -1280,9 +1167,6 @@ TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) { JsepTransportDescription answer_desc; answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_; - if (scenario == Scenario::kSdes) { - answer_desc.cryptos.push_back(sdes_param); - } ASSERT_TRUE( jsep_transport2_ ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer) @@ -1301,8 +1185,7 @@ TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) { ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer) .ok()); - if (scenario == Scenario::kDtlsAfterCallerSetAnswer || - scenario == Scenario::kSdes) { + if (scenario == Scenario::kDtlsAfterCallerSetAnswer) { ConnectTransport(); } EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive()); @@ -1341,7 +1224,6 @@ INSTANTIATE_TEST_SUITE_P( JsepTransport2Test, JsepTransport2HeaderExtensionTest, ::testing::Values( - std::make_tuple(Scenario::kSdes, false), std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, true), std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, true), std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, true), @@ -1351,8 +1233,7 @@ INSTANTIATE_TEST_SUITE_P( // This test verifies the ICE parameters are properly applied to the transports. TEST_F(JsepTransport2Test, SetIceParametersWithRenomination) { - jsep_transport_ = - CreateJsepTransport2(/* rtcp_mux_enabled= */ true, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(/* rtcp_mux_enabled= */ true); JsepTransportDescription jsep_description; jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1); diff --git a/third_party/libwebrtc/pc/media_session.cc b/third_party/libwebrtc/pc/media_session.cc index a118beebb0..3928088c7f 100644 --- a/third_party/libwebrtc/pc/media_session.cc +++ b/third_party/libwebrtc/pc/media_session.cc @@ -22,7 +22,6 @@ #include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" -#include "api/crypto_params.h" #include "media/base/codec.h" #include "media/base/media_constants.h" #include "media/base/media_engine.h" @@ -47,19 +46,6 @@ using webrtc::RTCError; using webrtc::RTCErrorType; using webrtc::RtpTransceiverDirection; -const char kInline[] = "inline:"; - -void GetSupportedSdesCryptoSuiteNames( - void (*func)(const webrtc::CryptoOptions&, std::vector<int>*), - const webrtc::CryptoOptions& crypto_options, - std::vector<std::string>* names) { - std::vector<int> crypto_suites; - func(crypto_options, &crypto_suites); - for (const auto crypto : crypto_suites) { - names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); - } -} - webrtc::RtpExtension RtpExtensionFromCapability( const webrtc::RtpHeaderExtensionCapability& capability) { return webrtc::RtpExtension(capability.uri, @@ -167,140 +153,6 @@ bool IsMediaContentOfType(const ContentInfo* content, MediaType media_type) { return content->media_description()->type() == media_type; } -bool CreateCryptoParams(int tag, - const std::string& cipher, - CryptoParams* crypto_out) { - int key_len; - int salt_len; - if (!rtc::GetSrtpKeyAndSaltLengths(rtc::SrtpCryptoSuiteFromName(cipher), - &key_len, &salt_len)) { - return false; - } - - int master_key_len = key_len + salt_len; - std::string master_key; - if (!rtc::CreateRandomData(master_key_len, &master_key)) { - return false; - } - - RTC_CHECK_EQ(master_key_len, master_key.size()); - std::string key = rtc::Base64::Encode(master_key); - - crypto_out->tag = tag; - crypto_out->crypto_suite = cipher; - crypto_out->key_params = kInline; - crypto_out->key_params += key; - return true; -} - -bool AddCryptoParams(const std::string& crypto_suite, - CryptoParamsVec* cryptos_out) { - int size = static_cast<int>(cryptos_out->size()); - - cryptos_out->resize(size + 1); - return CreateCryptoParams(size, crypto_suite, &cryptos_out->at(size)); -} - -void AddMediaCryptos(const CryptoParamsVec& cryptos, - MediaContentDescription* media) { - for (const CryptoParams& crypto : cryptos) { - media->AddCrypto(crypto); - } -} - -bool CreateMediaCryptos(const std::vector<std::string>& crypto_suites, - MediaContentDescription* media) { - CryptoParamsVec cryptos; - for (const std::string& crypto_suite : crypto_suites) { - if (!AddCryptoParams(crypto_suite, &cryptos)) { - return false; - } - } - AddMediaCryptos(cryptos, media); - return true; -} - -const CryptoParamsVec* GetCryptos(const ContentInfo* content) { - if (!content || !content->media_description()) { - return nullptr; - } - return &content->media_description()->cryptos(); -} - -bool FindMatchingCrypto(const CryptoParamsVec& cryptos, - const CryptoParams& crypto, - CryptoParams* crypto_out) { - auto it = absl::c_find_if( - cryptos, [&crypto](const CryptoParams& c) { return crypto.Matches(c); }); - if (it == cryptos.end()) { - return false; - } - *crypto_out = *it; - return true; -} - -// For audio, HMAC 32 (if enabled) is prefered over HMAC 80 because of the -// low overhead. -void GetSupportedAudioSdesCryptoSuites( - const webrtc::CryptoOptions& crypto_options, - std::vector<int>* crypto_suites) { - if (crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher) { - crypto_suites->push_back(rtc::kSrtpAes128CmSha1_32); - } - crypto_suites->push_back(rtc::kSrtpAes128CmSha1_80); - if (crypto_options.srtp.enable_gcm_crypto_suites) { - crypto_suites->push_back(rtc::kSrtpAeadAes256Gcm); - crypto_suites->push_back(rtc::kSrtpAeadAes128Gcm); - } -} - -void GetSupportedAudioSdesCryptoSuiteNames( - const webrtc::CryptoOptions& crypto_options, - std::vector<std::string>* crypto_suite_names) { - GetSupportedSdesCryptoSuiteNames(GetSupportedAudioSdesCryptoSuites, - crypto_options, crypto_suite_names); -} - -void GetSupportedVideoSdesCryptoSuites( - const webrtc::CryptoOptions& crypto_options, - std::vector<int>* crypto_suites) { - crypto_suites->push_back(rtc::kSrtpAes128CmSha1_80); - if (crypto_options.srtp.enable_gcm_crypto_suites) { - crypto_suites->push_back(rtc::kSrtpAeadAes256Gcm); - crypto_suites->push_back(rtc::kSrtpAeadAes128Gcm); - } -} - -void GetSupportedVideoSdesCryptoSuiteNames( - const webrtc::CryptoOptions& crypto_options, - std::vector<std::string>* crypto_suite_names) { - GetSupportedSdesCryptoSuiteNames(GetSupportedVideoSdesCryptoSuites, - crypto_options, crypto_suite_names); -} - -// Support any GCM cipher (if enabled through options). For video support only -// 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated (if enabled) unless -// bundle is enabled because it is low overhead. -// Pick the crypto in the list that is supported. -bool SelectCrypto(const MediaContentDescription* offer, - bool bundle, - const webrtc::CryptoOptions& crypto_options, - CryptoParams* crypto_out) { - bool audio = offer->type() == MEDIA_TYPE_AUDIO; - const CryptoParamsVec& cryptos = offer->cryptos(); - - for (const CryptoParams& crypto : cryptos) { - if ((crypto_options.srtp.enable_gcm_crypto_suites && - rtc::IsGcmCryptoSuiteName(crypto.crypto_suite)) || - rtc::kCsAesCm128HmacSha1_80 == crypto.crypto_suite || - (rtc::kCsAesCm128HmacSha1_32 == crypto.crypto_suite && audio && - !bundle && crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher)) { - return CreateCryptoParams(crypto.tag, crypto.crypto_suite, crypto_out); - } - } - return false; -} - // Finds all StreamParams of all media types and attach them to stream_params. StreamParamsVec GetCurrentStreamParams( const std::vector<const ContentInfo*>& active_local_contents) { @@ -496,118 +348,6 @@ bool UpdateTransportInfoForBundle(const ContentGroup& bundle_group, return true; } -// Gets the CryptoParamsVec of the given `content_name` from `sdesc`, and -// sets it to `cryptos`. -bool GetCryptosByName(const SessionDescription* sdesc, - const std::string& content_name, - CryptoParamsVec* cryptos) { - if (!sdesc || !cryptos) { - return false; - } - const ContentInfo* content = sdesc->GetContentByName(content_name); - if (!content || !content->media_description()) { - return false; - } - *cryptos = content->media_description()->cryptos(); - return true; -} - -// Prunes the `target_cryptos` by removing the crypto params (crypto_suite) -// which are not available in `filter`. -void PruneCryptos(const CryptoParamsVec& filter, - CryptoParamsVec* target_cryptos) { - if (!target_cryptos) { - return; - } - - target_cryptos->erase( - std::remove_if(target_cryptos->begin(), target_cryptos->end(), - // Returns true if the `crypto`'s crypto_suite is not - // found in `filter`. - [&filter](const CryptoParams& crypto) { - for (const CryptoParams& entry : filter) { - if (entry.crypto_suite == crypto.crypto_suite) - return false; - } - return true; - }), - target_cryptos->end()); -} - -bool IsRtpContent(SessionDescription* sdesc, const std::string& content_name) { - bool is_rtp = false; - ContentInfo* content = sdesc->GetContentByName(content_name); - if (content && content->media_description()) { - is_rtp = IsRtpProtocol(content->media_description()->protocol()); - } - return is_rtp; -} - -// Updates the crypto parameters of the `sdesc` according to the given -// `bundle_group`. The crypto parameters of all the contents within the -// `bundle_group` should be updated to use the common subset of the -// available cryptos. -bool UpdateCryptoParamsForBundle(const ContentGroup& bundle_group, - SessionDescription* sdesc) { - // The bundle should not be empty. - if (!sdesc || !bundle_group.FirstContentName()) { - return false; - } - - bool common_cryptos_needed = false; - // Get the common cryptos. - const ContentNames& content_names = bundle_group.content_names(); - CryptoParamsVec common_cryptos; - bool first = true; - for (const std::string& content_name : content_names) { - if (!IsRtpContent(sdesc, content_name)) { - continue; - } - // The common cryptos are needed if any of the content does not have DTLS - // enabled. - if (!sdesc->GetTransportInfoByName(content_name)->description.secure()) { - common_cryptos_needed = true; - } - if (first) { - first = false; - // Initial the common_cryptos with the first content in the bundle group. - if (!GetCryptosByName(sdesc, content_name, &common_cryptos)) { - return false; - } - if (common_cryptos.empty()) { - // If there's no crypto params, we should just return. - return true; - } - } else { - CryptoParamsVec cryptos; - if (!GetCryptosByName(sdesc, content_name, &cryptos)) { - return false; - } - PruneCryptos(cryptos, &common_cryptos); - } - } - - if (common_cryptos.empty() && common_cryptos_needed) { - return false; - } - - // Update to use the common cryptos. - for (const std::string& content_name : content_names) { - if (!IsRtpContent(sdesc, content_name)) { - continue; - } - ContentInfo* content = sdesc->GetContentByName(content_name); - if (IsMediaContent(content)) { - MediaContentDescription* media_desc = content->media_description(); - if (!media_desc) { - return false; - } - media_desc->set_cryptos(common_cryptos); - } - } - return true; -} - std::vector<const ContentInfo*> GetActiveContents( const SessionDescription& description, const MediaSessionOptions& session_options) { @@ -634,9 +374,6 @@ std::vector<const ContentInfo*> GetActiveContents( RTCError CreateContentOffer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, - const SecurePolicy& secure_policy, - const CryptoParamsVec* current_cryptos, - const std::vector<std::string>& crypto_suites, const RtpHeaderExtensions& rtp_extensions, UniqueRandomIdGenerator* ssrc_generator, StreamParamsVec* current_streams, @@ -665,22 +402,6 @@ RTCError CreateContentOffer( AddSimulcastToMediaDescription(media_description_options, offer); - if (secure_policy != SEC_DISABLED) { - if (current_cryptos) { - AddMediaCryptos(*current_cryptos, offer); - } - if (offer->cryptos().empty()) { - if (!CreateMediaCryptos(crypto_suites, offer)) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create crypto parameters"); - } - } - } - - if (secure_policy == SEC_REQUIRED && offer->cryptos().empty()) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create crypto parameters"); - } return RTCError::OK(); } @@ -688,9 +409,6 @@ RTCError CreateMediaContentOffer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, const std::vector<Codec>& codecs, - const SecurePolicy& secure_policy, - const CryptoParamsVec* current_cryptos, - const std::vector<std::string>& crypto_suites, const RtpHeaderExtensions& rtp_extensions, UniqueRandomIdGenerator* ssrc_generator, StreamParamsVec* current_streams, @@ -705,7 +423,6 @@ RTCError CreateMediaContentOffer( } return CreateContentOffer(media_description_options, session_options, - secure_policy, current_cryptos, crypto_suites, rtp_extensions, ssrc_generator, current_streams, offer); } @@ -1254,17 +971,6 @@ void NegotiateRtpHeaderExtensions(const RtpHeaderExtensions& local_extensions, const RtpHeaderExtensions& offered_extensions, webrtc::RtpExtension::Filter filter, RtpHeaderExtensions* negotiated_extensions) { - // TransportSequenceNumberV2 is not offered by default. The special logic for - // the TransportSequenceNumber extensions works as follows: - // Offer Answer - // V1 V1 if in local_extensions. - // V1 and V2 V2 regardless of local_extensions. - // V2 V2 regardless of local_extensions. - const webrtc::RtpExtension* transport_sequence_number_v2_offer = - FindHeaderExtensionByUriDiscardUnsupported( - offered_extensions, - webrtc::RtpExtension::kTransportSequenceNumberV2Uri, filter); - bool frame_descriptor_in_local = false; bool dependency_descriptor_in_local = false; bool abs_capture_time_in_local = false; @@ -1276,29 +982,16 @@ void NegotiateRtpHeaderExtensions(const RtpHeaderExtensions& local_extensions, dependency_descriptor_in_local = true; else if (ours.uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri) abs_capture_time_in_local = true; + const webrtc::RtpExtension* theirs = FindHeaderExtensionByUriDiscardUnsupported(offered_extensions, ours.uri, filter); if (theirs) { - if (transport_sequence_number_v2_offer && - ours.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) { - // Don't respond to - // http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 - // if we get an offer including - // http://www.webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02 - continue; - } else { - // We respond with their RTP header extension id. - negotiated_extensions->push_back(*theirs); - } + // We respond with their RTP header extension id. + negotiated_extensions->push_back(*theirs); } } - if (transport_sequence_number_v2_offer) { - // Respond that we support kTransportSequenceNumberV2Uri. - negotiated_extensions->push_back(*transport_sequence_number_v2_offer); - } - // Frame descriptors support. If the extension is not present locally, but is // in the offer, we add it to the list. if (!dependency_descriptor_in_local) { @@ -1367,8 +1060,6 @@ bool CreateMediaContentAnswer( const MediaContentDescription* offer, const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, - const SecurePolicy& sdes_policy, - const CryptoParamsVec* current_cryptos, const RtpHeaderExtensions& local_rtp_extensions, UniqueRandomIdGenerator* ssrc_generator, bool enable_encrypted_rtp_header_extensions, @@ -1409,21 +1100,6 @@ bool CreateMediaContentAnswer( answer->set_remote_estimate(offer->remote_estimate()); - if (sdes_policy != SEC_DISABLED) { - CryptoParams crypto; - if (SelectCrypto(offer, bundle_enabled, session_options.crypto_options, - &crypto)) { - if (current_cryptos) { - FindMatchingCrypto(*current_cryptos, crypto, &crypto); - } - answer->AddCrypto(crypto); - } - } - - if (answer->cryptos().empty() && sdes_policy == SEC_REQUIRED) { - return false; - } - AddSimulcastToMediaDescription(media_description_options, answer); answer->set_direction(NegotiateRtpTransceiverDirection( @@ -1462,9 +1138,7 @@ bool IsMediaProtocolSupported(MediaType type, } void SetMediaProtocol(bool secure_transport, MediaContentDescription* desc) { - if (!desc->cryptos().empty()) - desc->set_protocol(kMediaProtocolSavpf); - else if (secure_transport) + if (secure_transport) desc->set_protocol(kMediaProtocolDtlsSavpf); else desc->set_protocol(kMediaProtocolAvpf); @@ -1486,23 +1160,6 @@ const TransportDescription* GetTransportDescription( return desc; } -// Gets the current DTLS state from the transport description. -bool IsDtlsActive(const ContentInfo* content, - const SessionDescription* current_description) { - if (!content) { - return false; - } - - size_t msection_index = content - ¤t_description->contents()[0]; - - if (current_description->transport_infos().size() <= msection_index) { - return false; - } - - return current_description->transport_infos()[msection_index] - .description.secure(); -} - webrtc::RTCErrorOr<AudioCodecs> GetNegotiatedCodecsForOffer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, @@ -1867,11 +1524,6 @@ MediaSessionDescriptionFactory::CreateOfferOrError( RTCErrorType::INTERNAL_ERROR, "CreateOffer failed to UpdateTransportInfoForBundle"); } - if (!UpdateCryptoParamsForBundle(offer_bundle, offer.get())) { - LOG_AND_RETURN_ERROR( - RTCErrorType::INTERNAL_ERROR, - "CreateOffer failed to UpdateCryptoParamsForBundle."); - } } } @@ -2045,12 +1697,6 @@ MediaSessionDescriptionFactory::CreateAnswerOrError( RTCErrorType::INTERNAL_ERROR, "CreateAnswer failed to UpdateTransportInfoForBundle."); } - - if (!UpdateCryptoParamsForBundle(answer_bundle, answer.get())) { - LOG_AND_RETURN_ERROR( - RTCErrorType::INTERNAL_ERROR, - "CreateAnswer failed to UpdateCryptoParamsForBundle."); - } } } } @@ -2402,19 +2048,6 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForOffer( return error_or_filtered_codecs.MoveError(); } - cricket::SecurePolicy sdes_policy = - IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED - : secure(); - - std::vector<std::string> crypto_suites; - if (media_description_options.type == MEDIA_TYPE_AUDIO) { - GetSupportedAudioSdesCryptoSuiteNames(session_options.crypto_options, - &crypto_suites); - } else { - GetSupportedVideoSdesCryptoSuiteNames(session_options.crypto_options, - &crypto_suites); - } - std::unique_ptr<MediaContentDescription> content_description; if (media_description_options.type == MEDIA_TYPE_AUDIO) { content_description = std::make_unique<AudioContentDescription>(); @@ -2424,15 +2057,15 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForOffer( auto error = CreateMediaContentOffer( media_description_options, session_options, - error_or_filtered_codecs.MoveValue(), sdes_policy, - GetCryptos(current_content), crypto_suites, header_extensions, - ssrc_generator(), current_streams, content_description.get(), + error_or_filtered_codecs.MoveValue(), header_extensions, ssrc_generator(), + current_streams, content_description.get(), transport_desc_factory_->trials()); if (!error.ok()) { return error; } - bool secure_transport = transport_desc_factory_->secure() != SEC_DISABLED; + // Insecure transport should only occur in testing. + bool secure_transport = !(transport_desc_factory_->insecure()); SetMediaProtocol(secure_transport, content_description.get()); content_description->set_direction(media_description_options.direction); @@ -2456,15 +2089,9 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForOffer( IceCredentialsIterator* ice_credentials) const { auto data = std::make_unique<SctpDataContentDescription>(); - bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED); + bool secure_transport = true; - cricket::SecurePolicy sdes_policy = - IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED - : secure(); std::vector<std::string> crypto_suites; - // SDES doesn't make sense for SCTP, so we disable it, and we only - // get SDES crypto suites for RTP-based data channels. - sdes_policy = cricket::SEC_DISABLED; // Unlike SetMediaProtocol below, we need to set the protocol // before we call CreateMediaContentOffer. Otherwise, // CreateMediaContentOffer won't know this is SCTP and will @@ -2474,10 +2101,9 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForOffer( data->set_use_sctpmap(session_options.use_obsolete_sctp_sdp); data->set_max_message_size(kSctpSendBufferSize); - auto error = CreateContentOffer( - media_description_options, session_options, sdes_policy, - GetCryptos(current_content), crypto_suites, RtpHeaderExtensions(), - ssrc_generator(), current_streams, data.get()); + auto error = CreateContentOffer(media_description_options, session_options, + RtpHeaderExtensions(), ssrc_generator(), + current_streams, data.get()); if (!error.ok()) { return error; } @@ -2546,10 +2172,14 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( } else { offer_content_description = offer_content->media_description()->as_video(); } + // If this section is part of a bundle, bundle_transport is non-null. + // Then require_transport_attributes is false - we can handle sections + // without the DTLS parameters. For rejected m-lines it does not matter. + // Otherwise, transport attributes MUST be present. std::unique_ptr<TransportDescription> transport = CreateTransportAnswer( media_description_options.mid, offer_description, media_description_options.transport_options, current_description, - bundle_transport != nullptr, ice_credentials); + !offer_content->rejected && bundle_transport == nullptr, ice_credentials); if (!transport) { LOG_AND_RETURN_ERROR( RTCErrorType::INTERNAL_ERROR, @@ -2590,9 +2220,6 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( } else { answer_content = std::make_unique<VideoContentDescription>(); } - // Do not require or create SDES cryptos if DTLS is used. - cricket::SecurePolicy sdes_policy = - transport->secure() ? cricket::SEC_DISABLED : secure(); if (!SetCodecsInAnswer( offer_content_description, filtered_codecs, media_description_options, session_options, ssrc_generator(), current_streams, @@ -2602,7 +2229,6 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( } if (!CreateMediaContentAnswer( offer_content_description, media_description_options, session_options, - sdes_policy, GetCryptos(current_content), filtered_rtp_header_extensions(header_extensions), ssrc_generator(), enable_encrypted_rtp_header_extensions_, current_streams, bundle_enabled, answer_content.get())) { @@ -2646,16 +2272,13 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForAnswer( std::unique_ptr<TransportDescription> data_transport = CreateTransportAnswer( media_description_options.mid, offer_description, media_description_options.transport_options, current_description, - bundle_transport != nullptr, ice_credentials); + !offer_content->rejected && bundle_transport == nullptr, ice_credentials); if (!data_transport) { LOG_AND_RETURN_ERROR( RTCErrorType::INTERNAL_ERROR, "Failed to create transport answer, data transport is missing"); } - // Do not require or create SDES cryptos if DTLS is used. - cricket::SecurePolicy sdes_policy = - data_transport->secure() ? cricket::SEC_DISABLED : secure(); bool bundle_enabled = offer_description->HasGroup(GROUP_TYPE_BUNDLE) && session_options.bundle_enabled; RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_DATA)); @@ -2680,9 +2303,9 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForAnswer( } if (!CreateMediaContentAnswer( offer_data_description, media_description_options, session_options, - sdes_policy, GetCryptos(current_content), RtpHeaderExtensions(), - ssrc_generator(), enable_encrypted_rtp_header_extensions_, - current_streams, bundle_enabled, data_answer.get())) { + RtpHeaderExtensions(), ssrc_generator(), + enable_encrypted_rtp_header_extensions_, current_streams, + bundle_enabled, data_answer.get())) { LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, "Failed to create answer"); } @@ -2721,10 +2344,11 @@ RTCError MediaSessionDescriptionFactory::AddUnsupportedContentForAnswer( SessionDescription* answer, IceCredentialsIterator* ice_credentials) const { std::unique_ptr<TransportDescription> unsupported_transport = - CreateTransportAnswer(media_description_options.mid, offer_description, - media_description_options.transport_options, - current_description, bundle_transport != nullptr, - ice_credentials); + CreateTransportAnswer( + media_description_options.mid, offer_description, + media_description_options.transport_options, current_description, + !offer_content->rejected && bundle_transport == nullptr, + ice_credentials); if (!unsupported_transport) { LOG_AND_RETURN_ERROR( RTCErrorType::INTERNAL_ERROR, diff --git a/third_party/libwebrtc/pc/media_session.h b/third_party/libwebrtc/pc/media_session.h index 0b3cb67c35..c9fbc4ba63 100644 --- a/third_party/libwebrtc/pc/media_session.h +++ b/third_party/libwebrtc/pc/media_session.h @@ -160,8 +160,6 @@ class MediaSessionDescriptionFactory { const VideoCodecs& recv_codecs); RtpHeaderExtensions filtered_rtp_header_extensions( RtpHeaderExtensions extensions) const; - SecurePolicy secure() const { return secure_; } - void set_secure(SecurePolicy s) { secure_ = s; } void set_enable_encrypted_rtp_header_extensions(bool enable) { enable_encrypted_rtp_header_extensions_ = enable; @@ -320,9 +318,6 @@ class MediaSessionDescriptionFactory { webrtc::AlwaysValidPointer<rtc::UniqueRandomIdGenerator> const ssrc_generator_; bool enable_encrypted_rtp_header_extensions_ = false; - // TODO(zhihuang): Rename secure_ to sdec_policy_; rename the related getter - // and setter. - SecurePolicy secure_ = SEC_DISABLED; const TransportDescriptionFactory* transport_desc_factory_; }; diff --git a/third_party/libwebrtc/pc/media_session_unittest.cc b/third_party/libwebrtc/pc/media_session_unittest.cc index f4fd09cba0..d00ad1c90e 100644 --- a/third_party/libwebrtc/pc/media_session_unittest.cc +++ b/third_party/libwebrtc/pc/media_session_unittest.cc @@ -25,7 +25,6 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/candidate.h" -#include "api/crypto_params.h" #include "api/rtp_parameters.h" #include "media/base/codec.h" #include "media/base/media_constants.h" @@ -50,10 +49,6 @@ #include "test/gtest.h" #include "test/scoped_key_value_config.h" -#define ASSERT_CRYPTO(cd, s, cs) \ - ASSERT_EQ(s, cd->cryptos().size()); \ - ASSERT_EQ(cs, cd->cryptos()[0].crypto_suite) - namespace cricket { namespace { @@ -254,12 +249,6 @@ const char* kMediaProtocols[] = {"RTP/AVP", "RTP/SAVP", "RTP/AVPF", const char* kMediaProtocolsDtls[] = {"TCP/TLS/RTP/SAVPF", "TCP/TLS/RTP/SAVP", "UDP/TLS/RTP/SAVPF", "UDP/TLS/RTP/SAVP"}; -// SRTP cipher name negotiated by the tests. This must be updated if the -// default changes. -const char* kDefaultSrtpCryptoSuite = kCsAesCm128HmacSha1_80; -const char* kDefaultSrtpCryptoSuiteGcm = kCsAeadAes256Gcm; -const uint8_t kDefaultCryptoSuiteSize = 3U; - // These constants are used to make the code using "AddMediaDescriptionOptions" // more readable. constexpr bool kStopped = true; @@ -388,17 +377,6 @@ MediaSessionOptions CreateAudioMediaSession() { return session_options; } -// prefers GCM SDES crypto suites by removing non-GCM defaults. -void PreferGcmCryptoParameters(CryptoParamsVec* cryptos) { - cryptos->erase( - std::remove_if(cryptos->begin(), cryptos->end(), - [](const CryptoParams& crypto) { - return crypto.crypto_suite != kCsAeadAes256Gcm && - crypto.crypto_suite != kCsAeadAes128Gcm; - }), - cryptos->end()); -} - // TODO(zhihuang): Most of these tests were written while MediaSessionOptions // was designed for Plan B SDP, where only one audio "m=" section and one video // "m=" section could be generated, and ordering couldn't be controlled. Many of @@ -451,18 +429,6 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { return video_streams; } - bool CompareCryptoParams(const CryptoParamsVec& c1, - const CryptoParamsVec& c2) { - if (c1.size() != c2.size()) - return false; - for (size_t i = 0; i < c1.size(); ++i) - if (c1[i].tag != c2[i].tag || c1[i].crypto_suite != c2[i].crypto_suite || - c1[i].key_params != c2[i].key_params || - c1[i].session_params != c2[i].session_params) - return false; - return true; - } - // Returns true if the transport info contains "renomination" as an // ICE option. bool GetIceRenomination(const TransportInfo* transport_info) { @@ -566,50 +532,6 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { } } - void TestCryptoWithBundle(bool offer) { - f1_.set_secure(SEC_ENABLED); - MediaSessionOptions options; - AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &options); - std::unique_ptr<SessionDescription> ref_desc; - std::unique_ptr<SessionDescription> desc; - if (offer) { - options.bundle_enabled = false; - ref_desc = f1_.CreateOfferOrError(options, nullptr).MoveValue(); - options.bundle_enabled = true; - desc = f1_.CreateOfferOrError(options, ref_desc.get()).MoveValue(); - } else { - options.bundle_enabled = true; - ref_desc = f1_.CreateOfferOrError(options, nullptr).MoveValue(); - desc = - f1_.CreateAnswerOrError(ref_desc.get(), options, nullptr).MoveValue(); - } - ASSERT_TRUE(desc); - const MediaContentDescription* audio_media_desc = - desc->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - const MediaContentDescription* video_media_desc = - desc->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_TRUE(CompareCryptoParams(audio_media_desc->cryptos(), - video_media_desc->cryptos())); - ASSERT_CRYPTO(audio_media_desc, offer ? kDefaultCryptoSuiteSize : 1U, - kDefaultSrtpCryptoSuite); - - // Verify the selected crypto is one from the reference audio - // media content. - const MediaContentDescription* ref_audio_media_desc = - ref_desc->GetContentDescriptionByName("audio"); - bool found = false; - for (size_t i = 0; i < ref_audio_media_desc->cryptos().size(); ++i) { - if (ref_audio_media_desc->cryptos()[i].Matches( - audio_media_desc->cryptos()[0])) { - found = true; - break; - } - } - EXPECT_TRUE(found); - } - // This test that the audio and video media direction is set to // `expected_direction_in_answer` in an answer if the offer direction is set // to `direction_in_offer` and the answer is willing to both send and receive. @@ -650,59 +572,6 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { return true; } - void TestVideoGcmCipher(bool gcm_offer, bool gcm_answer) { - MediaSessionOptions offer_opts; - AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &offer_opts); - offer_opts.crypto_options.srtp.enable_gcm_crypto_suites = gcm_offer; - - MediaSessionOptions answer_opts; - AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &answer_opts); - answer_opts.crypto_options.srtp.enable_gcm_crypto_suites = gcm_answer; - - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - std::unique_ptr<SessionDescription> offer = - f1_.CreateOfferOrError(offer_opts, nullptr).MoveValue(); - ASSERT_TRUE(offer.get()); - if (gcm_offer && gcm_answer) { - for (ContentInfo& content : offer->contents()) { - auto cryptos = content.media_description()->cryptos(); - PreferGcmCryptoParameters(&cryptos); - content.media_description()->set_cryptos(cryptos); - } - } - std::unique_ptr<SessionDescription> answer = - f2_.CreateAnswerOrError(offer.get(), answer_opts, nullptr).MoveValue(); - const ContentInfo* ac = answer->GetContentByName("audio"); - const ContentInfo* vc = answer->GetContentByName("video"); - ASSERT_TRUE(ac); - ASSERT_TRUE(vc); - EXPECT_EQ(MediaProtocolType::kRtp, ac->type); - EXPECT_EQ(MediaProtocolType::kRtp, vc->type); - const MediaContentDescription* acd = ac->media_description(); - const MediaContentDescription* vcd = vc->media_description(); - EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); - EXPECT_THAT(acd->codecs(), ElementsAreArray(kAudioCodecsAnswer)); - EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw - EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached - EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux - if (gcm_offer && gcm_answer) { - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuiteGcm); - } else { - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); - } - EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); - EXPECT_THAT(vcd->codecs(), ElementsAreArray(kVideoCodecsAnswer)); - EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached - EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux - if (gcm_offer && gcm_answer) { - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuiteGcm); - } else { - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuite); - } - EXPECT_EQ(kMediaProtocolSavpf, vcd->protocol()); - } - void TestTransportSequenceNumberNegotiation( const RtpHeaderExtensions& local, const RtpHeaderExtensions& offered, @@ -768,7 +637,6 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { // Create a typical audio offer, and ensure it matches what we expect. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { - f1_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(CreateAudioMediaSession(), nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -783,14 +651,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached. EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on - ASSERT_CRYPTO(acd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); } // Create an offer with just Opus and RED. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOfferWithJustOpusAndRed) { - f1_.set_secure(SEC_ENABLED); // First, prefer to only use opus and red. std::vector<webrtc::RtpCodecCapability> preferences; preferences.push_back( @@ -819,7 +685,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, // Create an offer with RED before Opus, which enables RED with Opus encoding. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOfferWithRedForOpus) { - f1_.set_secure(SEC_ENABLED); // First, prefer to only use opus and red. std::vector<webrtc::RtpCodecCapability> preferences; preferences.push_back( @@ -850,7 +715,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOfferWithRedForOpus) { TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) { MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - f1_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -867,15 +731,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) { EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on - ASSERT_CRYPTO(acd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); EXPECT_EQ(f1_.video_sendrecv_codecs(), vcd->codecs()); EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached EXPECT_EQ(kAutoBandwidth, vcd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(vcd->rtcp_mux()); // rtcp-mux defaults on - ASSERT_CRYPTO(vcd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, vcd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, vcd->protocol()); } // Test creating an offer with bundle where the Codecs have the same dynamic @@ -906,8 +768,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestBundleOfferWithSameCodecPlType) { // after an audio only session has been negotiated. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateUpdatedVideoOfferWithBundle) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); MediaSessionOptions opts; AddMediaDescriptionOptions(MEDIA_TYPE_AUDIO, "audio", RtpTransceiverDirection::kRecvOnly, kActive, @@ -934,10 +794,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, EXPECT_TRUE(vcd); EXPECT_TRUE(acd); - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, vcd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, vcd->protocol()); } // Create an SCTP data offer with bundle without error. @@ -945,7 +803,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSctpDataOffer) { MediaSessionOptions opts; opts.bundle_enabled = true; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); - f1_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); EXPECT_TRUE(offer.get()); @@ -953,7 +810,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSctpDataOffer) { auto dcd = GetFirstSctpDataContentDescription(offer.get()); ASSERT_TRUE(dcd); // Since this transport is insecure, the protocol should be "SCTP". - EXPECT_EQ(kMediaProtocolSctp, dcd->protocol()); + EXPECT_EQ(kMediaProtocolUdpDtlsSctp, dcd->protocol()); } // Create an SCTP data offer with bundle without error. @@ -961,8 +818,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSecureSctpDataOffer) { MediaSessionOptions opts; opts.bundle_enabled = true; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); - f1_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); EXPECT_TRUE(offer.get()); @@ -978,19 +833,18 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateImplicitSctpDataOffer) { MediaSessionOptions opts; opts.bundle_enabled = true; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); - f1_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer1( f1_.CreateOfferOrError(opts, nullptr).MoveValue()); ASSERT_TRUE(offer1.get()); const ContentInfo* data = offer1->GetContentByName("data"); ASSERT_TRUE(data); - ASSERT_EQ(kMediaProtocolSctp, data->media_description()->protocol()); + ASSERT_EQ(kMediaProtocolUdpDtlsSctp, data->media_description()->protocol()); std::unique_ptr<SessionDescription> offer2( f1_.CreateOfferOrError(opts, offer1.get()).MoveValue()); data = offer2->GetContentByName("data"); ASSERT_TRUE(data); - EXPECT_EQ(kMediaProtocolSctp, data->media_description()->protocol()); + EXPECT_EQ(kMediaProtocolUdpDtlsSctp, data->media_description()->protocol()); } // Test that if BUNDLE is enabled and all media sections are rejected then the @@ -1289,8 +1143,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateOfferContentOrder) { // Create a typical audio answer, and ensure it matches what we expect. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(CreateAudioMediaSession(), nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -1308,24 +1160,16 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) { EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); } // Create a typical audio answer with GCM ciphers enabled, and ensure it // matches what we expect. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); MediaSessionOptions opts = CreateAudioMediaSession(); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); ASSERT_TRUE(offer.get()); - for (ContentInfo& content : offer->contents()) { - auto cryptos = content.media_description()->cryptos(); - PreferGcmCryptoParameters(&cryptos); - content.media_description()->set_cryptos(cryptos); - } std::unique_ptr<SessionDescription> answer = f2_.CreateAnswerOrError(offer.get(), opts, nullptr).MoveValue(); const ContentInfo* ac = answer->GetContentByName("audio"); @@ -1339,8 +1183,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuiteGcm); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); } // Create an audio answer with no common codecs, and ensure it is rejected. @@ -1369,8 +1212,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -1389,31 +1230,11 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); EXPECT_THAT(vcd->codecs(), ElementsAreArray(kVideoCodecsAnswer)); EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, vcd->protocol()); -} - -// Create a typical video answer with GCM ciphers enabled, and ensure it -// matches what we expect. -TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcm) { - TestVideoGcmCipher(true, true); -} - -// Create a typical video answer with GCM ciphers enabled for the offer only, -// and ensure it matches what we expect. -TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmOffer) { - TestVideoGcmCipher(true, false); -} - -// Create a typical video answer with GCM ciphers enabled for the answer only, -// and ensure it matches what we expect. -TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmAnswer) { - TestVideoGcmCipher(false, true); + EXPECT_EQ(kMediaProtocolDtlsSavpf, vcd->protocol()); } // Create a video answer with no common codecs, and ensure it is rejected. @@ -1512,13 +1333,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerWithoutSctpmap) { // and "TCP/DTLS/SCTP" offers. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerToDifferentOfferedProtos) { - // Need to enable DTLS offer/answer generation (disabled by default in this - // test). - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); - MediaSessionOptions opts; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); std::unique_ptr<SessionDescription> offer = @@ -1547,13 +1361,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerToOfferWithDefinedMessageSize) { - // Need to enable DTLS offer/answer generation (disabled by default in this - // test). - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); - MediaSessionOptions opts; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); std::unique_ptr<SessionDescription> offer = @@ -1577,13 +1384,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerToOfferWithZeroMessageSize) { - // Need to enable DTLS offer/answer generation (disabled by default in this - // test). - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); - MediaSessionOptions opts; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); std::unique_ptr<SessionDescription> offer = @@ -1672,13 +1472,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, CreateAnswerToInactiveOffer) { RtpTransceiverDirection::kInactive); } -// Test that the media protocol is RTP/AVPF if DTLS and SDES are disabled. +// Test that the media protocol is RTP/AVPF if DTLS is disabled. TEST_F(MediaSessionDescriptionFactoryTest, AudioOfferAnswerWithCryptoDisabled) { MediaSessionOptions opts = CreateAudioMediaSession(); - f1_.set_secure(SEC_DISABLED); - f2_.set_secure(SEC_DISABLED); - tdf1_.set_secure(SEC_DISABLED); - tdf2_.set_secure(SEC_DISABLED); + tdf1_.SetInsecureForTesting(); + tdf1_.set_certificate(nullptr); + tdf2_.SetInsecureForTesting(); + tdf2_.set_certificate(nullptr); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); @@ -1731,30 +1531,72 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestOfferAnswerWithRtpExtensions) { } // Create a audio/video offer and answer and ensure that the -// TransportSequenceNumber RTP header extensions are handled correctly. 02 is -// supported and should take precedence even though not listed among locally -// supported extensions. +// TransportSequenceNumber RTP v1 and v2 header extensions are handled +// correctly. TEST_F(MediaSessionDescriptionFactoryTest, - TestOfferAnswerWithTransportSequenceNumberInOffer) { + TestOfferAnswerWithTransportSequenceNumberV1LocalAndV1InOffer) { TestTransportSequenceNumberNegotiation( MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Local. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Offer. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01)); // Expected answer. } TEST_F(MediaSessionDescriptionFactoryTest, - TestOfferAnswerWithTransportSequenceNumber01And02InOffer) { + TestOfferAnswerWithTransportSequenceNumberV1LocalAndV1V2InOffer) { TestTransportSequenceNumberNegotiation( MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Local. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Offer. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01)); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV1LocalAndV2InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Offer. + {}); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV2LocalAndV1InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Offer. + {}); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV2LocalAndV1V2InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Offer. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02)); // Expected answer. } TEST_F(MediaSessionDescriptionFactoryTest, - TestOfferAnswerWithTransportSequenceNumber02InOffer) { + TestOfferAnswerWithTransportSequenceNumberV2LocalAndV2InOffer) { TestTransportSequenceNumberNegotiation( - MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Local. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Offer. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02)); // Expected answer. } +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV1V2LocalAndV1InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Offer. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01)); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV1V2LocalAndV2InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Offer. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02)); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV1V2LocalAndV1V2InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Offer. + MAKE_VECTOR( + kRtpExtensionTransportSequenceNumber01And02)); // Expected answer. +} TEST_F(MediaSessionDescriptionFactoryTest, TestNegotiateFrameDescriptorWhenUnexposedLocally) { @@ -2468,7 +2310,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { AttachSenderToMediaDescriptionOptions("audio", MEDIA_TYPE_AUDIO, kAudioTrack2, {kMediaStream1}, 1, &opts); - f1_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); @@ -2494,11 +2335,9 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on - ASSERT_CRYPTO(acd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); EXPECT_EQ(f1_.video_sendrecv_codecs(), vcd->codecs()); - ASSERT_CRYPTO(vcd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); const StreamParamsVec& video_streams = vcd->streams(); ASSERT_EQ(1U, video_streams.size()); @@ -2529,10 +2368,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { EXPECT_EQ(acd->codecs(), updated_acd->codecs()); EXPECT_EQ(vcd->type(), updated_vcd->type()); EXPECT_EQ(vcd->codecs(), updated_vcd->codecs()); - ASSERT_CRYPTO(updated_acd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_TRUE(CompareCryptoParams(acd->cryptos(), updated_acd->cryptos())); - ASSERT_CRYPTO(updated_vcd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_TRUE(CompareCryptoParams(vcd->cryptos(), updated_vcd->cryptos())); const StreamParamsVec& updated_audio_streams = updated_acd->streams(); ASSERT_EQ(2U, updated_audio_streams.size()); @@ -2753,8 +2588,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video", RtpTransceiverDirection::kRecvOnly, kActive, &offer_opts); - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(offer_opts, nullptr).MoveValue(); @@ -2782,8 +2615,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { ASSERT_TRUE(vc); const MediaContentDescription* acd = ac->media_description(); const MediaContentDescription* vcd = vc->media_description(); - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuite); EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); EXPECT_THAT(acd->codecs(), ElementsAreArray(kAudioCodecsAnswer)); @@ -2828,11 +2659,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { const MediaContentDescription* updated_acd = ac->media_description(); const MediaContentDescription* updated_vcd = vc->media_description(); - ASSERT_CRYPTO(updated_acd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_TRUE(CompareCryptoParams(acd->cryptos(), updated_acd->cryptos())); - ASSERT_CRYPTO(updated_vcd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_TRUE(CompareCryptoParams(vcd->cryptos(), updated_vcd->cryptos())); - EXPECT_EQ(acd->type(), updated_acd->type()); EXPECT_EQ(acd->codecs(), updated_acd->codecs()); EXPECT_EQ(vcd->type(), updated_vcd->type()); @@ -3774,54 +3600,9 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfo(false, options, true); } -// Create an offer with bundle enabled and verify the crypto parameters are -// the common set of the available cryptos. -TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoWithOfferBundle) { - TestCryptoWithBundle(true); -} - -// Create an answer with bundle enabled and verify the crypto parameters are -// the common set of the available cryptos. -TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoWithAnswerBundle) { - TestCryptoWithBundle(false); -} - -// Verifies that creating answer fails if the offer has UDP/TLS/RTP/SAVPF but -// DTLS is not enabled locally. -TEST_F(MediaSessionDescriptionFactoryTest, - TestOfferDtlsSavpfWithoutDtlsFailed) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_DISABLED); - tdf2_.set_secure(SEC_DISABLED); - - std::unique_ptr<SessionDescription> offer = - f1_.CreateOfferOrError(CreateAudioMediaSession(), nullptr).MoveValue(); - ASSERT_TRUE(offer.get()); - ContentInfo* offer_content = offer->GetContentByName("audio"); - ASSERT_TRUE(offer_content); - MediaContentDescription* offer_audio_desc = - offer_content->media_description(); - offer_audio_desc->set_protocol(kMediaProtocolDtlsSavpf); - - std::unique_ptr<SessionDescription> answer = - f2_.CreateAnswerOrError(offer.get(), CreateAudioMediaSession(), nullptr) - .MoveValue(); - ASSERT_TRUE(answer); - ContentInfo* answer_content = answer->GetContentByName("audio"); - ASSERT_TRUE(answer_content); - - ASSERT_TRUE(answer_content->rejected); -} - // Offers UDP/TLS/RTP/SAVPF and verifies the answer can be created and contains // UDP/TLS/RTP/SAVPF. TEST_F(MediaSessionDescriptionFactoryTest, TestOfferDtlsSavpfCreateAnswer) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); - std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(CreateAudioMediaSession(), nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -3845,136 +3626,24 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestOfferDtlsSavpfCreateAnswer) { EXPECT_EQ(kMediaProtocolDtlsSavpf, answer_audio_desc->protocol()); } -// Test that we include both SDES and DTLS in the offer, but only include SDES -// in the answer if DTLS isn't negotiated. -TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoDtls) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_DISABLED); - MediaSessionOptions options; - AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &options); - std::unique_ptr<SessionDescription> offer, answer; - const MediaContentDescription* audio_media_desc; - const MediaContentDescription* video_media_desc; - const TransportDescription* audio_trans_desc; - const TransportDescription* video_trans_desc; - - // Generate an offer with SDES and DTLS support. - offer = f1_.CreateOfferOrError(options, nullptr).MoveValue(); - ASSERT_TRUE(offer.get()); - - audio_media_desc = offer->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - video_media_desc = offer->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_EQ(kDefaultCryptoSuiteSize, audio_media_desc->cryptos().size()); - EXPECT_EQ(kDefaultCryptoSuiteSize, video_media_desc->cryptos().size()); - - audio_trans_desc = offer->GetTransportDescriptionByName("audio"); - ASSERT_TRUE(audio_trans_desc); - video_trans_desc = offer->GetTransportDescriptionByName("video"); - ASSERT_TRUE(video_trans_desc); - ASSERT_TRUE(audio_trans_desc->identity_fingerprint.get()); - ASSERT_TRUE(video_trans_desc->identity_fingerprint.get()); - - // Generate an answer with only SDES support, since tdf2 has crypto disabled. - answer = f2_.CreateAnswerOrError(offer.get(), options, nullptr).MoveValue(); - ASSERT_TRUE(answer.get()); - - audio_media_desc = answer->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - video_media_desc = answer->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_EQ(1u, audio_media_desc->cryptos().size()); - EXPECT_EQ(1u, video_media_desc->cryptos().size()); - - audio_trans_desc = answer->GetTransportDescriptionByName("audio"); - ASSERT_TRUE(audio_trans_desc); - video_trans_desc = answer->GetTransportDescriptionByName("video"); - ASSERT_TRUE(video_trans_desc); - ASSERT_FALSE(audio_trans_desc->identity_fingerprint.get()); - ASSERT_FALSE(video_trans_desc->identity_fingerprint.get()); - - // Enable DTLS; the answer should now only have DTLS support. - tdf2_.set_secure(SEC_ENABLED); - answer = f2_.CreateAnswerOrError(offer.get(), options, nullptr).MoveValue(); - ASSERT_TRUE(answer.get()); - - audio_media_desc = answer->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - video_media_desc = answer->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_TRUE(audio_media_desc->cryptos().empty()); - EXPECT_TRUE(video_media_desc->cryptos().empty()); - EXPECT_EQ(kMediaProtocolSavpf, audio_media_desc->protocol()); - EXPECT_EQ(kMediaProtocolSavpf, video_media_desc->protocol()); - - audio_trans_desc = answer->GetTransportDescriptionByName("audio"); - ASSERT_TRUE(audio_trans_desc); - video_trans_desc = answer->GetTransportDescriptionByName("video"); - ASSERT_TRUE(video_trans_desc); - ASSERT_TRUE(audio_trans_desc->identity_fingerprint.get()); - ASSERT_TRUE(video_trans_desc->identity_fingerprint.get()); - - // Try creating offer again. DTLS enabled now, crypto's should be empty - // in new offer. - offer = f1_.CreateOfferOrError(options, offer.get()).MoveValue(); - ASSERT_TRUE(offer.get()); - audio_media_desc = offer->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - video_media_desc = offer->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_TRUE(audio_media_desc->cryptos().empty()); - EXPECT_TRUE(video_media_desc->cryptos().empty()); - - audio_trans_desc = offer->GetTransportDescriptionByName("audio"); - ASSERT_TRUE(audio_trans_desc); - video_trans_desc = offer->GetTransportDescriptionByName("video"); - ASSERT_TRUE(video_trans_desc); - ASSERT_TRUE(audio_trans_desc->identity_fingerprint.get()); - ASSERT_TRUE(video_trans_desc->identity_fingerprint.get()); -} - -// Test that an answer can't be created if cryptos are required but the offer is -// unsecure. -TEST_F(MediaSessionDescriptionFactoryTest, TestSecureAnswerToUnsecureOffer) { - MediaSessionOptions options = CreateAudioMediaSession(); - f1_.set_secure(SEC_DISABLED); - tdf1_.set_secure(SEC_DISABLED); - f2_.set_secure(SEC_REQUIRED); - tdf1_.set_secure(SEC_ENABLED); - - std::unique_ptr<SessionDescription> offer = - f1_.CreateOfferOrError(options, nullptr).MoveValue(); - ASSERT_TRUE(offer.get()); - - auto error = f2_.CreateAnswerOrError(offer.get(), options, nullptr); - EXPECT_FALSE(error.ok()); -} // Test that we accept a DTLS offer without SDES and create an appropriate // answer. TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoOfferDtlsButNotSdes) { + /* TODO(hta): Figure this one out. f1_.set_secure(SEC_DISABLED); f2_.set_secure(SEC_ENABLED); tdf1_.set_secure(SEC_ENABLED); tdf2_.set_secure(SEC_ENABLED); + */ MediaSessionOptions options; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &options); - // Generate an offer with DTLS but without SDES. + // Generate an offer with DTLS std::unique_ptr<SessionDescription> offer = f1_.CreateOfferOrError(options, nullptr).MoveValue(); ASSERT_TRUE(offer.get()); - const AudioContentDescription* audio_offer = - GetFirstAudioContentDescription(offer.get()); - ASSERT_TRUE(audio_offer->cryptos().empty()); - const VideoContentDescription* video_offer = - GetFirstVideoContentDescription(offer.get()); - ASSERT_TRUE(video_offer->cryptos().empty()); - const TransportDescription* audio_offer_trans_desc = offer->GetTransportDescriptionByName("audio"); ASSERT_TRUE(audio_offer_trans_desc->identity_fingerprint.get()); @@ -4656,14 +4325,10 @@ class MediaProtocolTest : public testing::TestWithParam<const char*> { MAKE_VECTOR(kAudioCodecs2)); f2_.set_video_codecs(MAKE_VECTOR(kVideoCodecs2), MAKE_VECTOR(kVideoCodecs2)); - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); tdf1_.set_certificate(rtc::RTCCertificate::Create( std::unique_ptr<rtc::SSLIdentity>(new rtc::FakeSSLIdentity("id1")))); tdf2_.set_certificate(rtc::RTCCertificate::Create( std::unique_ptr<rtc::SSLIdentity>(new rtc::FakeSSLIdentity("id2")))); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); } protected: @@ -4710,6 +4375,9 @@ INSTANTIATE_TEST_SUITE_P(MediaProtocolDtlsPatternTest, TEST_F(MediaSessionDescriptionFactoryTest, TestSetAudioCodecs) { webrtc::test::ScopedKeyValueConfig field_trials; TransportDescriptionFactory tdf(field_trials); + tdf.set_certificate(rtc::RTCCertificate::Create( + std::unique_ptr<rtc::SSLIdentity>(new rtc::FakeSSLIdentity("id")))); + UniqueRandomIdGenerator ssrc_generator; MediaSessionDescriptionFactory sf(nullptr, false, &ssrc_generator, &tdf); std::vector<AudioCodec> send_codecs = MAKE_VECTOR(kAudioCodecs1); @@ -4779,6 +4447,9 @@ bool CodecsMatch(const std::vector<Codec>& codecs1, void TestAudioCodecsOffer(RtpTransceiverDirection direction) { webrtc::test::ScopedKeyValueConfig field_trials; TransportDescriptionFactory tdf(field_trials); + tdf.set_certificate(rtc::RTCCertificate::Create( + std::unique_ptr<rtc::SSLIdentity>(new rtc::FakeSSLIdentity("id")))); + UniqueRandomIdGenerator ssrc_generator; MediaSessionDescriptionFactory sf(nullptr, false, &ssrc_generator, &tdf); const std::vector<AudioCodec> send_codecs = MAKE_VECTOR(kAudioCodecs1); @@ -4879,6 +4550,11 @@ void TestAudioCodecsAnswer(RtpTransceiverDirection offer_direction, webrtc::test::ScopedKeyValueConfig field_trials; TransportDescriptionFactory offer_tdf(field_trials); TransportDescriptionFactory answer_tdf(field_trials); + offer_tdf.set_certificate(rtc::RTCCertificate::Create( + std::unique_ptr<rtc::SSLIdentity>(new rtc::FakeSSLIdentity("offer_id")))); + answer_tdf.set_certificate( + rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>( + new rtc::FakeSSLIdentity("answer_id")))); UniqueRandomIdGenerator ssrc_generator1, ssrc_generator2; MediaSessionDescriptionFactory offer_factory(nullptr, false, &ssrc_generator1, &offer_tdf); diff --git a/third_party/libwebrtc/pc/peer_connection.cc b/third_party/libwebrtc/pc/peer_connection.cc index 8c9b0cbab6..76cf13aa18 100644 --- a/third_party/libwebrtc/pc/peer_connection.cc +++ b/third_party/libwebrtc/pc/peer_connection.cc @@ -104,13 +104,7 @@ uint32_t ConvertIceTransportTypeToCandidateFilter( IceCandidatePairType GetIceCandidatePairCounter( const cricket::Candidate& local, const cricket::Candidate& remote) { - const auto& l = local.type(); - const auto& r = remote.type(); - const auto& host = cricket::LOCAL_PORT_TYPE; - const auto& srflx = cricket::STUN_PORT_TYPE; - const auto& relay = cricket::RELAY_PORT_TYPE; - const auto& prflx = cricket::PRFLX_PORT_TYPE; - if (l == host && r == host) { + if (local.is_local() && remote.is_local()) { bool local_hostname = !local.address().hostname().empty() && local.address().IsUnresolvedIP(); bool remote_hostname = !remote.address().hostname().empty() && @@ -143,34 +137,41 @@ IceCandidatePairType GetIceCandidatePairCounter( } } } - if (l == host && r == srflx) - return kIceCandidatePairHostSrflx; - if (l == host && r == relay) - return kIceCandidatePairHostRelay; - if (l == host && r == prflx) - return kIceCandidatePairHostPrflx; - if (l == srflx && r == host) - return kIceCandidatePairSrflxHost; - if (l == srflx && r == srflx) - return kIceCandidatePairSrflxSrflx; - if (l == srflx && r == relay) - return kIceCandidatePairSrflxRelay; - if (l == srflx && r == prflx) - return kIceCandidatePairSrflxPrflx; - if (l == relay && r == host) - return kIceCandidatePairRelayHost; - if (l == relay && r == srflx) - return kIceCandidatePairRelaySrflx; - if (l == relay && r == relay) - return kIceCandidatePairRelayRelay; - if (l == relay && r == prflx) - return kIceCandidatePairRelayPrflx; - if (l == prflx && r == host) - return kIceCandidatePairPrflxHost; - if (l == prflx && r == srflx) - return kIceCandidatePairPrflxSrflx; - if (l == prflx && r == relay) - return kIceCandidatePairPrflxRelay; + + if (local.is_local()) { + if (remote.is_stun()) + return kIceCandidatePairHostSrflx; + if (remote.is_relay()) + return kIceCandidatePairHostRelay; + if (remote.is_prflx()) + return kIceCandidatePairHostPrflx; + } else if (local.is_stun()) { + if (remote.is_local()) + return kIceCandidatePairSrflxHost; + if (remote.is_stun()) + return kIceCandidatePairSrflxSrflx; + if (remote.is_relay()) + return kIceCandidatePairSrflxRelay; + if (remote.is_prflx()) + return kIceCandidatePairSrflxPrflx; + } else if (local.is_relay()) { + if (remote.is_local()) + return kIceCandidatePairRelayHost; + if (remote.is_stun()) + return kIceCandidatePairRelaySrflx; + if (remote.is_relay()) + return kIceCandidatePairRelayRelay; + if (remote.is_prflx()) + return kIceCandidatePairRelayPrflx; + } else if (local.is_prflx()) { + if (remote.is_local()) + return kIceCandidatePairPrflxHost; + if (remote.is_stun()) + return kIceCandidatePairPrflxSrflx; + if (remote.is_relay()) + return kIceCandidatePairPrflxRelay; + } + return kIceCandidatePairMax; } @@ -347,15 +348,7 @@ bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration, return false; // Enable DTLS by default if we have an identity store or a certificate. - bool default_enabled = - (dependencies.cert_generator || !configuration.certificates.empty()); - -#if defined(WEBRTC_FUCHSIA) - // The `configuration` can override the default value. - return configuration.enable_dtls_srtp.value_or(default_enabled); -#else - return default_enabled; -#endif + return (dependencies.cert_generator || !configuration.certificates.empty()); } // Calls `ParseIceServersOrError` to extract ice server information from the @@ -415,9 +408,6 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( int max_ipv6_networks; bool disable_link_local_networks; absl::optional<int> screencast_min_bitrate; -#if defined(WEBRTC_FUCHSIA) - absl::optional<bool> enable_dtls_srtp; -#endif TcpCandidatePolicy tcp_candidate_policy; CandidateNetworkPolicy candidate_network_policy; int audio_jitter_buffer_max_packets; @@ -482,9 +472,6 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( max_ipv6_networks == o.max_ipv6_networks && disable_link_local_networks == o.disable_link_local_networks && screencast_min_bitrate == o.screencast_min_bitrate && -#if defined(WEBRTC_FUCHSIA) - enable_dtls_srtp == o.enable_dtls_srtp && -#endif ice_candidate_pool_size == o.ice_candidate_pool_size && prune_turn_ports == o.prune_turn_ports && turn_port_prune_policy == o.turn_port_prune_policy && @@ -1694,6 +1681,15 @@ RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) { return RTCError::OK(); } +void PeerConnection::ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) { + worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, settings]() { + RTC_DCHECK_RUN_ON(worker_thread()); + call_->GetTransportControllerSend()->ReconfigureBandwidthEstimation( + settings); + })); +} + void PeerConnection::SetAudioPlayout(bool playout) { if (!worker_thread()->IsCurrent()) { worker_thread()->BlockingCall( @@ -2706,9 +2702,7 @@ void PeerConnection::ReportRemoteIceCandidateAdded( bool PeerConnection::SrtpRequired() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return (dtls_enabled_ || - sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() == - cricket::SEC_REQUIRED); + return dtls_enabled_; } void PeerConnection::OnTransportControllerGatheringState( diff --git a/third_party/libwebrtc/pc/peer_connection.h b/third_party/libwebrtc/pc/peer_connection.h index 406bc1cef2..3c923139dc 100644 --- a/third_party/libwebrtc/pc/peer_connection.h +++ b/third_party/libwebrtc/pc/peer_connection.h @@ -236,6 +236,8 @@ class PeerConnection : public PeerConnectionInternal, const std::vector<cricket::Candidate>& candidates) override; RTCError SetBitrate(const BitrateSettings& bitrate) override; + void ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) override; void SetAudioPlayout(bool playout) override; void SetAudioRecording(bool recording) override; diff --git a/third_party/libwebrtc/pc/peer_connection_crypto_unittest.cc b/third_party/libwebrtc/pc/peer_connection_crypto_unittest.cc index 3b3f502e1f..1d90e04714 100644 --- a/third_party/libwebrtc/pc/peer_connection_crypto_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_crypto_unittest.cc @@ -24,7 +24,6 @@ #include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/create_peerconnection_factory.h" #include "api/crypto/crypto_options.h" -#include "api/crypto_params.h" #include "api/jsep.h" #include "api/peer_connection_interface.h" #include "api/scoped_refptr.h" @@ -178,13 +177,6 @@ SdpContentPredicate HaveDtlsFingerprint() { }; } -SdpContentPredicate HaveSdesCryptos() { - return [](const cricket::ContentInfo* content, - const cricket::TransportInfo* transport) { - return !content->media_description()->cryptos().empty(); - }; -} - SdpContentPredicate HaveProtocol(const std::string& protocol) { return [protocol](const cricket::ContentInfo* content, const cricket::TransportInfo* transport) { @@ -192,22 +184,6 @@ SdpContentPredicate HaveProtocol(const std::string& protocol) { }; } -SdpContentPredicate HaveSdesGcmCryptos(size_t num_crypto_suites) { - return [num_crypto_suites](const cricket::ContentInfo* content, - const cricket::TransportInfo* transport) { - const auto& cryptos = content->media_description()->cryptos(); - if (cryptos.size() != num_crypto_suites) { - return false; - } - for (size_t i = 0; i < cryptos.size(); ++i) { - if (cryptos[i].key_params.size() == 67U && - cryptos[i].crypto_suite == "AEAD_AES_256_GCM") - return true; - } - return false; - }; -} - class PeerConnectionCryptoTest : public PeerConnectionCryptoBaseTest, public ::testing::WithParamInterface<SdpSemantics> { @@ -215,20 +191,13 @@ class PeerConnectionCryptoTest PeerConnectionCryptoTest() : PeerConnectionCryptoBaseTest(GetParam()) {} }; -SdpContentMutator RemoveSdesCryptos() { - return [](cricket::ContentInfo* content, cricket::TransportInfo* transport) { - content->media_description()->set_cryptos({}); - }; -} - SdpContentMutator RemoveDtlsFingerprint() { return [](cricket::ContentInfo* content, cricket::TransportInfo* transport) { transport->description.identity_fingerprint.reset(); }; } -// When DTLS is enabled, the SDP offer/answer should have a DTLS fingerprint and -// no SDES cryptos. +// When DTLS is enabled, the SDP offer/answer should have a DTLS fingerprint TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsEnabled) { RTCConfiguration config; auto caller = CreatePeerConnectionWithAudioVideo(config); @@ -238,7 +207,6 @@ TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsEnabled) { ASSERT_FALSE(offer->description()->contents().empty()); EXPECT_TRUE(SdpContentsAll(HaveDtlsFingerprint(), offer->description())); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), offer->description())); EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolDtlsSavpf), offer->description())); } @@ -253,238 +221,10 @@ TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsEnabled) { ASSERT_FALSE(answer->description()->contents().empty()); EXPECT_TRUE(SdpContentsAll(HaveDtlsFingerprint(), answer->description())); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), answer->description())); EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolDtlsSavpf), answer->description())); } -#if defined(WEBRTC_FUCHSIA) -// When DTLS is disabled, the SDP offer/answer should include SDES cryptos and -// should not have a DTLS fingerprint. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsDisabled) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), offer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf), - offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsDisabled) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOffer()); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), answer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf), - answer->description())); -} - -// When encryption is disabled, the SDP offer/answer should have neither a DTLS -// fingerprint nor any SDES crypto options. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenEncryptionDisabled) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), offer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf), - offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenEncryptionDisabled) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOffer()); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), answer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf), - answer->description())); -} - -// CryptoOptions has been promoted to RTCConfiguration. As such if it is ever -// set in the configuration it should overrite the settings set in the factory. -TEST_P(PeerConnectionCryptoTest, RTCConfigurationCryptoOptionOverridesFactory) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - CryptoOptions crypto_options; - crypto_options.srtp.enable_gcm_crypto_suites = false; - config.crypto_options = crypto_options; - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - // This should exist if GCM is enabled see CorrectCryptoInOfferWithSdesAndGcm - EXPECT_FALSE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description())); -} - -// When DTLS is disabled and GCM cipher suites are enabled, the SDP offer/answer -// should have the correct ciphers in the SDES crypto options. -// With GCM cipher suites enabled, there will be 3 cryptos in the offer and 1 -// in the answer. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWithSdesAndGcm) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWithSdesAndGcm) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - for (cricket::ContentInfo& content : offer->description()->contents()) { - auto cryptos = content.media_description()->cryptos(); - cryptos.erase(cryptos.begin()); // Assumes that non-GCM is the default. - content.media_description()->set_cryptos(cryptos); - } - - callee->SetRemoteDescription(std::move(offer)); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(1), answer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CanSetSdesGcmRemoteOfferAndLocalAnswer) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - ASSERT_TRUE(callee->SetLocalDescription(std::move(answer))); -} - -// The following group tests that two PeerConnections can successfully exchange -// an offer/answer when DTLS is off and that they will refuse any offer/answer -// applied locally/remotely if it does not include SDES cryptos. -TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOfferAndSetAsLocal(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswerAndSetAsLocal(); - ASSERT_TRUE(answer); - ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetLocalOfferWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - SdpContentsForEach(RemoveSdesCryptos(), offer->description()); - - EXPECT_FALSE(caller->SetLocalDescription(std::move(offer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetRemoteOfferWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - SdpContentsForEach(RemoveSdesCryptos(), offer->description()); - - EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetLocalAnswerWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); - auto answer = callee->CreateAnswer(); - SdpContentsForEach(RemoveSdesCryptos(), answer->description()); - - EXPECT_FALSE(callee->SetLocalDescription(std::move(answer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetRemoteAnswerWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); - auto answer = callee->CreateAnswerAndSetAsLocal(); - SdpContentsForEach(RemoveSdesCryptos(), answer->description()); - - EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer))); -} -#endif - // The following group tests that two PeerConnections can successfully exchange // an offer/answer when DTLS is on and that they will refuse any offer/answer // applied locally/remotely if it does not include a DTLS fingerprint. @@ -545,28 +285,6 @@ TEST_P(PeerConnectionCryptoTest, EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer))); } -#if defined(WEBRTC_FUCHSIA) -// Test that an offer/answer can be exchanged when encryption is disabled. -TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenNoEncryption) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOfferAndSetAsLocal(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswerAndSetAsLocal(); - ASSERT_TRUE(answer); - ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer))); -} -#endif - // Tests that a DTLS call can be established when the certificate is specified // in the PeerConnection config and no certificate generator is specified. TEST_P(PeerConnectionCryptoTest, diff --git a/third_party/libwebrtc/pc/peer_connection_encodings_integrationtest.cc b/third_party/libwebrtc/pc/peer_connection_encodings_integrationtest.cc index 4a93e915df..06299d7029 100644 --- a/third_party/libwebrtc/pc/peer_connection_encodings_integrationtest.cc +++ b/third_party/libwebrtc/pc/peer_connection_encodings_integrationtest.cc @@ -9,6 +9,7 @@ */ #include <string> +#include <string_view> #include <vector> #include "absl/strings/match.h" @@ -41,6 +42,7 @@ #include "pc/test/simulcast_layer_util.h" #include "rtc_base/gunit.h" #include "rtc_base/physical_socket_server.h" +#include "rtc_base/thread.h" #include "test/gmock.h" #include "test/gtest.h" @@ -269,6 +271,34 @@ class PeerConnectionEncodingsIntegrationTest : public ::testing::Test { return num_sending_layers == num_active_layers; } + int EncodedFrames(rtc::scoped_refptr<PeerConnectionTestWrapper> pc_wrapper, + std::string_view rid) { + rtc::scoped_refptr<const RTCStatsReport> report = GetStats(pc_wrapper); + std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps = + report->GetStatsOfType<RTCOutboundRtpStreamStats>(); + for (const auto* outbound_rtp : outbound_rtps) { + if (outbound_rtp->rid.value_or("") == rid) { + return outbound_rtp->frames_encoded.value_or(0); + } + } + return 0; + } + + bool EncodingIsActive( + rtc::scoped_refptr<PeerConnectionTestWrapper> pc_wrapper, + std::string_view rid) { + rtc::scoped_refptr<const RTCStatsReport> report = GetStats(pc_wrapper); + std::vector<const RTCOutboundRtpStreamStats*> outbound_rtps = + report->GetStatsOfType<RTCOutboundRtpStreamStats>(); + for (const auto* outbound_rtp : outbound_rtps) { + if (outbound_rtp->rid.value_or("") == rid) { + return *outbound_rtp->active; + } + } + RTC_CHECK(false) << "Rid not found: " << rid; + return false; + } + bool HasOutboundRtpWithRidAndScalabilityMode( rtc::scoped_refptr<PeerConnectionTestWrapper> pc_wrapper, absl::string_view rid, @@ -1964,6 +1994,65 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, Simulcast) { EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3")); } +TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, + SimulcastEncodingStopWhenRtpEncodingChangeToInactive) { + rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc(); + if (SkipTestDueToAv1Missing(local_pc_wrapper)) { + return; + } + rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc(); + ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper); + + std::vector<cricket::SimulcastLayer> layers = + CreateLayers({"q", "h", "f"}, /*active=*/true); + rtc::scoped_refptr<RtpTransceiverInterface> transceiver = + AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, + layers); + std::vector<RtpCodecCapability> codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, codec_name_); + transceiver->SetCodecPreferences(codecs); + + rtc::scoped_refptr<RtpSenderInterface> sender = transceiver->sender(); + RtpParameters parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + ASSERT_EQ(parameters.encodings[0].rid, "q"); + parameters.encodings[0].scalability_mode = "L1T3"; + parameters.encodings[0].scale_resolution_down_by = 4; + ASSERT_EQ(parameters.encodings[1].rid, "h"); + parameters.encodings[1].scalability_mode = "L1T3"; + parameters.encodings[1].scale_resolution_down_by = 2; + ASSERT_EQ(parameters.encodings[2].rid, "f"); + parameters.encodings[2].scalability_mode = "L1T3"; + parameters.encodings[2].scale_resolution_down_by = 1; + sender->SetParameters(parameters); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "f") > 1, + kLongTimeoutForRampingUp.ms()); + + // Switch higest layer to Inactive. + parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + parameters.encodings[2].active = false; + sender->SetParameters(parameters); + ASSERT_TRUE_WAIT(!EncodingIsActive(local_pc_wrapper, "f"), + kDefaultTimeout.ms()); + + int encoded_frames_f = EncodedFrames(local_pc_wrapper, "f"); + int encoded_frames_h = EncodedFrames(local_pc_wrapper, "h"); + int encoded_frames_q = EncodedFrames(local_pc_wrapper, "q"); + + // Wait until the encoder has encoded another 10 frames on lower layers. + ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "q") > encoded_frames_q + 10, + kDefaultTimeout.ms()); + ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "h") > encoded_frames_h + 10, + kDefaultTimeout.ms()); + EXPECT_LE(EncodedFrames(local_pc_wrapper, "f") - encoded_frames_f, 2); +} + INSTANTIATE_TEST_SUITE_P(StandardPath, PeerConnectionEncodingsIntegrationParameterizedTest, ::testing::Values("VP8", diff --git a/third_party/libwebrtc/pc/peer_connection_ice_unittest.cc b/third_party/libwebrtc/pc/peer_connection_ice_unittest.cc index 492e108cbc..267cca4959 100644 --- a/third_party/libwebrtc/pc/peer_connection_ice_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_ice_unittest.cc @@ -94,7 +94,6 @@ using ::testing::Values; constexpr int kIceCandidatesTimeout = 10000; constexpr int64_t kWaitTimeout = 10000; -constexpr uint64_t kTiebreakerDefault = 44444; class PeerConnectionWrapperForIceTest : public PeerConnectionWrapper { public: @@ -362,7 +361,7 @@ class PeerConnectionIceTest << " != " << b.address().ToString(); } if (a.type() != b.type()) { - failure_info << "\ntype: " << a.type() << " != " << b.type(); + failure_info << "\ntype: " << a.type_name() << " != " << b.type_name(); } std::string failure_info_str = failure_info.str(); if (failure_info_str.empty()) { @@ -1448,7 +1447,6 @@ class PeerConnectionIceConfigTest : public ::testing::Test { packet_socket_factory_.get(), &field_trials_)); port_allocator_ = port_allocator.get(); - port_allocator_->SetIceTiebreaker(kTiebreakerDefault); PeerConnectionDependencies pc_dependencies(&observer_); pc_dependencies.allocator = std::move(port_allocator); auto result = pc_factory_->CreatePeerConnectionOrError( diff --git a/third_party/libwebrtc/pc/peer_connection_integrationtest.cc b/third_party/libwebrtc/pc/peer_connection_integrationtest.cc index c960a36b5e..24ca52f619 100644 --- a/third_party/libwebrtc/pc/peer_connection_integrationtest.cc +++ b/third_party/libwebrtc/pc/peer_connection_integrationtest.cc @@ -275,26 +275,6 @@ TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) { ASSERT_TRUE(ExpectNewFrames(media_expectations)); } -#if defined(WEBRTC_FUCHSIA) -// Uses SDES instead of DTLS for key agreement. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) { - PeerConnectionInterface::RTCConfiguration sdes_config; - sdes_config.enable_dtls_srtp.emplace(false); - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config)); - ConnectFakeSignaling(); - - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} -#endif - // Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions` // option to offer encrypted versions of all header extensions alongside the // unencrypted versions. @@ -3087,25 +3067,23 @@ TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) { // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this // metric is only populated when we reach kIceConnectionComplete in the // current implementation. - EXPECT_EQ(cricket::RELAY_PORT_TYPE, - caller()->last_candidate_gathered().type()); - EXPECT_EQ(cricket::RELAY_PORT_TYPE, - callee()->last_candidate_gathered().type()); + EXPECT_TRUE(caller()->last_candidate_gathered().is_relay()); + EXPECT_TRUE(callee()->last_candidate_gathered().is_relay()); // Loosen the caller's candidate filter. caller_config = caller()->pc()->GetConfiguration(); caller_config.type = PeerConnectionInterface::kAll; caller()->pc()->SetConfiguration(caller_config); // We should have gathered a new host candidate. - EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE, - caller()->last_candidate_gathered().type(), kDefaultTimeout); + EXPECT_TRUE_WAIT(caller()->last_candidate_gathered().is_local(), + kDefaultTimeout); // Loosen the callee's candidate filter. callee_config = callee()->pc()->GetConfiguration(); callee_config.type = PeerConnectionInterface::kAll; callee()->pc()->SetConfiguration(callee_config); - EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE, - callee()->last_candidate_gathered().type(), kDefaultTimeout); + EXPECT_TRUE_WAIT(callee()->last_candidate_gathered().is_local(), + kDefaultTimeout); // Create an offer and verify that it does not contain an ICE restart (i.e new // ice credentials). diff --git a/third_party/libwebrtc/pc/peer_connection_interface_unittest.cc b/third_party/libwebrtc/pc/peer_connection_interface_unittest.cc index 61794bb0f9..71c85d4c6f 100644 --- a/third_party/libwebrtc/pc/peer_connection_interface_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_interface_unittest.cc @@ -114,7 +114,6 @@ static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"}; static const char kRecvonly[] = "recvonly"; static const char kSendrecv[] = "sendrecv"; -constexpr uint64_t kTiebreakerDefault = 44444; // Reference SDP with a MediaStream with label "stream1" and audio track with // id "audio_1" and a video track with id "video_1; @@ -420,29 +419,6 @@ static const char kSdpStringMs1Video1[] = "a=ssrc:4 cname:stream1\r\n" "a=ssrc:4 msid:stream1 videotrack1\r\n"; -static const char kDtlsSdesFallbackSdp[] = - "v=0\r\n" - "o=xxxxxx 7 2 IN IP4 0.0.0.0\r\n" - "s=-\r\n" - "c=IN IP4 0.0.0.0\r\n" - "t=0 0\r\n" - "a=group:BUNDLE audio\r\n" - "a=msid-semantic: WMS\r\n" - "m=audio 1 RTP/SAVPF 0\r\n" - "a=sendrecv\r\n" - "a=rtcp-mux\r\n" - "a=mid:audio\r\n" - "a=ssrc:1 cname:stream1\r\n" - "a=ice-ufrag:e5785931\r\n" - "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" - "a=rtpmap:0 pcmu/8000\r\n" - "a=fingerprint:sha-1 " - "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" - "a=setup:actpass\r\n" - "a=crypto:0 AES_CM_128_HMAC_SHA1_80 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n"; - class RtcEventLogOutputNull final : public RtcEventLogOutput { public: bool IsActive() const override { return true; } @@ -734,7 +710,6 @@ class PeerConnectionInterfaceBaseTest : public ::testing::Test { std::make_unique<rtc::BasicPacketSocketFactory>(vss_.get()), &field_trials_)); port_allocator_ = port_allocator.get(); - port_allocator_->SetIceTiebreaker(kTiebreakerDefault); // Create certificate generator unless DTLS constraint is explicitly set to // false. @@ -1662,7 +1637,7 @@ TEST_P(PeerConnectionInterfaceTest, AddTrackWithoutStream) { // Test that we can call GetStats() after AddTrack but before connecting // the PeerConnection to a peer. TEST_P(PeerConnectionInterfaceTest, AddTrackBeforeConnecting) { - CreatePeerConnectionWithoutDtls(); + CreatePeerConnection(); rtc::scoped_refptr<AudioTrackInterface> audio_track( CreateAudioTrack("audio_track")); rtc::scoped_refptr<VideoTrackInterface> video_track( @@ -1673,7 +1648,7 @@ TEST_P(PeerConnectionInterfaceTest, AddTrackBeforeConnecting) { } TEST_P(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddTrack) { - CreatePeerConnectionWithoutDtls(); + CreatePeerConnection(); rtc::scoped_refptr<AudioTrackInterface> audio_track( CreateAudioTrack("audio_track")); rtc::scoped_refptr<VideoTrackInterface> video_track( @@ -1695,7 +1670,7 @@ TEST_P(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddTrack) { // Don't run under Unified Plan since the stream API is not available. TEST_F(PeerConnectionInterfaceTestPlanB, AttachmentIdIsSetOnAddStream) { - CreatePeerConnectionWithoutDtls(); + CreatePeerConnection(); AddVideoStream(kStreamId1); auto senders = pc_->GetSenders(); ASSERT_EQ(1u, senders.size()); @@ -2130,24 +2105,6 @@ TEST_P(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) { #endif } -// Test that fallback from DTLS to SDES is not supported. -// The fallback was previously supported but was removed to simplify the code -// and because it's non-standard. -TEST_P(PeerConnectionInterfaceTest, DtlsSdesFallbackNotSupported) { - RTCConfiguration rtc_config; - CreatePeerConnection(rtc_config); - // Wait for fake certificate to be generated. Previously, this is what caused - // the "a=crypto" lines to be rejected. - AddAudioTrack("audio_label"); - AddVideoTrack("video_label"); - ASSERT_NE(nullptr, fake_certificate_generator_); - EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(), - kTimeout); - std::unique_ptr<SessionDescriptionInterface> desc( - CreateSessionDescription(SdpType::kOffer, kDtlsSdesFallbackSdp, nullptr)); - EXPECT_FALSE(DoSetSessionDescription(std::move(desc), /*local=*/false)); -} - // Test that we can create an audio only offer and receive an answer with a // limited set of audio codecs and receive an updated offer with more audio // codecs, where the added codecs are not supported. diff --git a/third_party/libwebrtc/pc/peer_connection_proxy.h b/third_party/libwebrtc/pc/peer_connection_proxy.h index 6db27f2dd5..aaccfe45d0 100644 --- a/third_party/libwebrtc/pc/peer_connection_proxy.h +++ b/third_party/libwebrtc/pc/peer_connection_proxy.h @@ -16,6 +16,7 @@ #include <vector> #include "api/peer_connection_interface.h" +#include "api/transport/bandwidth_estimation_settings.h" #include "pc/proxy.h" namespace webrtc { @@ -137,6 +138,9 @@ PROXY_METHOD2(void, std::function<void(RTCError)>) PROXY_METHOD1(bool, RemoveIceCandidates, const std::vector<cricket::Candidate>&) PROXY_METHOD1(RTCError, SetBitrate, const BitrateSettings&) +PROXY_METHOD1(void, + ReconfigureBandwidthEstimation, + const BandwidthEstimationSettings&) PROXY_METHOD1(void, SetAudioPlayout, bool) PROXY_METHOD1(void, SetAudioRecording, bool) // This method will be invoked on the network thread. See diff --git a/third_party/libwebrtc/pc/rtc_stats_collector.cc b/third_party/libwebrtc/pc/rtc_stats_collector.cc index a5a3067fa1..a49e8ef0b2 100644 --- a/third_party/libwebrtc/pc/rtc_stats_collector.cc +++ b/third_party/libwebrtc/pc/rtc_stats_collector.cc @@ -72,7 +72,7 @@ namespace { const char kDirectionInbound = 'I'; const char kDirectionOutbound = 'O'; -const char* kAudioPlayoutSingletonId = "AP"; +static constexpr char kAudioPlayoutSingletonId[] = "AP"; // TODO(https://crbug.com/webrtc/10656): Consider making IDs less predictable. std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) { @@ -164,19 +164,6 @@ std::string RTCMediaSourceStatsIDFromKindAndAttachment( return sb.str(); } -const char* CandidateTypeToRTCIceCandidateType(const cricket::Candidate& c) { - if (c.is_local()) - return "host"; - if (c.is_stun()) - return "srflx"; - if (c.is_prflx()) - return "prflx"; - if (c.is_relay()) - return "relay"; - RTC_DCHECK_NOTREACHED(); - return nullptr; -} - const char* DataStateToRTCDataChannelState( DataChannelInterface::DataState state) { switch (state) { @@ -961,12 +948,10 @@ const std::string& ProduceIceCandidateStats(Timestamp timestamp, if (is_local) { candidate_stats->network_type = NetworkTypeToStatsType(candidate.network_type()); - const std::string& candidate_type = candidate.type(); const std::string& relay_protocol = candidate.relay_protocol(); const std::string& url = candidate.url(); - if (candidate_type == cricket::RELAY_PORT_TYPE || - (candidate_type == cricket::PRFLX_PORT_TYPE && - !relay_protocol.empty())) { + if (candidate.is_relay() || + (candidate.is_prflx() && !relay_protocol.empty())) { RTC_DCHECK(relay_protocol.compare("udp") == 0 || relay_protocol.compare("tcp") == 0 || relay_protocol.compare("tls") == 0); @@ -974,7 +959,7 @@ const std::string& ProduceIceCandidateStats(Timestamp timestamp, if (!url.empty()) { candidate_stats->url = url; } - } else if (candidate_type == cricket::STUN_PORT_TYPE) { + } else if (candidate.is_stun()) { if (!url.empty()) { candidate_stats->url = url; } @@ -1000,8 +985,7 @@ const std::string& ProduceIceCandidateStats(Timestamp timestamp, candidate_stats->address = candidate.address().ipaddr().ToString(); candidate_stats->port = static_cast<int32_t>(candidate.address().port()); candidate_stats->protocol = candidate.protocol(); - candidate_stats->candidate_type = - CandidateTypeToRTCIceCandidateType(candidate); + candidate_stats->candidate_type = candidate.type_name(); candidate_stats->priority = static_cast<int32_t>(candidate.priority()); candidate_stats->foundation = candidate.foundation(); auto related_address = candidate.related_address(); diff --git a/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc b/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc index 61b3bca1db..98cbd2d7e3 100644 --- a/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc +++ b/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc @@ -23,6 +23,7 @@ #include <vector> #include "absl/strings/str_replace.h" +#include "absl/types/optional.h" #include "api/candidate.h" #include "api/dtls_transport_interface.h" #include "api/media_stream_interface.h" @@ -211,7 +212,7 @@ std::unique_ptr<cricket::Candidate> CreateFakeCandidate( int port, const std::string& protocol, const rtc::AdapterType adapter_type, - const std::string& candidate_type, + const absl::string_view candidate_type, uint32_t priority, const rtc::AdapterType underlying_type_for_vpn = rtc::ADAPTER_TYPE_UNKNOWN) { @@ -3723,7 +3724,7 @@ class RTCTestStats : public RTCStats { RTCTestStats(const std::string& id, Timestamp timestamp) : RTCStats(id, timestamp) {} - RTCStatsMember<int32_t> dummy_stat; + absl::optional<int32_t> dummy_stat; }; WEBRTC_RTCSTATS_IMPL(RTCTestStats, diff --git a/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc b/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc index 002f9d34b5..de8e6e3f67 100644 --- a/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc +++ b/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc @@ -18,6 +18,7 @@ #include "absl/algorithm/container.h" #include "absl/strings/match.h" +#include "absl/types/optional.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/audio_options.h" @@ -212,14 +213,14 @@ class RTCStatsVerifier { } template <typename T> - void MarkAttributeTested(const RTCStatsMember<T>& field, + void MarkAttributeTested(const absl::optional<T>& field, bool test_successful) { untested_attribute_names_.erase(stats_->GetAttribute(field).name()); all_tests_successful_ &= test_successful; } template <typename T> - void TestAttributeIsDefined(const RTCStatsMember<T>& field) { + void TestAttributeIsDefined(const absl::optional<T>& field) { EXPECT_TRUE(field.has_value()) << stats_->type() << "." << stats_->GetAttribute(field).name() << "[" << stats_->id() << "] was undefined."; @@ -227,7 +228,7 @@ class RTCStatsVerifier { } template <typename T> - void TestAttributeIsUndefined(const RTCStatsMember<T>& field) { + void TestAttributeIsUndefined(const absl::optional<T>& field) { Attribute attribute = stats_->GetAttribute(field); EXPECT_FALSE(field.has_value()) << stats_->type() << "." << attribute.name() << "[" << stats_->id() @@ -236,7 +237,7 @@ class RTCStatsVerifier { } template <typename T> - void TestAttributeIsPositive(const RTCStatsMember<T>& field) { + void TestAttributeIsPositive(const absl::optional<T>& field) { Attribute attribute = stats_->GetAttribute(field); EXPECT_TRUE(field.has_value()) << stats_->type() << "." << attribute.name() << "[" << stats_->id() << "] was undefined."; @@ -252,7 +253,7 @@ class RTCStatsVerifier { } template <typename T> - void TestAttributeIsNonNegative(const RTCStatsMember<T>& field) { + void TestAttributeIsNonNegative(const absl::optional<T>& field) { Attribute attribute = stats_->GetAttribute(field); EXPECT_TRUE(field.has_value()) << stats_->type() << "." << attribute.name() << "[" << stats_->id() << "] was undefined."; @@ -268,13 +269,13 @@ class RTCStatsVerifier { } template <typename T> - void TestAttributeIsIDReference(const RTCStatsMember<T>& field, + void TestAttributeIsIDReference(const absl::optional<T>& field, const char* expected_type) { TestAttributeIsIDReference(field, expected_type, false); } template <typename T> - void TestAttributeIsOptionalIDReference(const RTCStatsMember<T>& field, + void TestAttributeIsOptionalIDReference(const absl::optional<T>& field, const char* expected_type) { TestAttributeIsIDReference(field, expected_type, true); } @@ -291,7 +292,7 @@ class RTCStatsVerifier { private: template <typename T> - void TestAttributeIsIDReference(const RTCStatsMember<T>& field, + void TestAttributeIsIDReference(const absl::optional<T>& field, const char* expected_type, bool optional) { if (optional && !field.has_value()) { diff --git a/third_party/libwebrtc/pc/rtc_stats_traversal.cc b/third_party/libwebrtc/pc/rtc_stats_traversal.cc index dfd0570b8f..e9d11b5ae5 100644 --- a/third_party/libwebrtc/pc/rtc_stats_traversal.cc +++ b/third_party/libwebrtc/pc/rtc_stats_traversal.cc @@ -15,6 +15,7 @@ #include <utility> #include <vector> +#include "absl/types/optional.h" #include "api/stats/rtcstats_objects.h" #include "rtc_base/checks.h" @@ -42,7 +43,7 @@ void TraverseAndTakeVisitedStats(RTCStatsReport* report, } } -void AddIdIfDefined(const RTCStatsMember<std::string>& id, +void AddIdIfDefined(const absl::optional<std::string>& id, std::vector<const std::string*>* neighbor_ids) { if (id.has_value()) neighbor_ids->push_back(&(*id)); diff --git a/third_party/libwebrtc/pc/rtp_receiver.cc b/third_party/libwebrtc/pc/rtp_receiver.cc index a2b3353c0e..9431aab10a 100644 --- a/third_party/libwebrtc/pc/rtp_receiver.cc +++ b/third_party/libwebrtc/pc/rtp_receiver.cc @@ -12,6 +12,7 @@ #include <stddef.h> +#include <atomic> #include <utility> #include <vector> @@ -22,8 +23,10 @@ namespace webrtc { // This function is only expected to be called on the signalling thread. +// On the other hand, some test or even production setups may use +// several signaling threads. int RtpReceiverInternal::GenerateUniqueId() { - static int g_unique_id = 0; + static std::atomic<int> g_unique_id{0}; return ++g_unique_id; } diff --git a/third_party/libwebrtc/pc/rtp_transceiver.cc b/third_party/libwebrtc/pc/rtp_transceiver.cc index 34d744a3bb..de31b2e36a 100644 --- a/third_party/libwebrtc/pc/rtp_transceiver.cc +++ b/third_party/libwebrtc/pc/rtp_transceiver.cc @@ -171,6 +171,35 @@ RtpTransceiver::RtpTransceiver( : media_engine()->voice().send_codecs()); senders_.push_back(sender); receivers_.push_back(receiver); + + // Set default header extensions depending on whether simulcast/SVC is used. + RtpParameters parameters = sender->internal()->GetParametersInternal(); + bool uses_simulcast = parameters.encodings.size() > 1; + bool uses_svc = !parameters.encodings.empty() && + parameters.encodings[0].scalability_mode.has_value() && + parameters.encodings[0].scalability_mode != + ScalabilityModeToString(ScalabilityMode::kL1T1); + if (uses_simulcast || uses_svc) { + // Enable DD and VLA extensions, can be deactivated by the API. + // Skip this if the GFD extension was enabled via field trial + // for backward compability reasons. + bool uses_gfd = + absl::c_find_if( + header_extensions_to_negotiate_, + [](const RtpHeaderExtensionCapability& ext) { + return ext.uri == RtpExtension::kGenericFrameDescriptorUri00 && + ext.direction != webrtc::RtpTransceiverDirection::kStopped; + }) != header_extensions_to_negotiate_.end(); + if (!uses_gfd) { + for (RtpHeaderExtensionCapability& ext : + header_extensions_to_negotiate_) { + if (ext.uri == RtpExtension::kVideoLayersAllocationUri || + ext.uri == RtpExtension::kDependencyDescriptorUri) { + ext.direction = RtpTransceiverDirection::kSendRecv; + } + } + } + } } RtpTransceiver::~RtpTransceiver() { diff --git a/third_party/libwebrtc/pc/rtp_transceiver_unittest.cc b/third_party/libwebrtc/pc/rtp_transceiver_unittest.cc index d75e964509..b6dc7b2bb9 100644 --- a/third_party/libwebrtc/pc/rtp_transceiver_unittest.cc +++ b/third_party/libwebrtc/pc/rtp_transceiver_unittest.cc @@ -481,6 +481,81 @@ TEST_F(RtpTransceiverTestForHeaderExtensions, RtpTransceiverDirection::kStopped))); } +TEST_F(RtpTransceiverTestForHeaderExtensions, + SimulcastOrSvcEnablesExtensionsByDefault) { + std::vector<RtpHeaderExtensionCapability> extensions = { + {RtpExtension::kDependencyDescriptorUri, 1, + RtpTransceiverDirection::kStopped}, + {RtpExtension::kVideoLayersAllocationUri, 2, + RtpTransceiverDirection::kStopped}, + }; + + // Default is stopped. + auto sender = rtc::make_ref_counted<MockRtpSenderInternal>(); + auto transceiver = rtc::make_ref_counted<RtpTransceiver>( + RtpSenderProxyWithInternal<RtpSenderInternal>::Create( + rtc::Thread::Current(), sender), + RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create( + rtc::Thread::Current(), rtc::Thread::Current(), receiver_), + context(), extensions, + /* on_negotiation_needed= */ [] {}); + std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions = + transceiver->GetHeaderExtensionsToNegotiate(); + ASSERT_EQ(header_extensions.size(), 2u); + EXPECT_EQ(header_extensions[0].uri, RtpExtension::kDependencyDescriptorUri); + EXPECT_EQ(header_extensions[0].direction, RtpTransceiverDirection::kStopped); + EXPECT_EQ(header_extensions[1].uri, RtpExtension::kVideoLayersAllocationUri); + EXPECT_EQ(header_extensions[1].direction, RtpTransceiverDirection::kStopped); + + // Simulcast, i.e. more than one encoding. + RtpParameters simulcast_parameters; + simulcast_parameters.encodings.resize(2); + auto simulcast_sender = rtc::make_ref_counted<MockRtpSenderInternal>(); + EXPECT_CALL(*simulcast_sender, GetParametersInternal()) + .WillRepeatedly(Return(simulcast_parameters)); + auto simulcast_transceiver = rtc::make_ref_counted<RtpTransceiver>( + RtpSenderProxyWithInternal<RtpSenderInternal>::Create( + rtc::Thread::Current(), simulcast_sender), + RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create( + rtc::Thread::Current(), rtc::Thread::Current(), receiver_), + context(), extensions, + /* on_negotiation_needed= */ [] {}); + auto simulcast_extensions = + simulcast_transceiver->GetHeaderExtensionsToNegotiate(); + ASSERT_EQ(simulcast_extensions.size(), 2u); + EXPECT_EQ(simulcast_extensions[0].uri, + RtpExtension::kDependencyDescriptorUri); + EXPECT_EQ(simulcast_extensions[0].direction, + RtpTransceiverDirection::kSendRecv); + EXPECT_EQ(simulcast_extensions[1].uri, + RtpExtension::kVideoLayersAllocationUri); + EXPECT_EQ(simulcast_extensions[1].direction, + RtpTransceiverDirection::kSendRecv); + + // SVC, a single encoding with a scalabilityMode other than L1T1. + webrtc::RtpParameters svc_parameters; + svc_parameters.encodings.resize(1); + svc_parameters.encodings[0].scalability_mode = "L3T3"; + + auto svc_sender = rtc::make_ref_counted<MockRtpSenderInternal>(); + EXPECT_CALL(*svc_sender, GetParametersInternal()) + .WillRepeatedly(Return(svc_parameters)); + auto svc_transceiver = rtc::make_ref_counted<RtpTransceiver>( + RtpSenderProxyWithInternal<RtpSenderInternal>::Create( + rtc::Thread::Current(), svc_sender), + RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create( + rtc::Thread::Current(), rtc::Thread::Current(), receiver_), + context(), extensions, + /* on_negotiation_needed= */ [] {}); + std::vector<webrtc::RtpHeaderExtensionCapability> svc_extensions = + svc_transceiver->GetHeaderExtensionsToNegotiate(); + ASSERT_EQ(svc_extensions.size(), 2u); + EXPECT_EQ(svc_extensions[0].uri, RtpExtension::kDependencyDescriptorUri); + EXPECT_EQ(svc_extensions[0].direction, RtpTransceiverDirection::kSendRecv); + EXPECT_EQ(svc_extensions[1].uri, RtpExtension::kVideoLayersAllocationUri); + EXPECT_EQ(svc_extensions[1].direction, RtpTransceiverDirection::kSendRecv); +} + } // namespace } // namespace webrtc diff --git a/third_party/libwebrtc/pc/sdp_offer_answer.cc b/third_party/libwebrtc/pc/sdp_offer_answer.cc index 67c8d10241..95d54978c7 100644 --- a/third_party/libwebrtc/pc/sdp_offer_answer.cc +++ b/third_party/libwebrtc/pc/sdp_offer_answer.cc @@ -99,7 +99,7 @@ const char kSdpWithoutIceUfragPwd[] = "Called with SDP without ice-ufrag and ice-pwd."; const char kSdpWithoutDtlsFingerprint[] = "Called with SDP without DTLS fingerprint."; -const char kSdpWithoutSdesCrypto[] = "Called with SDP without SDES crypto."; +const char kSdpWithoutCrypto[] = "Called with SDP without crypto setup."; const char kSessionError[] = "Session error code: "; const char kSessionErrorDesc[] = "Session error description: "; @@ -271,7 +271,7 @@ bool MediaSectionsHaveSameCount(const SessionDescription& desc1, const SessionDescription& desc2) { return desc1.contents().size() == desc2.contents().size(); } -// Checks that each non-rejected content has SDES crypto keys or a DTLS +// Checks that each non-rejected content has a DTLS // fingerprint, unless it's in a BUNDLE group, in which case only the // BUNDLE-tag section (first media section/description in the BUNDLE group) // needs a ufrag and pwd. Mismatches, such as replying with a DTLS fingerprint @@ -285,9 +285,6 @@ RTCError VerifyCrypto(const SessionDescription* desc, if (content_info.rejected) { continue; } -#if !defined(WEBRTC_FUCHSIA) - RTC_CHECK(dtls_enabled) << "SDES protocol is only allowed in Fuchsia"; -#endif const std::string& mid = content_info.name; auto it = bundle_groups_by_mid.find(mid); const cricket::ContentGroup* bundle = @@ -313,10 +310,7 @@ RTCError VerifyCrypto(const SessionDescription* desc, kSdpWithoutDtlsFingerprint); } } else { - if (media->cryptos().empty()) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - kSdpWithoutSdesCrypto); - } + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, kSdpWithoutCrypto); } } return RTCError::OK(); @@ -1396,7 +1390,9 @@ void SdpOfferAnswerHandler::Initialize( pc_->trials()); if (pc_->options()->disable_encryption) { - webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); + RTC_LOG(LS_INFO) + << "Disabling encryption. This should only be done in tests."; + webrtc_session_desc_factory_->SetInsecureForTesting(); } webrtc_session_desc_factory_->set_enable_encrypted_rtp_header_extensions( @@ -3554,8 +3550,7 @@ RTCError SdpOfferAnswerHandler::ValidateSessionDescription( // Verify crypto settings. std::string crypto_error; - if (webrtc_session_desc_factory_->SdesPolicy() == cricket::SEC_REQUIRED || - pc_->dtls_enabled()) { + if (pc_->dtls_enabled()) { RTCError crypto_error = VerifyCrypto( sdesc->description(), pc_->dtls_enabled(), bundle_groups_by_mid); if (!crypto_error.ok()) { @@ -4302,11 +4297,13 @@ void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanOffer( GetMediaDescriptionOptionsForRejectedData(mid)); } else { const auto data_mid = pc_->sctp_mid(); - RTC_CHECK(data_mid); - if (mid == data_mid.value()) { + if (data_mid.has_value() && mid == data_mid.value()) { session_options->media_description_options.push_back( GetMediaDescriptionOptionsForActiveData(mid)); } else { + if (!data_mid.has_value()) { + RTC_LOG(LS_ERROR) << "Datachannel transport not available: " << mid; + } session_options->media_description_options.push_back( GetMediaDescriptionOptionsForRejectedData(mid)); } diff --git a/third_party/libwebrtc/pc/session_description.h b/third_party/libwebrtc/pc/session_description.h index 6ef9c316e1..fe037a5786 100644 --- a/third_party/libwebrtc/pc/session_description.h +++ b/third_party/libwebrtc/pc/session_description.h @@ -23,7 +23,6 @@ #include "absl/memory/memory.h" #include "absl/strings/string_view.h" -#include "api/crypto_params.h" #include "api/media_types.h" #include "api/rtp_parameters.h" #include "api/rtp_transceiver_direction.h" @@ -43,7 +42,6 @@ namespace cricket { -using CryptoParamsVec = std::vector<CryptoParams>; using RtpHeaderExtensions = std::vector<webrtc::RtpExtension>; // Options to control how session descriptions are generated. @@ -123,12 +121,6 @@ class MediaContentDescription { bandwidth_type_ = bandwidth_type; } - const std::vector<CryptoParams>& cryptos() const { return cryptos_; } - void AddCrypto(const CryptoParams& params) { cryptos_.push_back(params); } - void set_cryptos(const std::vector<CryptoParams>& cryptos) { - cryptos_ = cryptos; - } - // List of RTP header extensions. URIs are **NOT** guaranteed to be unique // as they can appear twice when both encrypted and non-encrypted extensions // are present. @@ -268,7 +260,6 @@ class MediaContentDescription { int bandwidth_ = kAutoBandwidth; std::string bandwidth_type_ = kApplicationSpecificBandwidth; - std::vector<CryptoParams> cryptos_; std::vector<webrtc::RtpExtension> rtp_header_extensions_; bool rtp_header_extensions_set_ = false; StreamParamsVec send_streams_; diff --git a/third_party/libwebrtc/pc/srtp_filter.cc b/third_party/libwebrtc/pc/srtp_filter.cc deleted file mode 100644 index b8be63cd22..0000000000 --- a/third_party/libwebrtc/pc/srtp_filter.cc +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2009 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "pc/srtp_filter.h" - -#include <string.h> - -#include <string> - -#include "absl/strings/match.h" -#include "rtc_base/logging.h" -#include "rtc_base/ssl_stream_adapter.h" -#include "rtc_base/third_party/base64/base64.h" -#include "rtc_base/zero_memory.h" - -namespace cricket { - -SrtpFilter::SrtpFilter() {} - -SrtpFilter::~SrtpFilter() {} - -bool SrtpFilter::IsActive() const { - return state_ >= ST_ACTIVE; -} - -bool SrtpFilter::Process(const std::vector<CryptoParams>& cryptos, - webrtc::SdpType type, - ContentSource source) { - bool ret = false; - switch (type) { - case webrtc::SdpType::kOffer: - ret = SetOffer(cryptos, source); - break; - case webrtc::SdpType::kPrAnswer: - ret = SetProvisionalAnswer(cryptos, source); - break; - case webrtc::SdpType::kAnswer: - ret = SetAnswer(cryptos, source); - break; - default: - break; - } - - if (!ret) { - return false; - } - - return true; -} - -bool SrtpFilter::SetOffer(const std::vector<CryptoParams>& offer_params, - ContentSource source) { - if (!ExpectOffer(source)) { - RTC_LOG(LS_ERROR) << "Wrong state to update SRTP offer"; - return false; - } - return StoreParams(offer_params, source); -} - -bool SrtpFilter::SetAnswer(const std::vector<CryptoParams>& answer_params, - ContentSource source) { - return DoSetAnswer(answer_params, source, true); -} - -bool SrtpFilter::SetProvisionalAnswer( - const std::vector<CryptoParams>& answer_params, - ContentSource source) { - return DoSetAnswer(answer_params, source, false); -} - -bool SrtpFilter::ExpectOffer(ContentSource source) { - return ((state_ == ST_INIT) || (state_ == ST_ACTIVE) || - (state_ == ST_SENTOFFER && source == CS_LOCAL) || - (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || - (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || - (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); -} - -bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, - ContentSource source) { - offer_params_ = params; - if (state_ == ST_INIT) { - state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER; - } else if (state_ == ST_ACTIVE) { - state_ = - (source == CS_LOCAL) ? ST_SENTUPDATEDOFFER : ST_RECEIVEDUPDATEDOFFER; - } - return true; -} - -bool SrtpFilter::ExpectAnswer(ContentSource source) { - return ((state_ == ST_SENTOFFER && source == CS_REMOTE) || - (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) || - (state_ == ST_SENTUPDATEDOFFER && source == CS_REMOTE) || - (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_LOCAL) || - (state_ == ST_SENTPRANSWER_NO_CRYPTO && source == CS_LOCAL) || - (state_ == ST_SENTPRANSWER && source == CS_LOCAL) || - (state_ == ST_RECEIVEDPRANSWER_NO_CRYPTO && source == CS_REMOTE) || - (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE)); -} - -bool SrtpFilter::DoSetAnswer(const std::vector<CryptoParams>& answer_params, - ContentSource source, - bool final) { - if (!ExpectAnswer(source)) { - RTC_LOG(LS_ERROR) << "Invalid state for SRTP answer"; - return false; - } - - // If the answer doesn't requests crypto complete the negotiation of an - // unencrypted session. - // Otherwise, finalize the parameters and apply them. - if (answer_params.empty()) { - if (final) { - return ResetParams(); - } else { - // Need to wait for the final answer to decide if - // we should go to Active state. - state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO - : ST_RECEIVEDPRANSWER_NO_CRYPTO; - return true; - } - } - CryptoParams selected_params; - if (!NegotiateParams(answer_params, &selected_params)) - return false; - - const CryptoParams& new_send_params = - (source == CS_REMOTE) ? selected_params : answer_params[0]; - const CryptoParams& new_recv_params = - (source == CS_REMOTE) ? answer_params[0] : selected_params; - if (!ApplySendParams(new_send_params) || !ApplyRecvParams(new_recv_params)) { - return false; - } - applied_send_params_ = new_send_params; - applied_recv_params_ = new_recv_params; - - if (final) { - offer_params_.clear(); - state_ = ST_ACTIVE; - } else { - state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; - } - return true; -} - -bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, - CryptoParams* selected_params) { - // We're processing an accept. We should have exactly one set of params, - // unless the offer didn't mention crypto, in which case we shouldn't be here. - bool ret = (answer_params.size() == 1U && !offer_params_.empty()); - if (ret) { - // We should find a match between the answer params and the offered params. - std::vector<CryptoParams>::const_iterator it; - for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { - if (answer_params[0].Matches(*it)) { - break; - } - } - - if (it != offer_params_.end()) { - *selected_params = *it; - } else { - ret = false; - } - } - - if (!ret) { - RTC_LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; - } - return ret; -} - -bool SrtpFilter::ResetParams() { - offer_params_.clear(); - applied_send_params_ = CryptoParams(); - applied_recv_params_ = CryptoParams(); - send_crypto_suite_ = absl::nullopt; - recv_crypto_suite_ = absl::nullopt; - send_key_.Clear(); - recv_key_.Clear(); - state_ = ST_INIT; - return true; -} - -bool SrtpFilter::ApplySendParams(const CryptoParams& send_params) { - if (applied_send_params_.crypto_suite == send_params.crypto_suite && - applied_send_params_.key_params == send_params.key_params) { - RTC_LOG(LS_INFO) << "Applying the same SRTP send parameters again. No-op."; - - // We do not want to reset the ROC if the keys are the same. So just return. - return true; - } - - send_crypto_suite_ = rtc::SrtpCryptoSuiteFromName(send_params.crypto_suite); - if (send_crypto_suite_ == rtc::kSrtpInvalidCryptoSuite) { - RTC_LOG(LS_WARNING) << "Unknown crypto suite(s) received:" - " send crypto_suite " - << send_params.crypto_suite; - return false; - } - - int send_key_len, send_salt_len; - if (!rtc::GetSrtpKeyAndSaltLengths(*send_crypto_suite_, &send_key_len, - &send_salt_len)) { - RTC_LOG(LS_ERROR) << "Could not get lengths for crypto suite(s):" - " send crypto_suite " - << send_params.crypto_suite; - return false; - } - - send_key_ = rtc::ZeroOnFreeBuffer<uint8_t>(send_key_len + send_salt_len); - return ParseKeyParams(send_params.key_params, send_key_.data(), - send_key_.size()); -} - -bool SrtpFilter::ApplyRecvParams(const CryptoParams& recv_params) { - if (applied_recv_params_.crypto_suite == recv_params.crypto_suite && - applied_recv_params_.key_params == recv_params.key_params) { - RTC_LOG(LS_INFO) << "Applying the same SRTP recv parameters again. No-op."; - - // We do not want to reset the ROC if the keys are the same. So just return. - return true; - } - - recv_crypto_suite_ = rtc::SrtpCryptoSuiteFromName(recv_params.crypto_suite); - if (recv_crypto_suite_ == rtc::kSrtpInvalidCryptoSuite) { - RTC_LOG(LS_WARNING) << "Unknown crypto suite(s) received:" - " recv crypto_suite " - << recv_params.crypto_suite; - return false; - } - - int recv_key_len, recv_salt_len; - if (!rtc::GetSrtpKeyAndSaltLengths(*recv_crypto_suite_, &recv_key_len, - &recv_salt_len)) { - RTC_LOG(LS_ERROR) << "Could not get lengths for crypto suite(s):" - " recv crypto_suite " - << recv_params.crypto_suite; - return false; - } - - recv_key_ = rtc::ZeroOnFreeBuffer<uint8_t>(recv_key_len + recv_salt_len); - return ParseKeyParams(recv_params.key_params, recv_key_.data(), - recv_key_.size()); -} - -bool SrtpFilter::ParseKeyParams(const std::string& key_params, - uint8_t* key, - size_t len) { - // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" - - // Fail if key-method is wrong. - if (!absl::StartsWith(key_params, "inline:")) { - return false; - } - - // Fail if base64 decode fails, or the key is the wrong size. - std::string key_b64(key_params.substr(7)), key_str; - if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, &key_str, - nullptr) || - key_str.size() != len) { - return false; - } - - memcpy(key, key_str.c_str(), len); - // TODO(bugs.webrtc.org/8905): Switch to ZeroOnFreeBuffer for storing - // sensitive data. - rtc::ExplicitZeroMemory(&key_str[0], key_str.size()); - return true; -} - -} // namespace cricket diff --git a/third_party/libwebrtc/pc/srtp_filter.h b/third_party/libwebrtc/pc/srtp_filter.h deleted file mode 100644 index 59c43f624b..0000000000 --- a/third_party/libwebrtc/pc/srtp_filter.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2009 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef PC_SRTP_FILTER_H_ -#define PC_SRTP_FILTER_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <list> -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "absl/types/optional.h" -#include "api/array_view.h" -#include "api/crypto_params.h" -#include "api/jsep.h" -#include "api/sequence_checker.h" -#include "pc/session_description.h" -#include "rtc_base/buffer.h" -#include "rtc_base/ssl_stream_adapter.h" - -// Forward declaration to avoid pulling in libsrtp headers here -struct srtp_event_data_t; -struct srtp_ctx_t_; - -namespace cricket { - -// A helper class used to negotiate SDES crypto params. -// TODO(zhihuang): Find a better name for this class, like "SdesNegotiator". -class SrtpFilter { - public: - enum Mode { PROTECT, UNPROTECT }; - enum Error { - ERROR_NONE, - ERROR_FAIL, - ERROR_AUTH, - ERROR_REPLAY, - }; - - SrtpFilter(); - ~SrtpFilter(); - - // Whether the filter is active (i.e. crypto has been properly negotiated). - bool IsActive() const; - - // Handle the offer/answer negotiation of the crypto parameters internally. - // TODO(zhihuang): Make SetOffer/ProvisionalAnswer/Answer private as helper - // methods once start using Process. - bool Process(const std::vector<CryptoParams>& cryptos, - webrtc::SdpType type, - ContentSource source); - - // Indicates which crypto algorithms and keys were contained in the offer. - // offer_params should contain a list of available parameters to use, or none, - // if crypto is not desired. This must be called before SetAnswer. - bool SetOffer(const std::vector<CryptoParams>& offer_params, - ContentSource source); - // Same as SetAnwer. But multiple calls are allowed to SetProvisionalAnswer - // after a call to SetOffer. - bool SetProvisionalAnswer(const std::vector<CryptoParams>& answer_params, - ContentSource source); - // Indicates which crypto algorithms and keys were contained in the answer. - // answer_params should contain the negotiated parameters, which may be none, - // if crypto was not desired or could not be negotiated (and not required). - // This must be called after SetOffer. If crypto negotiation completes - // successfully, this will advance the filter to the active state. - bool SetAnswer(const std::vector<CryptoParams>& answer_params, - ContentSource source); - - bool ResetParams(); - - static bool ParseKeyParams(const std::string& params, - uint8_t* key, - size_t len); - - absl::optional<int> send_crypto_suite() { return send_crypto_suite_; } - absl::optional<int> recv_crypto_suite() { return recv_crypto_suite_; } - - rtc::ArrayView<const uint8_t> send_key() { return send_key_; } - rtc::ArrayView<const uint8_t> recv_key() { return recv_key_; } - - protected: - bool ExpectOffer(ContentSource source); - - bool StoreParams(const std::vector<CryptoParams>& params, - ContentSource source); - - bool ExpectAnswer(ContentSource source); - - bool DoSetAnswer(const std::vector<CryptoParams>& answer_params, - ContentSource source, - bool final); - - bool NegotiateParams(const std::vector<CryptoParams>& answer_params, - CryptoParams* selected_params); - - private: - bool ApplySendParams(const CryptoParams& send_params); - - bool ApplyRecvParams(const CryptoParams& recv_params); - - enum State { - ST_INIT, // SRTP filter unused. - ST_SENTOFFER, // Offer with SRTP parameters sent. - ST_RECEIVEDOFFER, // Offer with SRTP parameters received. - ST_SENTPRANSWER_NO_CRYPTO, // Sent provisional answer without crypto. - // Received provisional answer without crypto. - ST_RECEIVEDPRANSWER_NO_CRYPTO, - ST_ACTIVE, // Offer and answer set. - // SRTP filter is active but new parameters are offered. - // When the answer is set, the state transitions to ST_ACTIVE or ST_INIT. - ST_SENTUPDATEDOFFER, - // SRTP filter is active but new parameters are received. - // When the answer is set, the state transitions back to ST_ACTIVE. - ST_RECEIVEDUPDATEDOFFER, - // SRTP filter is active but the sent answer is only provisional. - // When the final answer is set, the state transitions to ST_ACTIVE or - // ST_INIT. - ST_SENTPRANSWER, - // SRTP filter is active but the received answer is only provisional. - // When the final answer is set, the state transitions to ST_ACTIVE or - // ST_INIT. - ST_RECEIVEDPRANSWER - }; - State state_ = ST_INIT; - std::vector<CryptoParams> offer_params_; - CryptoParams applied_send_params_; - CryptoParams applied_recv_params_; - absl::optional<int> send_crypto_suite_; - absl::optional<int> recv_crypto_suite_; - rtc::ZeroOnFreeBuffer<uint8_t> send_key_; - rtc::ZeroOnFreeBuffer<uint8_t> recv_key_; -}; - -} // namespace cricket - -#endif // PC_SRTP_FILTER_H_ diff --git a/third_party/libwebrtc/pc/srtp_filter_unittest.cc b/third_party/libwebrtc/pc/srtp_filter_unittest.cc deleted file mode 100644 index fed023199f..0000000000 --- a/third_party/libwebrtc/pc/srtp_filter_unittest.cc +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright 2004 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "pc/srtp_filter.h" - -#include <string.h> - -#include "api/crypto_params.h" -#include "rtc_base/ssl_stream_adapter.h" -#include "test/gtest.h" - -using cricket::CryptoParams; -using cricket::CS_LOCAL; -using cricket::CS_REMOTE; - -namespace rtc { - -static const char kTestKeyParams1[] = - "inline:WVNfX19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz"; -static const char kTestKeyParams2[] = - "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR"; -static const char kTestKeyParams3[] = - "inline:1234X19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz"; -static const char kTestKeyParams4[] = - "inline:4567QCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR"; -static const char kTestKeyParamsGcm1[] = - "inline:e166KFlKzJsGW0d5apX+rrI05vxbrvMJEzFI14aTDCa63IRTlLK4iH66uOI="; -static const char kTestKeyParamsGcm2[] = - "inline:6X0oCd55zfz4VgtOwsuqcFq61275PDYN5uwuu3p7ZUHbfUY2FMpdP4m2PEo="; -static const char kTestKeyParamsGcm3[] = - "inline:YKlABGZWMgX32xuMotrG0v0T7G83veegaVzubQ=="; -static const char kTestKeyParamsGcm4[] = - "inline:gJ6tWoUym2v+/F6xjr7xaxiS3QbJJozl3ZD/0A=="; -static const cricket::CryptoParams kTestCryptoParams1(1, - "AES_CM_128_HMAC_SHA1_80", - kTestKeyParams1, - ""); -static const cricket::CryptoParams kTestCryptoParams2(1, - "AES_CM_128_HMAC_SHA1_80", - kTestKeyParams2, - ""); -static const cricket::CryptoParams kTestCryptoParamsGcm1(1, - "AEAD_AES_256_GCM", - kTestKeyParamsGcm1, - ""); -static const cricket::CryptoParams kTestCryptoParamsGcm2(1, - "AEAD_AES_256_GCM", - kTestKeyParamsGcm2, - ""); -static const cricket::CryptoParams kTestCryptoParamsGcm3(1, - "AEAD_AES_128_GCM", - kTestKeyParamsGcm3, - ""); -static const cricket::CryptoParams kTestCryptoParamsGcm4(1, - "AEAD_AES_128_GCM", - kTestKeyParamsGcm4, - ""); - -class SrtpFilterTest : public ::testing::Test { - protected: - SrtpFilterTest() {} - static std::vector<CryptoParams> MakeVector(const CryptoParams& params) { - std::vector<CryptoParams> vec; - vec.push_back(params); - return vec; - } - - void TestSetParams(const std::vector<CryptoParams>& params1, - const std::vector<CryptoParams>& params2) { - EXPECT_TRUE(f1_.SetOffer(params1, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(params1, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetAnswer(params2, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(params2, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - } - - void VerifyKeysAreEqual(ArrayView<const uint8_t> key1, - ArrayView<const uint8_t> key2) { - EXPECT_EQ(key1.size(), key2.size()); - EXPECT_EQ(0, memcmp(key1.data(), key2.data(), key1.size())); - } - - void VerifyCryptoParamsMatch(const std::string& cs1, const std::string& cs2) { - EXPECT_EQ(rtc::SrtpCryptoSuiteFromName(cs1), f1_.send_crypto_suite()); - EXPECT_EQ(rtc::SrtpCryptoSuiteFromName(cs2), f2_.send_crypto_suite()); - VerifyKeysAreEqual(f1_.send_key(), f2_.recv_key()); - VerifyKeysAreEqual(f2_.send_key(), f1_.recv_key()); - } - - cricket::SrtpFilter f1_; - cricket::SrtpFilter f2_; -}; - -// Test that we can set up the session and keys properly. -TEST_F(SrtpFilterTest, TestGoodSetupOneCryptoSuite) { - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); -} - -TEST_F(SrtpFilterTest, TestGoodSetupOneCryptoSuiteGcm) { - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParamsGcm1), CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParamsGcm2), CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); -} - -// Test that we can set up things with multiple params. -TEST_F(SrtpFilterTest, TestGoodSetupMultipleCryptoSuites) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - offer.push_back(kTestCryptoParams1); - offer[1].tag = 2; - offer[1].crypto_suite = kCsAesCm128HmacSha1_32; - answer[0].tag = 2; - answer[0].crypto_suite = kCsAesCm128HmacSha1_32; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); -} - -TEST_F(SrtpFilterTest, TestGoodSetupMultipleCryptoSuitesGcm) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParamsGcm1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParamsGcm3)); - offer.push_back(kTestCryptoParamsGcm4); - offer[1].tag = 2; - answer[0].tag = 2; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); -} - -// Test that we handle the cases where crypto is not desired. -TEST_F(SrtpFilterTest, TestGoodSetupNoCryptoSuites) { - std::vector<CryptoParams> offer, answer; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we handle the cases where crypto is not desired by the remote side. -TEST_F(SrtpFilterTest, TestGoodSetupNoAnswerCryptoSuites) { - std::vector<CryptoParams> answer; - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we call the functions the wrong way. -TEST_F(SrtpFilterTest, TestBadSetup) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we can set offer multiple times from the same source. -TEST_F(SrtpFilterTest, TestGoodSetupMultipleOffers) { - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams1), CS_REMOTE)); - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetAnswer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_TRUE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams1), CS_REMOTE)); - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_TRUE(f2_.SetAnswer(MakeVector(kTestCryptoParams2), CS_LOCAL)); -} -// Test that we can't set offer multiple times from different sources. -TEST_F(SrtpFilterTest, TestBadSetupMultipleOffers) { - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_FALSE(f1_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams1), CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_FALSE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_REMOTE)); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f2_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetAnswer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_TRUE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f2_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_TRUE(f2_.SetAnswer(MakeVector(kTestCryptoParams2), CS_LOCAL)); -} - -// Test that we fail if we have params in the answer when none were offered. -TEST_F(SrtpFilterTest, TestNoAnswerCryptoSuites) { - std::vector<CryptoParams> offer; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we have too many params in our answer. -TEST_F(SrtpFilterTest, TestMultipleAnswerCryptoSuites) { - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - answer.push_back(kTestCryptoParams2); - answer[1].tag = 2; - answer[1].crypto_suite = kCsAesCm128HmacSha1_32; - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we don't support the crypto suite. -TEST_F(SrtpFilterTest, TestInvalidCryptoSuite) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - offer[0].crypto_suite = answer[0].crypto_suite = "FOO"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we can't agree on a tag. -TEST_F(SrtpFilterTest, TestNoMatchingTag) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - answer[0].tag = 99; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we can't agree on a crypto suite. -TEST_F(SrtpFilterTest, TestNoMatchingCryptoSuite) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - answer[0].tag = 2; - answer[0].crypto_suite = "FOO"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys with bad base64 content. -TEST_F(SrtpFilterTest, TestInvalidKeyData) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = "inline:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys with the wrong key-method. -TEST_F(SrtpFilterTest, TestWrongKeyMethod) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = "outline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys of the wrong length. -TEST_F(SrtpFilterTest, TestKeyTooShort) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtx"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys of the wrong length. -TEST_F(SrtpFilterTest, TestKeyTooLong) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBRABCD"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys with lifetime or MKI set (since we don't support) -TEST_F(SrtpFilterTest, TestUnsupportedOptions) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = - "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:4"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we can encrypt/decrypt after negotiating AES_CM_128_HMAC_SHA1_80. -TEST_F(SrtpFilterTest, TestProtect_AES_CM_128_HMAC_SHA1_80) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - offer.push_back(kTestCryptoParams1); - offer[1].tag = 2; - offer[1].crypto_suite = kCsAesCm128HmacSha1_32; - TestSetParams(offer, answer); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); -} - -// Test that we can encrypt/decrypt after negotiating AES_CM_128_HMAC_SHA1_32. -TEST_F(SrtpFilterTest, TestProtect_AES_CM_128_HMAC_SHA1_32) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - offer.push_back(kTestCryptoParams1); - offer[1].tag = 2; - offer[1].crypto_suite = kCsAesCm128HmacSha1_32; - answer[0].tag = 2; - answer[0].crypto_suite = kCsAesCm128HmacSha1_32; - TestSetParams(offer, answer); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_32, kCsAesCm128HmacSha1_32); -} - -// Test that we can change encryption parameters. -TEST_F(SrtpFilterTest, TestChangeParameters) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - - TestSetParams(offer, answer); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - // Change the key parameters and crypto_suite. - offer[0].key_params = kTestKeyParams3; - offer[0].crypto_suite = kCsAesCm128HmacSha1_32; - answer[0].key_params = kTestKeyParams4; - answer[0].crypto_suite = kCsAesCm128HmacSha1_32; - - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f1_.IsActive()); - - // Test that the old keys are valid until the negotiation is complete. - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - // Complete the negotiation and test that we can still understand each other. - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_32, kCsAesCm128HmacSha1_32); -} - -// Test that we can send and receive provisional answers with crypto enabled. -// Also test that we can change the crypto. -TEST_F(SrtpFilterTest, TestProvisionalAnswer) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - offer.push_back(kTestCryptoParams1); - offer[1].tag = 2; - offer[1].crypto_suite = kCsAesCm128HmacSha1_32; - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetProvisionalAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetProvisionalAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - answer[0].key_params = kTestKeyParams4; - answer[0].tag = 2; - answer[0].crypto_suite = kCsAesCm128HmacSha1_32; - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_32, kCsAesCm128HmacSha1_32); -} - -// Test that a provisional answer doesn't need to contain a crypto. -TEST_F(SrtpFilterTest, TestProvisionalAnswerWithoutCrypto) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer; - - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetProvisionalAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetProvisionalAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - - answer.push_back(kTestCryptoParams2); - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); -} - -// Test that if we get a new local offer after a provisional answer -// with no crypto, that we are in an inactive state. -TEST_F(SrtpFilterTest, TestLocalOfferAfterProvisionalAnswerWithoutCrypto) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer; - - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_TRUE(f1_.SetProvisionalAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f2_.SetProvisionalAnswer(answer, CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - // The calls to set an offer after a provisional answer fail, so the - // state doesn't change. - EXPECT_FALSE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - - answer.push_back(kTestCryptoParams2); - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); -} - -// Test that we can disable encryption. -TEST_F(SrtpFilterTest, TestDisableEncryption) { - std::vector<CryptoParams> offer(MakeVector(kTestCryptoParams1)); - std::vector<CryptoParams> answer(MakeVector(kTestCryptoParams2)); - - TestSetParams(offer, answer); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - offer.clear(); - answer.clear(); - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - - // Test that the old keys are valid until the negotiation is complete. - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - // Complete the negotiation. - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); -} - -} // namespace rtc diff --git a/third_party/libwebrtc/pc/srtp_transport.h b/third_party/libwebrtc/pc/srtp_transport.h index 29721f3b68..bad4adc135 100644 --- a/third_party/libwebrtc/pc/srtp_transport.h +++ b/third_party/libwebrtc/pc/srtp_transport.h @@ -19,7 +19,6 @@ #include <vector> #include "absl/types/optional.h" -#include "api/crypto_params.h" #include "api/field_trials_view.h" #include "api/rtc_error.h" #include "p2p/base/packet_transport_internal.h" @@ -154,8 +153,6 @@ class SrtpTransport : public RtpTransport { std::unique_ptr<cricket::SrtpSession> send_rtcp_session_; std::unique_ptr<cricket::SrtpSession> recv_rtcp_session_; - absl::optional<cricket::CryptoParams> send_params_; - absl::optional<cricket::CryptoParams> recv_params_; absl::optional<int> send_crypto_suite_; absl::optional<int> recv_crypto_suite_; rtc::ZeroOnFreeBuffer<uint8_t> send_key_; diff --git a/third_party/libwebrtc/pc/test/fake_peer_connection_base.h b/third_party/libwebrtc/pc/test/fake_peer_connection_base.h index 1615088e99..9e4ed6d175 100644 --- a/third_party/libwebrtc/pc/test/fake_peer_connection_base.h +++ b/third_party/libwebrtc/pc/test/fake_peer_connection_base.h @@ -197,6 +197,9 @@ class FakePeerConnectionBase : public PeerConnectionInternal { return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented"); } + void ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) override {} + void SetAudioPlayout(bool playout) override {} void SetAudioRecording(bool recording) override {} diff --git a/third_party/libwebrtc/pc/test/mock_peer_connection_internal.h b/third_party/libwebrtc/pc/test/mock_peer_connection_internal.h index 5fd7a50b4f..b5f47cc46a 100644 --- a/third_party/libwebrtc/pc/test/mock_peer_connection_internal.h +++ b/third_party/libwebrtc/pc/test/mock_peer_connection_internal.h @@ -170,6 +170,10 @@ class MockPeerConnectionInternal : public PeerConnectionInternal { (const std::vector<cricket::Candidate>&), (override)); MOCK_METHOD(RTCError, SetBitrate, (const BitrateSettings&), (override)); + MOCK_METHOD(void, + ReconfigureBandwidthEstimation, + (const BandwidthEstimationSettings&), + (override)); MOCK_METHOD(void, SetAudioPlayout, (bool), (override)); MOCK_METHOD(void, SetAudioRecording, (bool), (override)); MOCK_METHOD(rtc::scoped_refptr<DtlsTransportInterface>, diff --git a/third_party/libwebrtc/pc/test/svc_e2e_tests.cc b/third_party/libwebrtc/pc/test/svc_e2e_tests.cc index b2382d700f..678c36b586 100644 --- a/third_party/libwebrtc/pc/test/svc_e2e_tests.cc +++ b/third_party/libwebrtc/pc/test/svc_e2e_tests.cc @@ -454,6 +454,7 @@ INSTANTIATE_TEST_SUITE_P( Values(UseDependencyDescriptor::Disabled, UseDependencyDescriptor::Enabled)), SvcTestNameGenerator); +#endif INSTANTIATE_TEST_SUITE_P( SvcTestAV1, @@ -503,6 +504,4 @@ INSTANTIATE_TEST_SUITE_P( Values(UseDependencyDescriptor::Enabled)), SvcTestNameGenerator); -#endif - } // namespace webrtc diff --git a/third_party/libwebrtc/pc/used_ids.h b/third_party/libwebrtc/pc/used_ids.h index 6b342cbea8..42ef00a7c0 100644 --- a/third_party/libwebrtc/pc/used_ids.h +++ b/third_party/libwebrtc/pc/used_ids.h @@ -147,15 +147,15 @@ class UsedRtpHeaderExtensionIds : public UsedIds<webrtc::RtpExtension> { private: // Returns the first unused id in reverse order from the max id of one byte - // header extensions. This hopefully reduce the risk of more collisions. We + // header extensions. This hopefully reduces the risk of more collisions. We // want to change the default ids as little as possible. If no unused id is // found and two byte header extensions are enabled (i.e., - // `extmap_allow_mixed_` is true), search for unused ids from 15 to 255. + // `extmap_allow_mixed_` is true), search for unused ids from 16 to 255. int FindUnusedId() override { if (next_extension_id_ <= webrtc::RtpExtension::kOneByteHeaderExtensionMaxId) { // First search in reverse order from the max id of one byte header - // extensions. + // extensions (14). while (IsIdUsed(next_extension_id_) && next_extension_id_ >= min_allowed_id_) { --next_extension_id_; @@ -165,9 +165,10 @@ class UsedRtpHeaderExtensionIds : public UsedIds<webrtc::RtpExtension> { if (id_domain_ == IdDomain::kTwoByteAllowed) { if (next_extension_id_ < min_allowed_id_) { // We have searched among all one-byte IDs without finding an unused ID, - // continue at the first two-byte ID. + // continue at the first two-byte ID (16; avoid 15 since it is somewhat + // special per https://www.rfc-editor.org/rfc/rfc8285#section-4.2 next_extension_id_ = - webrtc::RtpExtension::kOneByteHeaderExtensionMaxId + 1; + webrtc::RtpExtension::kOneByteHeaderExtensionMaxId + 2; } if (next_extension_id_ > diff --git a/third_party/libwebrtc/pc/used_ids_unittest.cc b/third_party/libwebrtc/pc/used_ids_unittest.cc index 6362f2773a..df3790b52c 100644 --- a/third_party/libwebrtc/pc/used_ids_unittest.cc +++ b/third_party/libwebrtc/pc/used_ids_unittest.cc @@ -119,7 +119,8 @@ TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) { UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed); // Fill all one byte IDs. - for (int i = 1; i < 15; ++i) { + for (int i = 1; i <= webrtc::RtpExtension::kOneByteHeaderExtensionMaxId; + ++i) { webrtc::RtpExtension id("", i); used_ids.FindAndSetIdUsed(&id); } @@ -131,11 +132,11 @@ TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) { // Expect to reassign to two-byte header extension IDs. used_ids.FindAndSetIdUsed(&id1_collision); - EXPECT_EQ(id1_collision.id, 15); + EXPECT_EQ(id1_collision.id, 16); used_ids.FindAndSetIdUsed(&id2_collision); - EXPECT_EQ(id2_collision.id, 16); + EXPECT_EQ(id2_collision.id, 17); used_ids.FindAndSetIdUsed(&id3_collision); - EXPECT_EQ(id3_collision.id, 17); + EXPECT_EQ(id3_collision.id, 18); } // Death tests. diff --git a/third_party/libwebrtc/pc/webrtc_sdp.cc b/third_party/libwebrtc/pc/webrtc_sdp.cc index 88f1ce0d1b..ea9c8580cd 100644 --- a/third_party/libwebrtc/pc/webrtc_sdp.cc +++ b/third_party/libwebrtc/pc/webrtc_sdp.cc @@ -29,7 +29,6 @@ #include "absl/strings/ascii.h" #include "absl/strings/match.h" #include "api/candidate.h" -#include "api/crypto_params.h" #include "api/jsep_ice_candidate.h" #include "api/jsep_session_description.h" #include "api/media_types.h" @@ -74,7 +73,6 @@ using cricket::AudioContentDescription; using cricket::Candidate; using cricket::Candidates; using cricket::ContentInfo; -using cricket::CryptoParams; using cricket::ICE_CANDIDATE_COMPONENT_RTCP; using cricket::ICE_CANDIDATE_COMPONENT_RTP; using cricket::kApplicationSpecificBandwidth; @@ -157,7 +155,6 @@ static const char kSsrcAttributeMsid[] = "msid"; static const char kDefaultMsid[] = "default"; static const char kNoStreamMsid[] = "-"; static const char kAttributeSsrcGroup[] = "ssrc-group"; -static const char kAttributeCrypto[] = "crypto"; static const char kAttributeCandidate[] = "candidate"; static const char kAttributeCandidateTyp[] = "typ"; static const char kAttributeCandidateRaddr[] = "raddr"; @@ -340,9 +337,6 @@ static bool ParseSsrcAttribute(absl::string_view line, static bool ParseSsrcGroupAttribute(absl::string_view line, SsrcGroupVec* ssrc_groups, SdpParseError* error); -static bool ParseCryptoAttribute(absl::string_view line, - MediaContentDescription* media_desc, - SdpParseError* error); static bool ParseRtpmapAttribute(absl::string_view line, const cricket::MediaType media_type, const std::vector<int>& payload_types, @@ -1126,7 +1120,7 @@ bool ParseCandidate(absl::string_view message, return ParseFailed(first_line, "Unsupported transport type.", error); } - std::string candidate_type; + absl::string_view candidate_type; const absl::string_view type = fields[7]; if (type == kCandidateHost) { candidate_type = cricket::LOCAL_PORT_TYPE; @@ -1668,18 +1662,6 @@ void BuildRtpContentAttributes(const MediaContentDescription* media_desc, AddLine(os.str(), message); } - // RFC 4568 - // a=crypto:<tag> <crypto-suite> <key-params> [<session-params>] - for (const CryptoParams& crypto_params : media_desc->cryptos()) { - InitAttrLine(kAttributeCrypto, &os); - os << kSdpDelimiterColon << crypto_params.tag << " " - << crypto_params.crypto_suite << " " << crypto_params.key_params; - if (!crypto_params.session_params.empty()) { - os << " " << crypto_params.session_params; - } - AddLine(os.str(), message); - } - // RFC 4566 // a=rtpmap:<payload type> <encoding name>/<clock rate> // [/<encodingparameters>] @@ -2359,6 +2341,7 @@ static bool ParseMsidAttribute(absl::string_view line, // Note that JSEP stipulates not sending msid-appdata so // a=msid:<stream id> <track id> // is supported for backward compability reasons only. + // RFC 8830 section 2 states that duplicate a=msid:stream track is illegal. std::vector<std::string> fields; size_t num_fields = rtc::tokenize(line.substr(kLinePrefixLength), kSdpDelimiterSpaceChar, &fields); @@ -2615,6 +2598,25 @@ static void BackfillCodecParameters(std::vector<cricket::Codec>& codecs) { if (!codec.GetParam(cricket::kH264FmtpPacketizationMode, &unused_value)) { codec.SetParam(cricket::kH264FmtpPacketizationMode, "0"); } + } else if (absl::EqualsIgnoreCase(cricket::kAv1CodecName, codec.name)) { + // https://aomediacodec.github.io/av1-rtp-spec/#72-sdp-parameters + if (!codec.GetParam(cricket::kAv1FmtpProfile, &unused_value)) { + codec.SetParam(cricket::kAv1FmtpProfile, "0"); + } + if (!codec.GetParam(cricket::kAv1FmtpLevelIdx, &unused_value)) { + codec.SetParam(cricket::kAv1FmtpLevelIdx, "5"); + } + if (!codec.GetParam(cricket::kAv1FmtpTier, &unused_value)) { + codec.SetParam(cricket::kAv1FmtpTier, "0"); + } + } else if (absl::EqualsIgnoreCase(cricket::kH265CodecName, codec.name)) { + // https://datatracker.ietf.org/doc/html/draft-aboba-avtcore-hevc-webrtc + if (!codec.GetParam(cricket::kH265FmtpLevelId, &unused_value)) { + codec.SetParam(cricket::kH265FmtpLevelId, "93"); + } + if (!codec.GetParam(cricket::kH265FmtpTxMode, &unused_value)) { + codec.SetParam(cricket::kH265FmtpTxMode, "SRST"); + } } } } @@ -2669,6 +2671,21 @@ static std::unique_ptr<MediaContentDescription> ParseContentDescription( return media_desc; } +bool HasDuplicateMsidLines(cricket::SessionDescription* desc) { + std::set<std::pair<std::string, std::string>> seen_msids; + for (const cricket::ContentInfo& content : desc->contents()) { + for (const cricket::StreamParams& stream : + content.media_description()->streams()) { + auto msid = std::pair(stream.first_stream_id(), stream.id); + if (seen_msids.find(msid) != seen_msids.end()) { + return true; + } + seen_msids.insert(std::move(msid)); + } + } + return false; +} + bool ParseMediaDescription( absl::string_view message, const TransportDescription& session_td, @@ -2851,6 +2868,11 @@ bool ParseMediaDescription( // Create TransportInfo with the media level "ice-pwd" and "ice-ufrag". desc->AddTransportInfo(TransportInfo(content_name, transport)); } + // Apply whole-description sanity checks + if (HasDuplicateMsidLines(desc)) { + ParseFailed(message, *pos, "Duplicate a=msid lines detected", error); + return false; + } desc->set_msid_signaling(msid_signaling); @@ -3206,10 +3228,6 @@ bool ParseContent(absl::string_view message, if (!ParseSsrcAttribute(*line, &ssrc_infos, msid_signaling, error)) { return false; } - } else if (HasAttribute(*line, kAttributeCrypto)) { - if (!ParseCryptoAttribute(*line, media_desc, error)) { - return false; - } } else if (HasAttribute(*line, kAttributeRtpmap)) { if (!ParseRtpmapAttribute(*line, media_type, payload_types, media_desc, error)) { @@ -3537,37 +3555,6 @@ bool ParseSsrcGroupAttribute(absl::string_view line, return true; } -bool ParseCryptoAttribute(absl::string_view line, - MediaContentDescription* media_desc, - SdpParseError* error) { - std::vector<absl::string_view> fields = - rtc::split(line.substr(kLinePrefixLength), kSdpDelimiterSpaceChar); - // RFC 4568 - // a=crypto:<tag> <crypto-suite> <key-params> [<session-params>] - const size_t expected_min_fields = 3; - if (fields.size() < expected_min_fields) { - return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); - } - std::string tag_value; - if (!GetValue(fields[0], kAttributeCrypto, &tag_value, error)) { - return false; - } - int tag = 0; - if (!GetValueFromString(line, tag_value, &tag, error)) { - return false; - } - const absl::string_view crypto_suite = fields[1]; - const absl::string_view key_params = fields[2]; - absl::string_view session_params; - if (fields.size() > 3) { - session_params = fields[3]; - } - - media_desc->AddCrypto( - CryptoParams(tag, crypto_suite, key_params, session_params)); - return true; -} - // Updates or creates a new codec entry in the audio description with according // to `name`, `clockrate`, `bitrate`, and `channels`. void UpdateCodec(int payload_type, diff --git a/third_party/libwebrtc/pc/webrtc_sdp_unittest.cc b/third_party/libwebrtc/pc/webrtc_sdp_unittest.cc index eb9bc729c6..999f0b6b26 100644 --- a/third_party/libwebrtc/pc/webrtc_sdp_unittest.cc +++ b/third_party/libwebrtc/pc/webrtc_sdp_unittest.cc @@ -25,7 +25,6 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" -#include "api/crypto_params.h" #include "api/jsep_session_description.h" #include "api/media_types.h" #include "api/rtp_parameters.h" @@ -59,7 +58,6 @@ using cricket::AudioContentDescription; using cricket::Candidate; using cricket::ContentGroup; using cricket::ContentInfo; -using cricket::CryptoParams; using cricket::ICE_CANDIDATE_COMPONENT_RTCP; using cricket::ICE_CANDIDATE_COMPONENT_RTP; using cricket::kFecSsrcGroupSemantics; @@ -102,13 +100,6 @@ static const char kCandidateFoundation1[] = "a0+B/1"; static const char kCandidateFoundation2[] = "a0+B/2"; static const char kCandidateFoundation3[] = "a0+B/3"; static const char kCandidateFoundation4[] = "a0+B/4"; -static const char kAttributeCryptoVoice[] = - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n"; -static const char kAttributeCryptoVideo[] = - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n"; static const char kFingerprint[] = "a=fingerprint:sha-1 " "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"; @@ -141,10 +132,6 @@ struct CodecParams { int maxaveragebitrate; }; -// TODO(deadbeef): In these reference strings, use "a=fingerprint" by default -// instead of "a=crypto", and have an explicit test for adding "a=crypto". -// Currently it's the other way around. - // Reference sdp string static const char kSdpFullString[] = "v=0\r\n" @@ -171,14 +158,13 @@ static const char kSdpFullString[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -199,11 +185,11 @@ static const char kSdpFullString[] = "a=candidate:a0+B/4 1 udp 2130706432 74.125.224.39 3457 typ relay " "generation 2\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" "a=mid:video_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" @@ -221,14 +207,14 @@ static const char kSdpString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -237,11 +223,12 @@ static const char kSdpString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" @@ -253,6 +240,9 @@ static const char kSdpSctpDataChannelString[] = "c=IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:data_content_name\r\n" "a=sctpmap:5000 webrtc-datachannel 1024\r\n"; @@ -265,6 +255,9 @@ static const char kSdpSctpDataChannelStringWithSctpPort[] = "c=IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:data_content_name\r\n"; // draft-ietf-mmusic-sctp-sdp-26 @@ -274,6 +267,9 @@ static const char kSdpSctpDataChannelStringWithSctpColonPort[] = "c=IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:data_content_name\r\n"; static const char kSdpSctpDataChannelWithCandidatesString[] = @@ -288,6 +284,9 @@ static const char kSdpSctpDataChannelWithCandidatesString[] = "generation 2\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:data_content_name\r\n" "a=sctpmap:5000 webrtc-datachannel 1024\r\n"; @@ -316,6 +315,9 @@ static const char kSdpAudioString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=rtpmap:111 opus/48000/2\r\n" @@ -327,6 +329,9 @@ static const char kSdpVideoString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=sendrecv\r\n" "a=rtpmap:120 VP8/90000\r\n" @@ -360,14 +365,14 @@ static const char kBundleOnlySdpFullString[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -379,9 +384,9 @@ static const char kBundleOnlySdpFullString[] = "a=mid:video_content_name\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" "a=ssrc:3 cname:stream_1_cname\r\n"; @@ -413,13 +418,13 @@ static const char kPlanBSdpFullString[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -443,10 +448,11 @@ static const char kPlanBSdpFullString[] = "a=candidate:a0+B/4 1 udp 2130706432 74.125.224.39 3457 typ relay " "generation 2\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" @@ -486,14 +492,14 @@ static const char kUnifiedPlanSdpFullString[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -515,11 +521,12 @@ static const char kUnifiedPlanSdpFullString[] = "a=candidate:a0+B/4 1 udp 2130706432 74.125.224.39 3457 typ relay " "generation 2\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" @@ -529,14 +536,14 @@ static const char kUnifiedPlanSdpFullString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice_2\r\na=ice-pwd:pwd_voice_2\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name_2\r\n" "a=msid:local_stream_2 audio_track_id_2\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -546,11 +553,12 @@ static const char kUnifiedPlanSdpFullString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video_2\r\na=ice-pwd:pwd_video_2\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name_2\r\n" "a=msid:local_stream_2 video_track_id_2\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc:5 cname:stream_2_cname\r\n" // Video track 3, stream 2. @@ -558,11 +566,12 @@ static const char kUnifiedPlanSdpFullString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video_3\r\na=ice-pwd:pwd_video_3\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name_3\r\n" "a=msid:local_stream_2 video_track_id_3\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc:6 cname:stream_2_cname\r\n"; @@ -599,14 +608,14 @@ static const char kUnifiedPlanSdpFullStringWithSpecialMsid[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -617,15 +626,15 @@ static const char kUnifiedPlanSdpFullStringWithSpecialMsid[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice_2\r\na=ice-pwd:pwd_voice_2\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name_2\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 audio_track_id_2\r\n" "a=msid:local_stream_2 audio_track_id_2\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -638,14 +647,14 @@ static const char kUnifiedPlanSdpFullStringWithSpecialMsid[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice_3\r\na=ice-pwd:pwd_voice_3\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name_3\r\n" "a=sendrecv\r\n" "a=msid:- audio_track_id_3\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -678,14 +687,14 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -706,11 +715,12 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "a=candidate:a0+B/4 1 udp 2130706432 74.125.224.39 3457 typ relay " "generation 2\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" // Audio track 2, stream 2. "m=audio 9 RTP/SAVPF 111 103 104\r\n" @@ -722,9 +732,6 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -736,8 +743,6 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "a=mid:video_content_name_2\r\n" "a=msid:local_stream_2 video_track_id_2\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" // Video track 3, stream 2. "m=video 9 RTP/SAVPF 120\r\n" @@ -747,8 +752,6 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "a=mid:video_content_name_3\r\n" "a=msid:local_stream_2 video_track_id_3\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n"; // One candidate reference string as per W3c spec. @@ -945,6 +948,14 @@ static void ReplaceRejected(bool audio_rejected, } } +static TransportDescription MakeTransportDescription(std::string ufrag, + std::string pwd) { + rtc::SSLFingerprint fingerprint(rtc::DIGEST_SHA_1, kIdentityDigest); + return TransportDescription(std::vector<std::string>(), ufrag, pwd, + cricket::ICEMODE_FULL, + cricket::CONNECTIONROLE_NONE, &fingerprint); +} + // WebRtcSdpTest class WebRtcSdpTest : public ::testing::Test { @@ -982,11 +993,12 @@ class WebRtcSdpTest : public ::testing::Test { desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp, absl::WrapUnique(video_desc_)); - // TransportInfo + // TransportInfo, with fingerprint + rtc::SSLFingerprint fingerprint(rtc::DIGEST_SHA_1, kIdentityDigest); desc_.AddTransportInfo(TransportInfo( - kAudioContentName, TransportDescription(kUfragVoice, kPwdVoice))); + kAudioContentName, MakeTransportDescription(kUfragVoice, kPwdVoice))); desc_.AddTransportInfo(TransportInfo( - kVideoContentName, TransportDescription(kUfragVideo, kPwdVideo))); + kVideoContentName, MakeTransportDescription(kUfragVideo, kPwdVideo))); // v4 host int port = 1234; @@ -1186,8 +1198,9 @@ class WebRtcSdpTest : public ::testing::Test { audio_desc_2->AddStream(audio_track_2); desc_.AddContent(kAudioContentName2, MediaProtocolType::kRtp, absl::WrapUnique(audio_desc_2)); - desc_.AddTransportInfo(TransportInfo( - kAudioContentName2, TransportDescription(kUfragVoice2, kPwdVoice2))); + desc_.AddTransportInfo( + TransportInfo(kAudioContentName2, + MakeTransportDescription(kUfragVoice2, kPwdVoice2))); // Video track 2, in stream 2. VideoContentDescription* video_desc_2 = CreateVideoContentDescription(); StreamParams video_track_2; @@ -1200,8 +1213,9 @@ class WebRtcSdpTest : public ::testing::Test { video_desc_2->AddStream(video_track_2); desc_.AddContent(kVideoContentName2, MediaProtocolType::kRtp, absl::WrapUnique(video_desc_2)); - desc_.AddTransportInfo(TransportInfo( - kVideoContentName2, TransportDescription(kUfragVideo2, kPwdVideo2))); + desc_.AddTransportInfo( + TransportInfo(kVideoContentName2, + MakeTransportDescription(kUfragVideo2, kPwdVideo2))); // Video track 3, in stream 2. VideoContentDescription* video_desc_3 = CreateVideoContentDescription(); @@ -1215,8 +1229,9 @@ class WebRtcSdpTest : public ::testing::Test { video_desc_3->AddStream(video_track_3); desc_.AddContent(kVideoContentName3, MediaProtocolType::kRtp, absl::WrapUnique(video_desc_3)); - desc_.AddTransportInfo(TransportInfo( - kVideoContentName3, TransportDescription(kUfragVideo3, kPwdVideo3))); + desc_.AddTransportInfo( + TransportInfo(kVideoContentName3, + MakeTransportDescription(kUfragVideo3, kPwdVideo3))); desc_.set_msid_signaling(cricket::kMsidSignalingMediaSection | cricket::kMsidSignalingSemantic); @@ -1230,10 +1245,6 @@ class WebRtcSdpTest : public ::testing::Test { AudioContentDescription* audio = new AudioContentDescription(); audio->set_rtcp_mux(true); audio->set_rtcp_reduced_size(true); - audio->AddCrypto(CryptoParams( - 1, "AES_CM_128_HMAC_SHA1_32", - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32", - "dummy_session_params")); audio->set_protocol(cricket::kMediaProtocolSavpf); audio->AddCodec(cricket::CreateAudioCodec(111, "opus", 48000, 2)); audio->AddCodec(cricket::CreateAudioCodec(103, "ISAC", 16000, 1)); @@ -1260,8 +1271,9 @@ class WebRtcSdpTest : public ::testing::Test { audio_desc_2->AddStream(audio_track_2); desc_.AddContent(kAudioContentName2, MediaProtocolType::kRtp, absl::WrapUnique(audio_desc_2)); - desc_.AddTransportInfo(TransportInfo( - kAudioContentName2, TransportDescription(kUfragVoice2, kPwdVoice2))); + desc_.AddTransportInfo( + TransportInfo(kAudioContentName2, + MakeTransportDescription(kUfragVoice2, kPwdVoice2))); // Audio track 3 has no stream ids. AudioContentDescription* audio_desc_3 = CreateAudioContentDescription(); @@ -1273,8 +1285,9 @@ class WebRtcSdpTest : public ::testing::Test { audio_desc_3->AddStream(audio_track_3); desc_.AddContent(kAudioContentName3, MediaProtocolType::kRtp, absl::WrapUnique(audio_desc_3)); - desc_.AddTransportInfo(TransportInfo( - kAudioContentName3, TransportDescription(kUfragVoice3, kPwdVoice3))); + desc_.AddTransportInfo( + TransportInfo(kAudioContentName3, + MakeTransportDescription(kUfragVoice3, kPwdVoice3))); desc_.set_msid_signaling(msid_signaling); ASSERT_TRUE(jdesc_.Initialize(desc_.Clone(), jdesc_.session_id(), jdesc_.session_version())); @@ -1308,9 +1321,6 @@ class WebRtcSdpTest : public ::testing::Test { // configuration. VideoContentDescription* CreateVideoContentDescription() { VideoContentDescription* video = new VideoContentDescription(); - video->AddCrypto(CryptoParams( - 1, "AES_CM_128_HMAC_SHA1_80", - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32", "")); video->set_protocol(cricket::kMediaProtocolSavpf); video->AddCodec(cricket::CreateVideoCodec(120, "VP8")); return video; @@ -1331,20 +1341,6 @@ class WebRtcSdpTest : public ::testing::Test { // rtcp_reduced_size EXPECT_EQ(cd1->rtcp_reduced_size(), cd2->rtcp_reduced_size()); - // cryptos - EXPECT_EQ(cd1->cryptos().size(), cd2->cryptos().size()); - if (cd1->cryptos().size() != cd2->cryptos().size()) { - ADD_FAILURE(); - return; - } - for (size_t i = 0; i < cd1->cryptos().size(); ++i) { - const CryptoParams c1 = cd1->cryptos().at(i); - const CryptoParams c2 = cd2->cryptos().at(i); - EXPECT_TRUE(c1.Matches(c2)); - EXPECT_EQ(c1.key_params, c2.key_params); - EXPECT_EQ(c1.session_params, c2.session_params); - } - // protocol // Use an equivalence class here, for old and new versions of the // protocol description. @@ -1497,8 +1493,14 @@ class WebRtcSdpTest : public ::testing::Test { EXPECT_EQ(transport1.description.ice_mode, transport2.description.ice_mode); if (transport1.description.identity_fingerprint) { - EXPECT_EQ(*transport1.description.identity_fingerprint, - *transport2.description.identity_fingerprint); + if (!transport2.description.identity_fingerprint) { + ADD_FAILURE() << "transport[" << i + << "]: left transport has fingerprint, right transport " + "does not have it"; + } else { + EXPECT_EQ(*transport1.description.identity_fingerprint, + *transport2.description.identity_fingerprint); + } } else { EXPECT_EQ(transport1.description.identity_fingerprint.get(), transport2.description.identity_fingerprint.get()); @@ -1559,7 +1561,7 @@ class WebRtcSdpTest : public ::testing::Test { RTC_DCHECK_NOTREACHED(); } TransportInfo transport_info(content_name, - TransportDescription(ufrag, pwd)); + MakeTransportDescription(ufrag, pwd)); SessionDescription* desc = const_cast<SessionDescription*>(jdesc->description()); desc->RemoveTransportInfoByName(content_name); @@ -1598,22 +1600,6 @@ class WebRtcSdpTest : public ::testing::Test { desc_.AddTransportInfo(transport_info); } - void AddFingerprint() { - desc_.RemoveTransportInfoByName(kAudioContentName); - desc_.RemoveTransportInfoByName(kVideoContentName); - rtc::SSLFingerprint fingerprint(rtc::DIGEST_SHA_1, kIdentityDigest); - desc_.AddTransportInfo(TransportInfo( - kAudioContentName, - TransportDescription(std::vector<std::string>(), kUfragVoice, kPwdVoice, - cricket::ICEMODE_FULL, - cricket::CONNECTIONROLE_NONE, &fingerprint))); - desc_.AddTransportInfo(TransportInfo( - kVideoContentName, - TransportDescription(std::vector<std::string>(), kUfragVideo, kPwdVideo, - cricket::ICEMODE_FULL, - cricket::CONNECTIONROLE_NONE, &fingerprint))); - } - void AddExtmap(bool encrypted) { audio_desc_ = new AudioContentDescription(*audio_desc_); video_desc_ = new VideoContentDescription(*video_desc_); @@ -1629,11 +1615,6 @@ class WebRtcSdpTest : public ::testing::Test { absl::WrapUnique(video_desc_)); } - void RemoveCryptos() { - audio_desc_->set_cryptos(std::vector<CryptoParams>()); - video_desc_->set_cryptos(std::vector<CryptoParams>()); - } - // Removes everything in StreamParams from the session description that is // used for a=ssrc lines. void RemoveSsrcSignalingFromStreamParams() { @@ -1730,7 +1711,7 @@ class WebRtcSdpTest : public ::testing::Test { desc_.AddContent(kDataContentName, MediaProtocolType::kSctp, std::move(data)); desc_.AddTransportInfo(TransportInfo( - kDataContentName, TransportDescription(kUfragData, kPwdData))); + kDataContentName, MakeTransportDescription(kUfragData, kPwdData))); } bool TestDeserializeDirection(RtpTransceiverDirection direction) { @@ -2035,39 +2016,6 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionEmpty) { EXPECT_EQ("", webrtc::SdpSerialize(jdesc_empty)); } -// This tests serialization of SDP with a=crypto and a=fingerprint, as would be -// the case in a DTLS offer. -TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprint) { - AddFingerprint(); - JsepSessionDescription jdesc_with_fingerprint(kDummyType); - MakeDescriptionWithoutCandidates(&jdesc_with_fingerprint); - std::string message = webrtc::SdpSerialize(jdesc_with_fingerprint); - - std::string sdp_with_fingerprint = kSdpString; - InjectAfter(kAttributeIcePwdVoice, kFingerprint, &sdp_with_fingerprint); - InjectAfter(kAttributeIcePwdVideo, kFingerprint, &sdp_with_fingerprint); - - EXPECT_EQ(sdp_with_fingerprint, message); -} - -// This tests serialization of SDP with a=fingerprint with no a=crypto, as would -// be the case in a DTLS answer. -TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprintNoCryptos) { - AddFingerprint(); - RemoveCryptos(); - JsepSessionDescription jdesc_with_fingerprint(kDummyType); - MakeDescriptionWithoutCandidates(&jdesc_with_fingerprint); - std::string message = webrtc::SdpSerialize(jdesc_with_fingerprint); - - std::string sdp_with_fingerprint = kSdpString; - Replace(kAttributeCryptoVoice, "", &sdp_with_fingerprint); - Replace(kAttributeCryptoVideo, "", &sdp_with_fingerprint); - InjectAfter(kAttributeIcePwdVoice, kFingerprint, &sdp_with_fingerprint); - InjectAfter(kAttributeIcePwdVideo, kFingerprint, &sdp_with_fingerprint); - - EXPECT_EQ(sdp_with_fingerprint, message); -} - TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithoutCandidates) { // JsepSessionDescription with desc but without candidates. JsepSessionDescription jdesc_no_candidates(kDummyType); @@ -2461,8 +2409,6 @@ TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutRtpmapButWithFmtp) { // Ensure that we can deserialize SDP with a=fingerprint properly. TEST_F(WebRtcSdpTest, DeserializeJsepSessionDescriptionWithFingerprint) { - // Add a DTLS a=fingerprint attribute to our session description. - AddFingerprint(); JsepSessionDescription new_jdesc(kDummyType); ASSERT_TRUE(new_jdesc.Initialize(desc_.Clone(), jdesc_.session_id(), jdesc_.session_version())); @@ -3177,8 +3123,6 @@ TEST_F(WebRtcSdpTest, DeserializeSdpWithInvalidAttributeValue) { // ssrc ExpectParseFailure("a=ssrc:1", "a=ssrc:badvalue"); ExpectParseFailure("a=ssrc-group:FEC 2 3", "a=ssrc-group:FEC badvalue 3"); - // crypto - ExpectParseFailure("a=crypto:1 ", "a=crypto:badvalue "); // rtpmap ExpectParseFailure("a=rtpmap:111 ", "a=rtpmap:badvalue "); ExpectParseFailure("opus/48000/2", "opus/badvalue/2"); @@ -3564,7 +3508,6 @@ TEST_F(WebRtcSdpTest, RoundTripSdpWithSctpDataChannelsWithCandidates) { } TEST_F(WebRtcSdpTest, SerializeDtlsSetupAttribute) { - AddFingerprint(); TransportInfo audio_transport_info = *(desc_.GetTransportInfoByName(kAudioContentName)); EXPECT_EQ(cricket::CONNECTIONROLE_NONE, @@ -3590,9 +3533,6 @@ TEST_F(WebRtcSdpTest, SerializeDtlsSetupAttribute) { std::string message = webrtc::SdpSerialize(jdesc_); std::string sdp_with_dtlssetup = kSdpFullString; - // Fingerprint attribute is necessary to add DTLS setup attribute. - InjectAfter(kAttributeIcePwdVoice, kFingerprint, &sdp_with_dtlssetup); - InjectAfter(kAttributeIcePwdVideo, kFingerprint, &sdp_with_dtlssetup); // Now adding `setup` attribute. InjectAfter(kFingerprint, "a=setup:active\r\n", &sdp_with_dtlssetup); EXPECT_EQ(sdp_with_dtlssetup, message); @@ -4331,6 +4271,27 @@ TEST_F(WebRtcSdpTest, DeserializeMsidAttributeWithMissingStreamId) { EXPECT_FALSE(SdpDeserialize(sdp, &jdesc_output)); } +TEST_F(WebRtcSdpTest, DeserializeMsidAttributeWithDuplicateStreamIdAndTrackId) { + std::string sdp = + "v=0\r\n" + "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n" + "s=-\r\n" + "t=0 0\r\n" + "m=audio 9 RTP/SAVPF 111\r\n" + "a=mid:0\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtpmap:111 opus/48000/2\r\n" + "a=msid:stream_id track_id\r\n" + "m=audio 9 RTP/SAVPF 111\r\n" + "a=mid:1\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtpmap:111 opus/48000/2\r\n" + "a=msid:stream_id track_id\r\n"; + + JsepSessionDescription jdesc_output(kDummyType); + EXPECT_FALSE(SdpDeserialize(sdp, &jdesc_output)); +} + // Tests that if both session-level address and media-level address exist, use // the media-level address. TEST_F(WebRtcSdpTest, ParseConnectionData) { @@ -5121,13 +5082,15 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { "a=setup:actpass\r\n" "a=ice-ufrag:ETEn\r\n" "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n" - "m=video 9 UDP/TLS/RTP/SAVPF 96 97\r\n" + "m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99\r\n" "c=IN IP4 0.0.0.0\r\n" "a=rtcp-mux\r\n" "a=sendonly\r\n" "a=mid:0\r\n" "a=rtpmap:96 H264/90000\r\n" "a=rtpmap:97 VP9/90000\r\n" + "a=rtpmap:98 AV1/90000\r\n" + "a=rtpmap:99 H265/90000\r\n" "a=ssrc:1234 cname:test\r\n"; JsepSessionDescription jdesc(kDummyType); EXPECT_TRUE(SdpDeserialize(sdp, &jdesc)); @@ -5136,7 +5099,7 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { const auto* description = content.media_description(); ASSERT_NE(description, nullptr); const std::vector<cricket::Codec> codecs = description->codecs(); - ASSERT_EQ(codecs.size(), 2u); + ASSERT_EQ(codecs.size(), 4u); std::string value; EXPECT_EQ(codecs[0].name, "H264"); @@ -5146,4 +5109,18 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { EXPECT_EQ(codecs[1].name, "VP9"); EXPECT_TRUE(codecs[1].GetParam("profile-id", &value)); EXPECT_EQ(value, "0"); + + EXPECT_EQ(codecs[2].name, "AV1"); + EXPECT_TRUE(codecs[2].GetParam("profile", &value)); + EXPECT_EQ(value, "0"); + EXPECT_TRUE(codecs[2].GetParam("level-idx", &value)); + EXPECT_EQ(value, "5"); + EXPECT_TRUE(codecs[2].GetParam("tier", &value)); + EXPECT_EQ(value, "0"); + + EXPECT_EQ(codecs[3].name, "H265"); + EXPECT_TRUE(codecs[3].GetParam("level-id", &value)); + EXPECT_EQ(value, "93"); + EXPECT_TRUE(codecs[3].GetParam("tx-mode", &value)); + EXPECT_EQ(value, "SRST"); } diff --git a/third_party/libwebrtc/pc/webrtc_session_description_factory.cc b/third_party/libwebrtc/pc/webrtc_session_description_factory.cc index 42a8da3e70..9919260aa3 100644 --- a/third_party/libwebrtc/pc/webrtc_session_description_factory.cc +++ b/third_party/libwebrtc/pc/webrtc_session_description_factory.cc @@ -128,13 +128,10 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( RTC_DCHECK(signaling_thread_); if (!dtls_enabled) { - SetSdesPolicy(cricket::SEC_REQUIRED); - RTC_LOG(LS_VERBOSE) << "DTLS-SRTP disabled."; + RTC_LOG(LS_INFO) << "DTLS-SRTP disabled"; + transport_desc_factory_.SetInsecureForTesting(); return; } - - // SRTP-SDES is disabled if DTLS is on. - SetSdesPolicy(cricket::SEC_DISABLED); if (certificate) { // Use `certificate`. certificate_request_state_ = CERTIFICATE_WAITING; @@ -142,31 +139,32 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( RTC_LOG(LS_VERBOSE) << "DTLS-SRTP enabled; has certificate parameter."; RTC_LOG(LS_INFO) << "Using certificate supplied to the constructor."; SetCertificate(certificate); - } else { - // Generate certificate. - certificate_request_state_ = CERTIFICATE_WAITING; - - auto callback = [weak_ptr = weak_factory_.GetWeakPtr()]( - rtc::scoped_refptr<rtc::RTCCertificate> certificate) { - if (!weak_ptr) { - return; - } - if (certificate) { - weak_ptr->SetCertificate(std::move(certificate)); - } else { - weak_ptr->OnCertificateRequestFailed(); - } - }; + return; + } + // Generate certificate. + RTC_DCHECK(cert_generator_); + certificate_request_state_ = CERTIFICATE_WAITING; + + auto callback = [weak_ptr = weak_factory_.GetWeakPtr()]( + rtc::scoped_refptr<rtc::RTCCertificate> certificate) { + if (!weak_ptr) { + return; + } + if (certificate) { + weak_ptr->SetCertificate(std::move(certificate)); + } else { + weak_ptr->OnCertificateRequestFailed(); + } + }; - rtc::KeyParams key_params = rtc::KeyParams(); - RTC_LOG(LS_VERBOSE) - << "DTLS-SRTP enabled; sending DTLS identity request (key type: " - << key_params.type() << ")."; + rtc::KeyParams key_params = rtc::KeyParams(); + RTC_LOG(LS_VERBOSE) + << "DTLS-SRTP enabled; sending DTLS identity request (key type: " + << key_params.type() << ")."; - // Request certificate. This happens asynchronously on a different thread. - cert_generator_->GenerateCertificateAsync(key_params, absl::nullopt, - std::move(callback)); - } + // Request certificate. This happens asynchronously on a different thread. + cert_generator_->GenerateCertificateAsync(key_params, absl::nullopt, + std::move(callback)); } WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { @@ -258,15 +256,6 @@ void WebRtcSessionDescriptionFactory::CreateAnswer( } } -void WebRtcSessionDescriptionFactory::SetSdesPolicy( - cricket::SecurePolicy secure_policy) { - session_desc_factory_.set_secure(secure_policy); -} - -cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const { - return session_desc_factory_.secure(); -} - void WebRtcSessionDescriptionFactory::InternalCreateOffer( CreateSessionDescriptionRequest request) { if (sdp_info_->local_description()) { @@ -450,7 +439,6 @@ void WebRtcSessionDescriptionFactory::SetCertificate( on_certificate_ready_(certificate); transport_desc_factory_.set_certificate(std::move(certificate)); - transport_desc_factory_.set_secure(cricket::SEC_ENABLED); while (!create_session_description_requests_.empty()) { if (create_session_description_requests_.front().type == @@ -462,4 +450,5 @@ void WebRtcSessionDescriptionFactory::SetCertificate( create_session_description_requests_.pop(); } } + } // namespace webrtc diff --git a/third_party/libwebrtc/pc/webrtc_session_description_factory.h b/third_party/libwebrtc/pc/webrtc_session_description_factory.h index 22ead41d9b..eed922eda7 100644 --- a/third_party/libwebrtc/pc/webrtc_session_description_factory.h +++ b/third_party/libwebrtc/pc/webrtc_session_description_factory.h @@ -73,9 +73,6 @@ class WebRtcSessionDescriptionFactory { void CreateAnswer(CreateSessionDescriptionObserver* observer, const cricket::MediaSessionOptions& session_options); - void SetSdesPolicy(cricket::SecurePolicy secure_policy); - cricket::SecurePolicy SdesPolicy() const; - void set_enable_encrypted_rtp_header_extensions(bool enable) { session_desc_factory_.set_enable_encrypted_rtp_header_extensions(enable); } @@ -88,6 +85,9 @@ class WebRtcSessionDescriptionFactory { bool waiting_for_certificate_for_testing() const { return certificate_request_state_ == CERTIFICATE_WAITING; } + void SetInsecureForTesting() { + transport_desc_factory_.SetInsecureForTesting(); + } private: enum CertificateRequestState { @@ -144,6 +144,7 @@ class WebRtcSessionDescriptionFactory { std::function<void(const rtc::scoped_refptr<rtc::RTCCertificate>&)> on_certificate_ready_; + rtc::WeakPtrFactory<WebRtcSessionDescriptionFactory> weak_factory_{this}; }; } // namespace webrtc |