blob: f914fc8365e4d5ddefff902f68f7a07bd103a1f6 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/peer_connection.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000013#include <limits.h>
14#include <stddef.h>
Harald Alvestrand0ccfbd22021-04-08 07:25:04 +000015
deadbeefeb459812015-12-15 19:24:43 -080016#include <algorithm>
Harald Alvestrande15fb152020-10-19 13:28:05 +000017#include <memory>
Harald Alvestrande15fb152020-10-19 13:28:05 +000018#include <set>
Harald Alvestrand0d4af122022-01-31 09:36:05 +000019#include <string>
Harald Alvestrand3eaee6b2020-10-19 06:35:55 +000020#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000021
Steve Anton64b626b2019-01-28 17:25:26 -080022#include "absl/algorithm/container.h"
Fredrik Solenberg41f3a432018-12-17 21:02:22 +010023#include "absl/strings/match.h"
Harald Alvestrand0d4af122022-01-31 09:36:05 +000024#include "absl/strings/string_view.h"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "api/jsep_ice_candidate.h"
Harald Alvestrand763f5a92020-10-22 10:39:40 +000026#include "api/rtp_parameters.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000027#include "api/rtp_transceiver_direction.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "api/uma_metrics.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000029#include "api/video/video_codec_constants.h"
30#include "call/audio_state.h"
31#include "call/packet_receiver.h"
Harald Alvestrand763f5a92020-10-22 10:39:40 +000032#include "media/base/media_channel.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000033#include "media/base/media_config.h"
Harald Alvestrand0d4af122022-01-31 09:36:05 +000034#include "media/base/media_engine.h"
Amit Hilbuchf4770402019-04-08 14:11:57 -070035#include "media/base/rid_description.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000036#include "media/base/stream_params.h"
37#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Harald Alvestrand0ccfbd22021-04-08 07:25:04 +000038#include "p2p/base/basic_async_resolver_factory.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000039#include "p2p/base/connection.h"
40#include "p2p/base/connection_info.h"
41#include "p2p/base/dtls_transport_internal.h"
42#include "p2p/base/p2p_constants.h"
43#include "p2p/base/p2p_transport_channel.h"
44#include "p2p/base/transport_info.h"
Harald Alvestrand9e334b72022-05-04 13:38:31 +000045#include "pc/channel_manager.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000046#include "pc/ice_server_parsing.h"
Harald Alvestrand763f5a92020-10-22 10:39:40 +000047#include "pc/rtp_receiver.h"
Harald Alvestrand0d4af122022-01-31 09:36:05 +000048#include "pc/rtp_receiver_proxy.h"
Harald Alvestrand763f5a92020-10-22 10:39:40 +000049#include "pc/rtp_sender.h"
Harald Alvestrand0d4af122022-01-31 09:36:05 +000050#include "pc/rtp_sender_proxy.h"
Harald Alvestrandc85328f2019-02-28 07:51:00 +010051#include "pc/sctp_transport.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000052#include "pc/simulcast_description.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000053#include "pc/webrtc_session_description_factory.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000054#include "rtc_base/helpers.h"
55#include "rtc_base/ip_address.h"
56#include "rtc_base/location.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020057#include "rtc_base/logging.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000058#include "rtc_base/net_helper.h"
Harald Alvestrand0d4af122022-01-31 09:36:05 +000059#include "rtc_base/network.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000060#include "rtc_base/network_constants.h"
Harald Alvestrand5761e7b2021-01-29 14:45:08 +000061#include "rtc_base/ref_counted_object.h"
Harald Alvestrand1f7eab62020-10-18 16:51:47 +000062#include "rtc_base/socket_address.h"
Steve Anton10542f22019-01-11 09:11:00 -080063#include "rtc_base/string_encode.h"
Tomas Gunnarsson1e40a0c2020-09-28 10:39:31 +020064#include "rtc_base/task_utils/to_queued_task.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020065#include "rtc_base/trace_event.h"
Harald Alvestrand763f5a92020-10-22 10:39:40 +000066#include "rtc_base/unique_id_generator.h"
Qingsi Wang7fc821d2018-07-12 12:54:53 -070067#include "system_wrappers/include/metrics.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068
Steve Anton75737c02017-11-06 10:37:17 -080069using cricket::ContentInfo;
70using cricket::ContentInfos;
71using cricket::MediaContentDescription;
Steve Anton5adfafd2017-12-20 16:34:00 -080072using cricket::MediaProtocolType;
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080073using cricket::RidDescription;
74using cricket::RidDirection;
Amit Hilbuchc63ddb22019-01-02 10:13:58 -080075using cricket::SessionDescription;
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080076using cricket::SimulcastDescription;
77using cricket::SimulcastLayer;
Amit Hilbuchc63ddb22019-01-02 10:13:58 -080078using cricket::SimulcastLayerList;
Amit Hilbuchbcd39d42019-01-25 17:13:56 -080079using cricket::StreamParams;
Steve Anton75737c02017-11-06 10:37:17 -080080using cricket::TransportInfo;
81
82using cricket::LOCAL_PORT_TYPE;
Steve Anton75737c02017-11-06 10:37:17 -080083using cricket::PRFLX_PORT_TYPE;
Jeroen de Borstaf242c82019-04-24 13:13:48 -070084using cricket::RELAY_PORT_TYPE;
85using cricket::STUN_PORT_TYPE;
Steve Anton75737c02017-11-06 10:37:17 -080086
Steve Antonba818672017-11-06 10:21:57 -080087namespace webrtc {
88
Steve Anton75737c02017-11-06 10:37:17 -080089namespace {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090
Amit Hilbuche2a284d2019-03-05 12:36:31 -080091// UMA metric names.
Amit Hilbuche2a284d2019-03-05 12:36:31 -080092const char kSimulcastNumberOfEncodings[] =
93 "WebRTC.PeerConnection.Simulcast.NumberOfSendEncodings";
Amit Hilbuche2a284d2019-03-05 12:36:31 -080094
Harald Alvestrand19793842018-06-25 12:03:50 +020095static const int REPORT_USAGE_PATTERN_DELAY_MS = 60000;
96
Taylor Brandstettera1c30352016-05-13 08:15:11 -070097uint32_t ConvertIceTransportTypeToCandidateFilter(
98 PeerConnectionInterface::IceTransportsType type) {
99 switch (type) {
100 case PeerConnectionInterface::kNone:
101 return cricket::CF_NONE;
102 case PeerConnectionInterface::kRelay:
103 return cricket::CF_RELAY;
104 case PeerConnectionInterface::kNoHost:
105 return (cricket::CF_ALL & ~cricket::CF_HOST);
106 case PeerConnectionInterface::kAll:
107 return cricket::CF_ALL;
108 default:
Artem Titovd3251962021-11-15 16:57:07 +0100109 RTC_DCHECK_NOTREACHED();
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700110 }
111 return cricket::CF_NONE;
112}
113
Steve Anton75737c02017-11-06 10:37:17 -0800114IceCandidatePairType GetIceCandidatePairCounter(
115 const cricket::Candidate& local,
116 const cricket::Candidate& remote) {
117 const auto& l = local.type();
118 const auto& r = remote.type();
119 const auto& host = LOCAL_PORT_TYPE;
120 const auto& srflx = STUN_PORT_TYPE;
121 const auto& relay = RELAY_PORT_TYPE;
122 const auto& prflx = PRFLX_PORT_TYPE;
123 if (l == host && r == host) {
Jeroen de Borst833979f2018-12-13 08:25:54 -0800124 bool local_hostname =
125 !local.address().hostname().empty() && local.address().IsUnresolvedIP();
126 bool remote_hostname = !remote.address().hostname().empty() &&
127 remote.address().IsUnresolvedIP();
Steve Anton75737c02017-11-06 10:37:17 -0800128 bool local_private = IPIsPrivate(local.address().ipaddr());
129 bool remote_private = IPIsPrivate(remote.address().ipaddr());
Jeroen de Borst833979f2018-12-13 08:25:54 -0800130 if (local_hostname) {
131 if (remote_hostname) {
132 return kIceCandidatePairHostNameHostName;
133 } else if (remote_private) {
134 return kIceCandidatePairHostNameHostPrivate;
135 } else {
136 return kIceCandidatePairHostNameHostPublic;
137 }
138 } else if (local_private) {
139 if (remote_hostname) {
140 return kIceCandidatePairHostPrivateHostName;
141 } else if (remote_private) {
Steve Anton75737c02017-11-06 10:37:17 -0800142 return kIceCandidatePairHostPrivateHostPrivate;
143 } else {
144 return kIceCandidatePairHostPrivateHostPublic;
145 }
146 } else {
Jeroen de Borst833979f2018-12-13 08:25:54 -0800147 if (remote_hostname) {
148 return kIceCandidatePairHostPublicHostName;
149 } else if (remote_private) {
Steve Anton75737c02017-11-06 10:37:17 -0800150 return kIceCandidatePairHostPublicHostPrivate;
151 } else {
152 return kIceCandidatePairHostPublicHostPublic;
153 }
154 }
155 }
156 if (l == host && r == srflx)
157 return kIceCandidatePairHostSrflx;
158 if (l == host && r == relay)
159 return kIceCandidatePairHostRelay;
160 if (l == host && r == prflx)
161 return kIceCandidatePairHostPrflx;
162 if (l == srflx && r == host)
163 return kIceCandidatePairSrflxHost;
164 if (l == srflx && r == srflx)
165 return kIceCandidatePairSrflxSrflx;
166 if (l == srflx && r == relay)
167 return kIceCandidatePairSrflxRelay;
168 if (l == srflx && r == prflx)
169 return kIceCandidatePairSrflxPrflx;
170 if (l == relay && r == host)
171 return kIceCandidatePairRelayHost;
172 if (l == relay && r == srflx)
173 return kIceCandidatePairRelaySrflx;
174 if (l == relay && r == relay)
175 return kIceCandidatePairRelayRelay;
176 if (l == relay && r == prflx)
177 return kIceCandidatePairRelayPrflx;
178 if (l == prflx && r == host)
179 return kIceCandidatePairPrflxHost;
180 if (l == prflx && r == srflx)
181 return kIceCandidatePairPrflxSrflx;
182 if (l == prflx && r == relay)
183 return kIceCandidatePairPrflxRelay;
184 return kIceCandidatePairMax;
185}
186
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200187absl::optional<int> RTCConfigurationToIceConfigOptionalInt(
Qingsi Wang866e08d2018-03-22 17:54:23 -0700188 int rtc_configuration_parameter) {
189 if (rtc_configuration_parameter ==
190 webrtc::PeerConnectionInterface::RTCConfiguration::kUndefined) {
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200191 return absl::nullopt;
Qingsi Wang866e08d2018-03-22 17:54:23 -0700192 }
193 return rtc_configuration_parameter;
194}
195
Jonas Orelande3096512020-05-27 09:01:05 +0200196// Check if the changes of IceTransportsType motives an ice restart.
197bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,
198 PeerConnectionInterface::IceTransportsType current,
199 PeerConnectionInterface::IceTransportsType modified) {
200 if (current == modified) {
201 return false;
202 }
203
204 if (!surface_ice_candidates_on_ice_transport_type_changed) {
205 return true;
206 }
207
208 auto current_filter = ConvertIceTransportTypeToCandidateFilter(current);
209 auto modified_filter = ConvertIceTransportTypeToCandidateFilter(modified);
210
211 // If surface_ice_candidates_on_ice_transport_type_changed is true and we
212 // extend the filter, then no ice restart is needed.
213 return (current_filter & modified_filter) != current_filter;
214}
215
Harald Alvestrand62166932020-10-26 08:30:41 +0000216cricket::IceConfig ParseIceConfig(
217 const PeerConnectionInterface::RTCConfiguration& config) {
218 cricket::ContinualGatheringPolicy gathering_policy;
219 switch (config.continual_gathering_policy) {
220 case PeerConnectionInterface::GATHER_ONCE:
221 gathering_policy = cricket::GATHER_ONCE;
222 break;
223 case PeerConnectionInterface::GATHER_CONTINUALLY:
224 gathering_policy = cricket::GATHER_CONTINUALLY;
225 break;
226 default:
Artem Titovd3251962021-11-15 16:57:07 +0100227 RTC_DCHECK_NOTREACHED();
Harald Alvestrand62166932020-10-26 08:30:41 +0000228 gathering_policy = cricket::GATHER_ONCE;
229 }
230
231 cricket::IceConfig ice_config;
232 ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt(
233 config.ice_connection_receiving_timeout);
234 ice_config.prioritize_most_likely_candidate_pairs =
235 config.prioritize_most_likely_ice_candidate_pairs;
236 ice_config.backup_connection_ping_interval =
237 RTCConfigurationToIceConfigOptionalInt(
238 config.ice_backup_candidate_pair_ping_interval);
239 ice_config.continual_gathering_policy = gathering_policy;
240 ice_config.presume_writable_when_fully_relayed =
241 config.presume_writable_when_fully_relayed;
242 ice_config.surface_ice_candidates_on_ice_transport_type_changed =
243 config.surface_ice_candidates_on_ice_transport_type_changed;
244 ice_config.ice_check_interval_strong_connectivity =
245 config.ice_check_interval_strong_connectivity;
246 ice_config.ice_check_interval_weak_connectivity =
247 config.ice_check_interval_weak_connectivity;
248 ice_config.ice_check_min_interval = config.ice_check_min_interval;
249 ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout;
250 ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks;
251 ice_config.ice_inactive_timeout = config.ice_inactive_timeout;
252 ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
253 ice_config.network_preference = config.network_preference;
Derek Bailey6c127a12021-04-15 12:42:41 -0700254 ice_config.stable_writable_connection_ping_interval =
255 config.stable_writable_connection_ping_interval_ms;
Harald Alvestrand62166932020-10-26 08:30:41 +0000256 return ice_config;
257}
258
259// Ensures the configuration doesn't have any parameters with invalid values,
260// or values that conflict with other parameters.
261//
262// Returns RTCError::OK() if there are no issues.
263RTCError ValidateConfiguration(
264 const PeerConnectionInterface::RTCConfiguration& config) {
265 return cricket::P2PTransportChannel::ValidateIceConfig(
266 ParseIceConfig(config));
267}
268
269bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) {
270 return content->media_description()->rtcp_mux();
271}
272
Tommic3257d02021-02-10 17:40:08 +0000273bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration,
274 const PeerConnectionFactoryInterface::Options& options,
275 const PeerConnectionDependencies& dependencies) {
276 if (options.disable_encryption)
277 return false;
278
279 // Enable DTLS by default if we have an identity store or a certificate.
280 bool default_enabled =
281 (dependencies.cert_generator || !configuration.certificates.empty());
282
Harald Alvestrandca327932022-04-04 15:37:31 +0000283#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000284 // The `configuration` can override the default value.
285 return configuration.enable_dtls_srtp.value_or(default_enabled);
Harald Alvestrandca327932022-04-04 15:37:31 +0000286#else
287 return default_enabled;
288#endif
Tommic3257d02021-02-10 17:40:08 +0000289}
290
Steve Anton75737c02017-11-06 10:37:17 -0800291} // namespace
292
deadbeef293e9262017-01-11 12:28:30 -0800293bool PeerConnectionInterface::RTCConfiguration::operator==(
294 const PeerConnectionInterface::RTCConfiguration& o) const {
295 // This static_assert prevents us from accidentally breaking operator==.
Steve Anton300bf8e2017-07-14 10:13:10 -0700296 // Note: Order matters! Fields must be ordered the same as RTCConfiguration.
deadbeef293e9262017-01-11 12:28:30 -0800297 struct stuff_being_tested_for_equality {
Magnus Jedvert3beb2072017-07-14 14:23:56 +0000298 IceServers servers;
Steve Anton300bf8e2017-07-14 10:13:10 -0700299 IceTransportsType type;
deadbeef293e9262017-01-11 12:28:30 -0800300 BundlePolicy bundle_policy;
301 RtcpMuxPolicy rtcp_mux_policy;
Steve Anton300bf8e2017-07-14 10:13:10 -0700302 std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
303 int ice_candidate_pool_size;
304 bool disable_ipv6;
305 bool disable_ipv6_on_wifi;
deadbeefd21eab32017-07-26 16:50:11 -0700306 int max_ipv6_networks;
Daniel Lazarenko2870b0a2018-01-25 10:30:22 +0100307 bool disable_link_local_networks;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200308 absl::optional<int> screencast_min_bitrate;
309 absl::optional<bool> combined_audio_video_bwe;
Harald Alvestrandca327932022-04-04 15:37:31 +0000310#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000311 absl::optional<bool> enable_dtls_srtp;
Harald Alvestrandca327932022-04-04 15:37:31 +0000312#endif
deadbeef293e9262017-01-11 12:28:30 -0800313 TcpCandidatePolicy tcp_candidate_policy;
314 CandidateNetworkPolicy candidate_network_policy;
315 int audio_jitter_buffer_max_packets;
316 bool audio_jitter_buffer_fast_accelerate;
Jakob Ivarsson10403ae2018-11-27 15:45:20 +0100317 int audio_jitter_buffer_min_delay_ms;
Jakob Ivarsson53eae872019-01-10 15:58:36 +0100318 bool audio_jitter_buffer_enable_rtx_handling;
deadbeef293e9262017-01-11 12:28:30 -0800319 int ice_connection_receiving_timeout;
320 int ice_backup_candidate_pair_ping_interval;
321 ContinualGatheringPolicy continual_gathering_policy;
deadbeef293e9262017-01-11 12:28:30 -0800322 bool prioritize_most_likely_ice_candidate_pairs;
323 struct cricket::MediaConfig media_config;
deadbeef293e9262017-01-11 12:28:30 -0800324 bool prune_turn_ports;
Honghai Zhangf8998cf2019-10-14 11:27:50 -0700325 PortPrunePolicy turn_port_prune_policy;
deadbeef293e9262017-01-11 12:28:30 -0800326 bool presume_writable_when_fully_relayed;
327 bool enable_ice_renomination;
328 bool redetermine_role_on_ice_restart;
Qingsi Wang1fe119f2019-05-31 16:55:33 -0700329 bool surface_ice_candidates_on_ice_transport_type_changed;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200330 absl::optional<int> ice_check_interval_strong_connectivity;
331 absl::optional<int> ice_check_interval_weak_connectivity;
332 absl::optional<int> ice_check_min_interval;
333 absl::optional<int> ice_unwritable_timeout;
334 absl::optional<int> ice_unwritable_min_checks;
Jiawei Ou9d4fd5552018-12-06 23:30:17 -0800335 absl::optional<int> ice_inactive_timeout;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200336 absl::optional<int> stun_candidate_keepalive_interval;
Jonas Orelandbdcee282017-10-10 14:01:40 +0200337 webrtc::TurnCustomizer* turn_customizer;
Steve Anton79e79602017-11-20 10:25:56 -0800338 SdpSemantics sdp_semantics;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200339 absl::optional<rtc::AdapterType> network_preference;
Zhi Huangb57e1692018-06-12 11:41:11 -0700340 bool active_reset_srtp_params;
Benjamin Wright8c27cca2018-10-25 10:16:44 -0700341 absl::optional<CryptoOptions> crypto_options;
Johannes Kron89f874e2018-11-12 10:25:48 +0100342 bool offer_extmap_allow_mixed;
Jonas Oreland3c028422019-08-22 16:16:35 +0200343 std::string turn_logging_id;
Eldar Rello5ab79e62019-10-09 18:29:44 +0300344 bool enable_implicit_rollback;
philipel16cec3b2019-10-25 12:23:02 +0200345 absl::optional<bool> allow_codec_switching;
Harald Alvestrand62166932020-10-26 08:30:41 +0000346 absl::optional<int> report_usage_pattern_delay_ms;
Derek Bailey6c127a12021-04-15 12:42:41 -0700347 absl::optional<int> stable_writable_connection_ping_interval_ms;
Jonas Orelandc8fa1ee2021-08-25 08:58:04 +0200348 webrtc::VpnPreference vpn_preference;
Jonas Oreland2ee0e642021-08-25 15:43:02 +0200349 std::vector<rtc::NetworkMask> vpn_list;
Niels Möller73d07742021-12-02 13:58:01 +0100350 PortAllocatorConfig port_allocator_config;
deadbeef293e9262017-01-11 12:28:30 -0800351 };
352 static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
353 "Did you add something to RTCConfiguration and forget to "
354 "update operator==?");
355 return type == o.type && servers == o.servers &&
356 bundle_policy == o.bundle_policy &&
357 rtcp_mux_policy == o.rtcp_mux_policy &&
358 tcp_candidate_policy == o.tcp_candidate_policy &&
359 candidate_network_policy == o.candidate_network_policy &&
360 audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
361 audio_jitter_buffer_fast_accelerate ==
362 o.audio_jitter_buffer_fast_accelerate &&
Jakob Ivarsson10403ae2018-11-27 15:45:20 +0100363 audio_jitter_buffer_min_delay_ms ==
364 o.audio_jitter_buffer_min_delay_ms &&
Jakob Ivarsson53eae872019-01-10 15:58:36 +0100365 audio_jitter_buffer_enable_rtx_handling ==
366 o.audio_jitter_buffer_enable_rtx_handling &&
deadbeef293e9262017-01-11 12:28:30 -0800367 ice_connection_receiving_timeout ==
368 o.ice_connection_receiving_timeout &&
369 ice_backup_candidate_pair_ping_interval ==
370 o.ice_backup_candidate_pair_ping_interval &&
371 continual_gathering_policy == o.continual_gathering_policy &&
372 certificates == o.certificates &&
373 prioritize_most_likely_ice_candidate_pairs ==
374 o.prioritize_most_likely_ice_candidate_pairs &&
375 media_config == o.media_config && disable_ipv6 == o.disable_ipv6 &&
zhihuangb09b3f92017-03-07 14:40:51 -0800376 disable_ipv6_on_wifi == o.disable_ipv6_on_wifi &&
deadbeefd21eab32017-07-26 16:50:11 -0700377 max_ipv6_networks == o.max_ipv6_networks &&
Daniel Lazarenko2870b0a2018-01-25 10:30:22 +0100378 disable_link_local_networks == o.disable_link_local_networks &&
deadbeef293e9262017-01-11 12:28:30 -0800379 screencast_min_bitrate == o.screencast_min_bitrate &&
380 combined_audio_video_bwe == o.combined_audio_video_bwe &&
Harald Alvestrandca327932022-04-04 15:37:31 +0000381#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06 +0000382 enable_dtls_srtp == o.enable_dtls_srtp &&
Harald Alvestrandca327932022-04-04 15:37:31 +0000383#endif
deadbeef293e9262017-01-11 12:28:30 -0800384 ice_candidate_pool_size == o.ice_candidate_pool_size &&
385 prune_turn_ports == o.prune_turn_ports &&
Honghai Zhangf8998cf2019-10-14 11:27:50 -0700386 turn_port_prune_policy == o.turn_port_prune_policy &&
deadbeef293e9262017-01-11 12:28:30 -0800387 presume_writable_when_fully_relayed ==
388 o.presume_writable_when_fully_relayed &&
389 enable_ice_renomination == o.enable_ice_renomination &&
skvlad51072462017-02-02 11:50:14 -0800390 redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
Qingsi Wang1fe119f2019-05-31 16:55:33 -0700391 surface_ice_candidates_on_ice_transport_type_changed ==
392 o.surface_ice_candidates_on_ice_transport_type_changed &&
Qingsi Wange6826d22018-03-08 14:55:14 -0800393 ice_check_interval_strong_connectivity ==
394 o.ice_check_interval_strong_connectivity &&
395 ice_check_interval_weak_connectivity ==
396 o.ice_check_interval_weak_connectivity &&
Steve Anton300bf8e2017-07-14 10:13:10 -0700397 ice_check_min_interval == o.ice_check_min_interval &&
Qingsi Wang22e623a2018-03-13 10:53:57 -0700398 ice_unwritable_timeout == o.ice_unwritable_timeout &&
399 ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
Jiawei Ou9d4fd5552018-12-06 23:30:17 -0800400 ice_inactive_timeout == o.ice_inactive_timeout &&
Qingsi Wangdb53f8e2018-02-20 14:45:49 -0800401 stun_candidate_keepalive_interval ==
402 o.stun_candidate_keepalive_interval &&
Steve Anton79e79602017-11-20 10:25:56 -0800403 turn_customizer == o.turn_customizer &&
Qingsi Wang9a5c6f82018-02-01 10:38:40 -0800404 sdp_semantics == o.sdp_semantics &&
Zhi Huangb57e1692018-06-12 11:41:11 -0700405 network_preference == o.network_preference &&
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700406 active_reset_srtp_params == o.active_reset_srtp_params &&
Johannes Kron89f874e2018-11-12 10:25:48 +0100407 crypto_options == o.crypto_options &&
Jonas Oreland3c028422019-08-22 16:16:35 +0200408 offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
Eldar Rello5ab79e62019-10-09 18:29:44 +0300409 turn_logging_id == o.turn_logging_id &&
philipel16cec3b2019-10-25 12:23:02 +0200410 enable_implicit_rollback == o.enable_implicit_rollback &&
Harald Alvestrand62166932020-10-26 08:30:41 +0000411 allow_codec_switching == o.allow_codec_switching &&
Derek Bailey6c127a12021-04-15 12:42:41 -0700412 report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms &&
413 stable_writable_connection_ping_interval_ms ==
Jonas Orelandc8fa1ee2021-08-25 08:58:04 +0200414 o.stable_writable_connection_ping_interval_ms &&
Niels Möller73d07742021-12-02 13:58:01 +0100415 vpn_preference == o.vpn_preference && vpn_list == o.vpn_list &&
416 port_allocator_config.min_port == o.port_allocator_config.min_port &&
417 port_allocator_config.max_port == o.port_allocator_config.max_port &&
418 port_allocator_config.flags == o.port_allocator_config.flags;
deadbeef293e9262017-01-11 12:28:30 -0800419}
420
421bool PeerConnectionInterface::RTCConfiguration::operator!=(
422 const PeerConnectionInterface::RTCConfiguration& o) const {
423 return !(*this == o);
deadbeef3edec7c2016-12-10 11:44:26 -0800424}
425
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000426RTCErrorOr<rtc::scoped_refptr<PeerConnection>> PeerConnection::Create(
Harald Alvestrand62166932020-10-26 08:30:41 +0000427 rtc::scoped_refptr<ConnectionContext> context,
Harald Alvestrand4da4a872020-11-04 10:34:21 +0000428 const PeerConnectionFactoryInterface::Options& options,
Harald Alvestrand62166932020-10-26 08:30:41 +0000429 std::unique_ptr<RtcEventLog> event_log,
430 std::unique_ptr<Call> call,
431 const PeerConnectionInterface::RTCConfiguration& configuration,
432 PeerConnectionDependencies dependencies) {
Henrik Boström62995db2022-01-03 09:58:10 +0100433 // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
Henrik Boström6d2fe892022-01-21 09:51:07 +0100434 if (configuration.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
435 RTC_LOG(LS_WARNING)
436 << "PeerConnection constructed with legacy SDP semantics!";
437 }
Henrik Boström62995db2022-01-03 09:58:10 +0100438
Harald Alvestrand62166932020-10-26 08:30:41 +0000439 RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
440 ParseIceConfig(configuration));
441 if (!config_error.ok()) {
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000442 RTC_LOG(LS_ERROR) << "Invalid ICE configuration: "
443 << config_error.message();
444 return config_error;
Harald Alvestrand62166932020-10-26 08:30:41 +0000445 }
446
447 if (!dependencies.allocator) {
448 RTC_LOG(LS_ERROR)
449 << "PeerConnection initialized without a PortAllocator? "
450 "This shouldn't happen if using PeerConnectionFactory.";
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000451 return RTCError(
452 RTCErrorType::INVALID_PARAMETER,
453 "Attempt to create a PeerConnection without a PortAllocatorFactory");
Harald Alvestrand62166932020-10-26 08:30:41 +0000454 }
455
456 if (!dependencies.observer) {
457 // TODO(deadbeef): Why do we do this?
458 RTC_LOG(LS_ERROR) << "PeerConnection initialized without a "
459 "PeerConnectionObserver";
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000460 return RTCError(RTCErrorType::INVALID_PARAMETER,
461 "Attempt to create a PeerConnection without an observer");
Harald Alvestrand62166932020-10-26 08:30:41 +0000462 }
463
464 bool is_unified_plan =
465 configuration.sdp_semantics == SdpSemantics::kUnifiedPlan;
Tommic3257d02021-02-10 17:40:08 +0000466 bool dtls_enabled = DtlsEnabled(configuration, options, dependencies);
Harald Alvestrand0ccfbd22021-04-08 07:25:04 +0000467
468 // Interim code: If an AsyncResolverFactory is given, but not an
469 // AsyncDnsResolverFactory, wrap it in a WrappingAsyncDnsResolverFactory
470 // If neither is given, create a WrappingAsyncDnsResolverFactory wrapping
471 // a BasicAsyncResolver.
472 // TODO(bugs.webrtc.org/12598): Remove code once all callers pass a
473 // AsyncDnsResolverFactory.
474 if (dependencies.async_dns_resolver_factory &&
475 dependencies.async_resolver_factory) {
476 RTC_LOG(LS_ERROR)
477 << "Attempt to set both old and new type of DNS resolver factory";
478 return RTCError(RTCErrorType::INVALID_PARAMETER,
479 "Both old and new type of DNS resolver given");
480 }
481 if (dependencies.async_resolver_factory) {
482 dependencies.async_dns_resolver_factory =
483 std::make_unique<WrappingAsyncDnsResolverFactory>(
484 std::move(dependencies.async_resolver_factory));
485 } else {
486 dependencies.async_dns_resolver_factory =
487 std::make_unique<WrappingAsyncDnsResolverFactory>(
488 std::make_unique<BasicAsyncResolverFactory>());
489 }
490
Harald Alvestrandfd9a8f82020-10-26 14:17:02 +0000491 // The PeerConnection constructor consumes some, but not all, dependencies.
Tommi87f70902021-04-27 14:43:08 +0200492 auto pc = rtc::make_ref_counted<PeerConnection>(
493 context, options, is_unified_plan, std::move(event_log), std::move(call),
494 dependencies, dtls_enabled);
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000495 RTCError init_error = pc->Initialize(configuration, std::move(dependencies));
496 if (!init_error.ok()) {
497 RTC_LOG(LS_ERROR) << "PeerConnection initialization failed";
498 return init_error;
Harald Alvestrand62166932020-10-26 08:30:41 +0000499 }
500 return pc;
501}
502
Harald Alvestrand4da4a872020-11-04 10:34:21 +0000503PeerConnection::PeerConnection(
504 rtc::scoped_refptr<ConnectionContext> context,
505 const PeerConnectionFactoryInterface::Options& options,
506 bool is_unified_plan,
507 std::unique_ptr<RtcEventLog> event_log,
508 std::unique_ptr<Call> call,
Tommic3257d02021-02-10 17:40:08 +0000509 PeerConnectionDependencies& dependencies,
510 bool dtls_enabled)
Harald Alvestranda39689c2020-10-15 08:34:31 +0000511 : context_(context),
Jonas Oreland6c7f9842022-04-19 17:24:10 +0200512 trials_(std::move(dependencies.trials), &context->field_trials()),
Harald Alvestrand4da4a872020-11-04 10:34:21 +0000513 options_(options),
Harald Alvestrandfd9a8f82020-10-26 14:17:02 +0000514 observer_(dependencies.observer),
Harald Alvestrand62166932020-10-26 08:30:41 +0000515 is_unified_plan_(is_unified_plan),
zhihuang38ede132017-06-15 12:52:32 -0700516 event_log_(std::move(event_log)),
Karl Wibergb03ab712019-02-14 11:59:57 +0100517 event_log_ptr_(event_log_.get()),
Harald Alvestrand0ccfbd22021-04-08 07:25:04 +0000518 async_dns_resolver_factory_(
519 std::move(dependencies.async_dns_resolver_factory)),
Harald Alvestrandfd9a8f82020-10-26 14:17:02 +0000520 port_allocator_(std::move(dependencies.allocator)),
521 ice_transport_factory_(std::move(dependencies.ice_transport_factory)),
522 tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
Karl Wiberg6cab5c82019-03-26 09:57:01 +0100523 call_(std::move(call)),
Henrik Boström79b69802019-07-18 11:16:56 +0200524 call_ptr_(call_.get()),
Tomas Gunnarsson97a387d2021-03-29 21:04:29 +0200525 // RFC 3264: The numeric value of the session id and version in the
526 // o line MUST be representable with a "64 bit signed integer".
Artem Titov880fa812021-07-30 22:30:23 +0200527 // Due to this constraint session id `session_id_` is max limited to
Tomas Gunnarsson97a387d2021-03-29 21:04:29 +0200528 // LLONG_MAX.
529 session_id_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
Tommic3257d02021-02-10 17:40:08 +0000530 dtls_enabled_(dtls_enabled),
Harald Alvestrand1090e442020-10-05 07:01:09 +0000531 data_channel_controller_(this),
Lahiru Ginnaliya Gamathige70f9e242021-01-27 23:32:46 -0800532 message_handler_(signaling_thread()),
Tommic3257d02021-02-10 17:40:08 +0000533 weak_factory_(this) {
534 worker_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
535 RTC_DCHECK_RUN_ON(worker_thread());
536 worker_thread_safety_ = PendingTaskSafetyFlag::Create();
537 if (!call_)
538 worker_thread_safety_->SetNotAlive();
539 });
540}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000541
542PeerConnection::~PeerConnection() {
Peter Boström1a9d6152015-12-08 22:15:17 +0100543 TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
Steve Anton4171afb2017-11-20 10:20:22 -0800544 RTC_DCHECK_RUN_ON(signaling_thread());
545
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000546 if (sdp_handler_) {
547 sdp_handler_->PrepareForShutdown();
548 }
Henrik Boströma3728d32019-10-28 12:09:49 +0100549
Steve Anton8af21862017-12-15 11:20:13 -0800550 // Need to stop transceivers before destroying the stats collector because
551 // AudioRtpSender has a reference to the StatsCollector it will update when
552 // stopping.
Harald Alvestrande15fb152020-10-19 13:28:05 +0000553 if (rtp_manager()) {
554 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
555 transceiver->StopInternal();
556 }
Steve Anton8af21862017-12-15 11:20:13 -0800557 }
Steve Anton4171afb2017-11-20 10:20:22 -0800558
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700559 stats_.reset(nullptr);
hbosb78306a2016-12-19 05:06:57 -0800560 if (stats_collector_) {
561 stats_collector_->WaitForPendingRequest();
562 stats_collector_ = nullptr;
563 }
Steve Anton75737c02017-11-06 10:37:17 -0800564
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000565 if (sdp_handler_) {
566 // Don't destroy BaseChannels until after stats has been cleaned up so that
567 // the last stats request can still read from the channels.
568 sdp_handler_->DestroyAllChannels();
Steve Anton8af21862017-12-15 11:20:13 -0800569
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000570 RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
Steve Anton75737c02017-11-06 10:37:17 -0800571
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000572 sdp_handler_->ResetSessionDescFactory();
573 }
Steve Anton75737c02017-11-06 10:37:17 -0800574
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +0100575 // port_allocator_ and transport_controller_ live on the network thread and
576 // should be destroyed there.
Harald Alvestrandbc32c562022-02-09 12:08:47 +0000577 transport_controller_copy_ = nullptr;
Karl Wibergfb3be392019-03-22 14:13:22 +0100578 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
579 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarssond69e0702021-04-07 15:14:43 +0200580 TeardownDataChannelTransport_n();
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +0100581 transport_controller_.reset();
Karl Wibergfb3be392019-03-22 14:13:22 +0100582 port_allocator_.reset();
Tommic3257d02021-02-10 17:40:08 +0000583 if (network_thread_safety_)
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +0100584 network_thread_safety_->SetNotAlive();
Karl Wibergfb3be392019-03-22 14:13:22 +0100585 });
Tomas Gunnarssond69e0702021-04-07 15:14:43 +0200586
eladalon248fd4f2017-09-06 05:18:15 -0700587 // call_ and event_log_ must be destroyed on the worker thread.
Steve Anton978b8762017-09-29 12:15:02 -0700588 worker_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
Karl Wibergb03ab712019-02-14 11:59:57 +0100589 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:08 +0000590 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 05:18:15 -0700591 call_.reset();
Qingsi Wang93a84392018-01-30 17:13:09 -0800592 // The event log must outlive call (and any other object that uses it).
eladalon248fd4f2017-09-06 05:18:15 -0700593 event_log_.reset();
594 });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595}
596
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000597RTCError PeerConnection::Initialize(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000598 const PeerConnectionInterface::RTCConfiguration& configuration,
Benjamin Wrightcab58882018-05-02 15:12:47 -0700599 PeerConnectionDependencies dependencies) {
Karl Wiberg744310f2019-02-14 10:18:56 +0100600 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 22:15:17 +0100601 TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
Steve Anton038834f2017-07-14 15:59:59 -0700602
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200603 cricket::ServerAddresses stun_servers;
604 std::vector<cricket::RelayServerConfig> turn_servers;
605
606 RTCErrorType parse_error =
607 ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
608 if (parse_error != RTCErrorType::NONE) {
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000609 return RTCError(parse_error, "ICE server parse failed");
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200610 }
611
Jonas Oreland3c028422019-08-22 16:16:35 +0200612 // Add the turn logging id to all turn servers
613 for (cricket::RelayServerConfig& turn_server : turn_servers) {
614 turn_server.turn_logging_id = configuration.turn_logging_id;
615 }
616
Harald Alvestrandfd9a8f82020-10-26 14:17:02 +0000617 // Note if STUN or TURN servers were supplied.
Harald Alvestrandb2a74782018-06-28 13:54:07 +0200618 if (!stun_servers.empty()) {
619 NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
620 }
621 if (!turn_servers.empty()) {
622 NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
623 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000624
Tommic3257d02021-02-10 17:40:08 +0000625 // Network thread initialization.
Harald Alvestrandbc32c562022-02-09 12:08:47 +0000626 transport_controller_copy_ =
627 network_thread()->Invoke<JsepTransportController*>(RTC_FROM_HERE, [&] {
628 RTC_DCHECK_RUN_ON(network_thread());
629 network_thread_safety_ = PendingTaskSafetyFlag::Create();
630 InitializePortAllocatorResult pa_result = InitializePortAllocator_n(
631 stun_servers, turn_servers, configuration);
632 // Send information about IPv4/IPv6 status.
633 PeerConnectionAddressFamilyCounter address_family =
634 pa_result.enable_ipv6 ? kPeerConnection_IPv6 : kPeerConnection_IPv4;
635 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
636 address_family,
637 kPeerConnectionAddressFamilyCounter_Max);
638 return InitializeTransportController_n(configuration, dependencies);
639 });
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 14:33:45 -0700640
Steve Antonba818672017-11-06 10:21:57 -0800641 configuration_ = configuration;
642
Harald Alvestrande15fb152020-10-19 13:28:05 +0000643 stats_ = std::make_unique<StatsCollector>(this);
644 stats_collector_ = RTCStatsCollector::Create(this);
645
Harald Alvestrand66c40362022-01-28 17:41:30 +0000646 sdp_handler_ = SdpOfferAnswerHandler::Create(this, configuration,
Niels Möllerafb246b2022-04-20 14:26:50 +0200647 dependencies, context_.get());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000648
Harald Alvestrande15fb152020-10-19 13:28:05 +0000649 rtp_manager_ = std::make_unique<RtpTransmissionManager>(
650 IsUnifiedPlan(), signaling_thread(), worker_thread(), channel_manager(),
651 &usage_pattern_, observer_, stats_.get(), [this]() {
652 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000653 sdp_handler_->UpdateNegotiationNeeded();
Harald Alvestrande15fb152020-10-19 13:28:05 +0000654 });
655
Steve Anton4171afb2017-11-20 10:20:22 -0800656 // Add default audio/video transceivers for Plan B SDP.
657 if (!IsUnifiedPlan()) {
Harald Alvestrande15fb152020-10-19 13:28:05 +0000658 rtp_manager()->transceivers()->Add(
659 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Tommi99c8a802021-04-27 15:00:00 +0200660 signaling_thread(),
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100661 rtc::make_ref_counted<RtpTransceiver>(cricket::MEDIA_TYPE_AUDIO,
662 channel_manager())));
Harald Alvestrande15fb152020-10-19 13:28:05 +0000663 rtp_manager()->transceivers()->Add(
664 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Tommi99c8a802021-04-27 15:00:00 +0200665 signaling_thread(),
Tomas Gunnarsson0d5ce622022-03-18 15:57:15 +0100666 rtc::make_ref_counted<RtpTransceiver>(cricket::MEDIA_TYPE_VIDEO,
667 channel_manager())));
Steve Anton4171afb2017-11-20 10:20:22 -0800668 }
Harald Alvestrand763f5a92020-10-22 10:39:40 +0000669
Harald Alvestrand62166932020-10-26 08:30:41 +0000670 int delay_ms = configuration.report_usage_pattern_delay_ms
671 ? *configuration.report_usage_pattern_delay_ms
672 : REPORT_USAGE_PATTERN_DELAY_MS;
Harald Alvestrand1090e442020-10-05 07:01:09 +0000673 message_handler_.RequestUsagePatternReport(
674 [this]() {
675 RTC_DCHECK_RUN_ON(signaling_thread());
676 ReportUsagePattern();
677 },
678 delay_ms);
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200679
Philipp Hanckef59d9fb2021-10-13 11:34:15 +0200680 // Record the number of configured ICE servers for all connections.
681 RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.PeerConnection.IceServers.Configured",
682 configuration_.servers.size(), 0, 31, 32);
683
Harald Alvestranda3dd7722020-11-27 08:05:42 +0000684 return RTCError::OK();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000685}
686
Harald Alvestrandbc32c562022-02-09 12:08:47 +0000687JsepTransportController* PeerConnection::InitializeTransportController_n(
Tommic3257d02021-02-10 17:40:08 +0000688 const RTCConfiguration& configuration,
689 const PeerConnectionDependencies& dependencies) {
690 JsepTransportController::Config config;
691 config.redetermine_role_on_ice_restart =
692 configuration.redetermine_role_on_ice_restart;
693 config.ssl_max_version = options_.ssl_max_version;
694 config.disable_encryption = options_.disable_encryption;
695 config.bundle_policy = configuration.bundle_policy;
696 config.rtcp_mux_policy = configuration.rtcp_mux_policy;
697 // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove
698 // this stub.
699 config.crypto_options = configuration.crypto_options.has_value()
700 ? *configuration.crypto_options
701 : options_.crypto_options;
702 config.transport_observer = this;
703 config.rtcp_handler = InitializeRtcpCallback();
704 config.event_log = event_log_ptr_;
705#if defined(ENABLE_EXTERNAL_AUTH)
706 config.enable_external_auth = true;
707#endif
708 config.active_reset_srtp_params = configuration.active_reset_srtp_params;
709
710 // DTLS has to be enabled to use SCTP.
Florent Castelli516e2842021-04-19 15:29:50 +0200711 if (dtls_enabled_) {
Tommic3257d02021-02-10 17:40:08 +0000712 config.sctp_factory = context_->sctp_transport_factory();
713 }
714
715 config.ice_transport_factory = ice_transport_factory_.get();
716 config.on_dtls_handshake_error_ =
717 [weak_ptr = weak_factory_.GetWeakPtr()](rtc::SSLHandshakeError s) {
718 if (weak_ptr) {
719 weak_ptr->OnTransportControllerDtlsHandshakeError(s);
720 }
721 };
722
Jonas Oreland6c7f9842022-04-19 17:24:10 +0200723 config.field_trials = trials_.get();
Jonas Orelanded99dae2022-03-09 09:28:10 +0100724
Tommic3257d02021-02-10 17:40:08 +0000725 transport_controller_.reset(
726 new JsepTransportController(network_thread(), port_allocator_.get(),
Harald Alvestrand0ccfbd22021-04-08 07:25:04 +0000727 async_dns_resolver_factory_.get(), config));
Tommic3257d02021-02-10 17:40:08 +0000728
729 transport_controller_->SubscribeIceConnectionState(
730 [this](cricket::IceConnectionState s) {
731 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson2001dc32021-04-06 11:36:00 +0200732 if (s == cricket::kIceConnectionConnected) {
733 ReportTransportStats();
734 }
Tommic3257d02021-02-10 17:40:08 +0000735 signaling_thread()->PostTask(
736 ToQueuedTask(signaling_thread_safety_.flag(), [this, s]() {
737 RTC_DCHECK_RUN_ON(signaling_thread());
738 OnTransportControllerConnectionState(s);
739 }));
740 });
741 transport_controller_->SubscribeConnectionState(
742 [this](PeerConnectionInterface::PeerConnectionState s) {
743 RTC_DCHECK_RUN_ON(network_thread());
744 signaling_thread()->PostTask(
745 ToQueuedTask(signaling_thread_safety_.flag(), [this, s]() {
746 RTC_DCHECK_RUN_ON(signaling_thread());
747 SetConnectionState(s);
748 }));
749 });
750 transport_controller_->SubscribeStandardizedIceConnectionState(
751 [this](PeerConnectionInterface::IceConnectionState s) {
752 RTC_DCHECK_RUN_ON(network_thread());
753 signaling_thread()->PostTask(
754 ToQueuedTask(signaling_thread_safety_.flag(), [this, s]() {
755 RTC_DCHECK_RUN_ON(signaling_thread());
756 SetStandardizedIceConnectionState(s);
757 }));
758 });
759 transport_controller_->SubscribeIceGatheringState(
760 [this](cricket::IceGatheringState s) {
761 RTC_DCHECK_RUN_ON(network_thread());
762 signaling_thread()->PostTask(
763 ToQueuedTask(signaling_thread_safety_.flag(), [this, s]() {
764 RTC_DCHECK_RUN_ON(signaling_thread());
765 OnTransportControllerGatheringState(s);
766 }));
767 });
768 transport_controller_->SubscribeIceCandidateGathered(
769 [this](const std::string& transport,
770 const std::vector<cricket::Candidate>& candidates) {
771 RTC_DCHECK_RUN_ON(network_thread());
772 signaling_thread()->PostTask(
773 ToQueuedTask(signaling_thread_safety_.flag(),
774 [this, t = transport, c = candidates]() {
775 RTC_DCHECK_RUN_ON(signaling_thread());
776 OnTransportControllerCandidatesGathered(t, c);
777 }));
778 });
779 transport_controller_->SubscribeIceCandidateError(
780 [this](const cricket::IceCandidateErrorEvent& event) {
781 RTC_DCHECK_RUN_ON(network_thread());
782 signaling_thread()->PostTask(ToQueuedTask(
783 signaling_thread_safety_.flag(), [this, event = event]() {
784 RTC_DCHECK_RUN_ON(signaling_thread());
785 OnTransportControllerCandidateError(event);
786 }));
787 });
788 transport_controller_->SubscribeIceCandidatesRemoved(
789 [this](const std::vector<cricket::Candidate>& c) {
790 RTC_DCHECK_RUN_ON(network_thread());
791 signaling_thread()->PostTask(
792 ToQueuedTask(signaling_thread_safety_.flag(), [this, c = c]() {
793 RTC_DCHECK_RUN_ON(signaling_thread());
794 OnTransportControllerCandidatesRemoved(c);
795 }));
796 });
797 transport_controller_->SubscribeIceCandidatePairChanged(
798 [this](const cricket::CandidatePairChangeEvent& event) {
799 RTC_DCHECK_RUN_ON(network_thread());
800 signaling_thread()->PostTask(ToQueuedTask(
801 signaling_thread_safety_.flag(), [this, event = event]() {
802 RTC_DCHECK_RUN_ON(signaling_thread());
803 OnTransportControllerCandidateChanged(event);
804 }));
805 });
806
807 transport_controller_->SetIceConfig(ParseIceConfig(configuration));
Harald Alvestrandbc32c562022-02-09 12:08:47 +0000808 return transport_controller_.get();
Tommic3257d02021-02-10 17:40:08 +0000809}
810
Yves Gerey665174f2018-06-19 15:03:05 +0200811rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::local_streams() {
Karl Wiberg5966c502019-02-21 23:55:09 +0100812 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 13:48:58 -0800813 RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
814 "Plan SdpSemantics. Please use GetSenders "
815 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000816 return sdp_handler_->local_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000817}
818
Yves Gerey665174f2018-06-19 15:03:05 +0200819rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
Karl Wiberg5966c502019-02-21 23:55:09 +0100820 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 13:48:58 -0800821 RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
822 "Plan SdpSemantics. Please use GetReceivers "
823 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000824 return sdp_handler_->remote_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825}
826
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29 +0000827bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 10:18:56 +0100828 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 13:48:58 -0800829 RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
830 "SdpSemantics. Please use AddTrack instead.";
Peter Boström1a9d6152015-12-08 22:15:17 +0100831 TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
Harald Alvestrand35ba0c52022-05-05 07:37:41 +0000832 if (!ConfiguredForMedia()) {
833 RTC_LOG(LS_ERROR) << "AddStream: Not configured for media";
834 return false;
835 }
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000836 return sdp_handler_->AddStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000837}
838
839void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 10:18:56 +0100840 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41 +0000841 RTC_DCHECK(ConfiguredForMedia());
Steve Antonfc853712018-03-01 13:48:58 -0800842 RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified "
843 "Plan SdpSemantics. Please use RemoveTrack "
844 "instead.";
Peter Boström1a9d6152015-12-08 22:15:17 +0100845 TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000846 sdp_handler_->RemoveStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000847}
848
Steve Anton2d6c76a2018-01-05 17:10:52 -0800849RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
Steve Antonf9381f02017-12-14 10:23:57 -0800850 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800851 const std::vector<std::string>& stream_ids) {
Karl Wiberg744310f2019-02-14 10:18:56 +0100852 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton2d6c76a2018-01-05 17:10:52 -0800853 TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
Harald Alvestrand35ba0c52022-05-05 07:37:41 +0000854 if (!ConfiguredForMedia()) {
855 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
856 "Not configured for media");
857 }
Steve Antonf9381f02017-12-14 10:23:57 -0800858 if (!track) {
859 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Track is null.");
860 }
861 if (!(track->kind() == MediaStreamTrackInterface::kAudioKind ||
862 track->kind() == MediaStreamTrackInterface::kVideoKind)) {
863 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
864 "Track has invalid kind: " + track->kind());
865 }
Steve Antonf9381f02017-12-14 10:23:57 -0800866 if (IsClosed()) {
867 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
868 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 15:35:42 -0800869 }
Niels Möllerafb246b2022-04-20 14:26:50 +0200870 if (rtp_manager()->FindSenderForTrack(track.get())) {
Steve Antonf9381f02017-12-14 10:23:57 -0800871 LOG_AND_RETURN_ERROR(
872 RTCErrorType::INVALID_PARAMETER,
873 "Sender already exists for track " + track->id() + ".");
deadbeefe1f9d832016-01-14 15:35:42 -0800874 }
Harald Alvestrande15fb152020-10-19 13:28:05 +0000875 auto sender_or_error = rtp_manager()->AddTrack(track, stream_ids);
Steve Antonf9381f02017-12-14 10:23:57 -0800876 if (sender_or_error.ok()) {
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000877 sdp_handler_->UpdateNegotiationNeeded();
Niels Möllerafb246b2022-04-20 14:26:50 +0200878 stats_->AddTrack(track.get());
Steve Antonf9381f02017-12-14 10:23:57 -0800879 }
880 return sender_or_error;
881}
deadbeefe1f9d832016-01-14 15:35:42 -0800882
Harald Alvestrand09a0d012022-01-04 19:42:07 +0000883RTCError PeerConnection::RemoveTrackOrError(
Steve Antonf9381f02017-12-14 10:23:57 -0800884 rtc::scoped_refptr<RtpSenderInterface> sender) {
Karl Wiberg744310f2019-02-14 10:18:56 +0100885 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41 +0000886 if (!ConfiguredForMedia()) {
887 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
888 "Not configured for media");
889 }
Steve Antonf9381f02017-12-14 10:23:57 -0800890 if (!sender) {
891 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Sender is null.");
892 }
deadbeefe1f9d832016-01-14 15:35:42 -0800893 if (IsClosed()) {
Steve Antonf9381f02017-12-14 10:23:57 -0800894 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
895 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 15:35:42 -0800896 }
Steve Antonf9381f02017-12-14 10:23:57 -0800897 if (IsUnifiedPlan()) {
898 auto transceiver = FindTransceiverBySender(sender);
899 if (!transceiver || !sender->track()) {
900 return RTCError::OK();
901 }
902 sender->SetTrack(nullptr);
903 if (transceiver->direction() == RtpTransceiverDirection::kSendRecv) {
Steve Anton52d86772018-02-20 15:48:12 -0800904 transceiver->internal()->set_direction(
905 RtpTransceiverDirection::kRecvOnly);
Steve Antonf9381f02017-12-14 10:23:57 -0800906 } else if (transceiver->direction() == RtpTransceiverDirection::kSendOnly) {
Steve Anton52d86772018-02-20 15:48:12 -0800907 transceiver->internal()->set_direction(
908 RtpTransceiverDirection::kInactive);
Steve Antonf9381f02017-12-14 10:23:57 -0800909 }
Steve Anton4171afb2017-11-20 10:20:22 -0800910 } else {
Steve Antonf9381f02017-12-14 10:23:57 -0800911 bool removed;
912 if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
Harald Alvestrande15fb152020-10-19 13:28:05 +0000913 removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 14:26:50 +0200914 sender.get());
Steve Antonf9381f02017-12-14 10:23:57 -0800915 } else {
916 RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
Harald Alvestrande15fb152020-10-19 13:28:05 +0000917 removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 14:26:50 +0200918 sender.get());
Steve Antonf9381f02017-12-14 10:23:57 -0800919 }
920 if (!removed) {
921 LOG_AND_RETURN_ERROR(
922 RTCErrorType::INVALID_PARAMETER,
923 "Couldn't find sender " + sender->id() + " to remove.");
924 }
Steve Anton4171afb2017-11-20 10:20:22 -0800925 }
Harald Alvestrand9cd199d2020-10-27 07:10:43 +0000926 sdp_handler_->UpdateNegotiationNeeded();
Steve Antonf9381f02017-12-14 10:23:57 -0800927 return RTCError::OK();
928}
929
930rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
931PeerConnection::FindTransceiverBySender(
932 rtc::scoped_refptr<RtpSenderInterface> sender) {
Harald Alvestrande15fb152020-10-19 13:28:05 +0000933 return rtp_manager()->transceivers()->FindBySender(sender);
deadbeefe1f9d832016-01-14 15:35:42 -0800934}
935
Steve Anton9158ef62017-11-27 13:01:52 -0800936RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
937PeerConnection::AddTransceiver(
938 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
Harald Alvestrand35ba0c52022-05-05 07:37:41 +0000939 if (!ConfiguredForMedia()) {
940 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
941 "Not configured for media");
942 }
943
Steve Anton9158ef62017-11-27 13:01:52 -0800944 return AddTransceiver(track, RtpTransceiverInit());
945}
946
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +0100947RtpTransportInternal* PeerConnection::GetRtpTransport(const std::string& mid) {
Harald Alvestrandbc32c562022-02-09 12:08:47 +0000948 // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
949 // This might be done by caching the value on the signaling thread.
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +0100950 RTC_DCHECK_RUN_ON(signaling_thread());
951 return network_thread()->Invoke<RtpTransportInternal*>(
952 RTC_FROM_HERE, [this, &mid] {
Harald Alvestrandbc32c562022-02-09 12:08:47 +0000953 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +0100954 auto rtp_transport = transport_controller_->GetRtpTransport(mid);
955 RTC_DCHECK(rtp_transport);
956 return rtp_transport;
957 });
958}
959
Steve Anton9158ef62017-11-27 13:01:52 -0800960RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
961PeerConnection::AddTransceiver(
962 rtc::scoped_refptr<MediaStreamTrackInterface> track,
963 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 10:18:56 +0100964 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41 +0000965 if (!ConfiguredForMedia()) {
966 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
967 "Not configured for media");
968 }
Steve Antonfc853712018-03-01 13:48:58 -0800969 RTC_CHECK(IsUnifiedPlan())
970 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 13:01:52 -0800971 if (!track) {
972 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "track is null");
973 }
974 cricket::MediaType media_type;
975 if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
976 media_type = cricket::MEDIA_TYPE_AUDIO;
977 } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
978 media_type = cricket::MEDIA_TYPE_VIDEO;
979 } else {
980 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
981 "Track kind is not audio or video");
982 }
983 return AddTransceiver(media_type, track, init);
984}
985
986RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
987PeerConnection::AddTransceiver(cricket::MediaType media_type) {
988 return AddTransceiver(media_type, RtpTransceiverInit());
989}
990
991RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
992PeerConnection::AddTransceiver(cricket::MediaType media_type,
993 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 10:18:56 +0100994 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41 +0000995 if (!ConfiguredForMedia()) {
996 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
997 "Not configured for media");
998 }
Steve Antonfc853712018-03-01 13:48:58 -0800999 RTC_CHECK(IsUnifiedPlan())
1000 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 13:01:52 -08001001 if (!(media_type == cricket::MEDIA_TYPE_AUDIO ||
1002 media_type == cricket::MEDIA_TYPE_VIDEO)) {
1003 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1004 "media type is not audio or video");
1005 }
1006 return AddTransceiver(media_type, nullptr, init);
1007}
1008
1009RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1010PeerConnection::AddTransceiver(
1011 cricket::MediaType media_type,
1012 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Steve Anton22da89f2018-01-25 13:58:07 -08001013 const RtpTransceiverInit& init,
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001014 bool update_negotiation_needed) {
Harald Alvestranda474fbf2020-10-01 16:47:23 +00001015 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00001016 if (!ConfiguredForMedia()) {
1017 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1018 "Not configured for media");
1019 }
Steve Anton9158ef62017-11-27 13:01:52 -08001020 RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
1021 media_type == cricket::MEDIA_TYPE_VIDEO));
1022 if (track) {
1023 RTC_DCHECK_EQ(media_type,
1024 (track->kind() == MediaStreamTrackInterface::kAudioKind
1025 ? cricket::MEDIA_TYPE_AUDIO
1026 : cricket::MEDIA_TYPE_VIDEO));
1027 }
1028
Amit Hilbuche2a284d2019-03-05 12:36:31 -08001029 RTC_HISTOGRAM_COUNTS_LINEAR(kSimulcastNumberOfEncodings,
1030 init.send_encodings.size(), 0, 7, 8);
1031
Amit Hilbuchaa584152019-02-06 17:09:52 -08001032 size_t num_rids = absl::c_count_if(init.send_encodings,
1033 [](const RtpEncodingParameters& encoding) {
1034 return !encoding.rid.empty();
1035 });
1036 if (num_rids > 0 && num_rids != init.send_encodings.size()) {
Amit Hilbuchce470aa2019-02-06 17:09:52 -08001037 LOG_AND_RETURN_ERROR(
Amit Hilbuchaa584152019-02-06 17:09:52 -08001038 RTCErrorType::INVALID_PARAMETER,
1039 "RIDs must be provided for either all or none of the send encodings.");
Emircan Uysaler78323432019-02-08 20:41:39 +00001040 }
1041
Amit Hilbuchf4770402019-04-08 14:11:57 -07001042 if (num_rids > 0 && absl::c_any_of(init.send_encodings,
1043 [](const RtpEncodingParameters& encoding) {
1044 return !IsLegalRsidName(encoding.rid);
1045 })) {
1046 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1047 "Invalid RID value provided.");
1048 }
1049
Amit Hilbuchaa584152019-02-06 17:09:52 -08001050 if (absl::c_any_of(init.send_encodings,
1051 [](const RtpEncodingParameters& encoding) {
1052 return encoding.ssrc.has_value();
1053 })) {
1054 LOG_AND_RETURN_ERROR(
1055 RTCErrorType::UNSUPPORTED_PARAMETER,
1056 "Attempted to set an unimplemented parameter of RtpParameters.");
Florent Castelli892acf02018-10-01 22:47:20 +02001057 }
1058
1059 RtpParameters parameters;
1060 parameters.encodings = init.send_encodings;
Amit Hilbuchaa584152019-02-06 17:09:52 -08001061
1062 // Encodings are dropped from the tail if too many are provided.
Florent Castellie1b685a2021-04-30 19:11:37 +02001063 size_t max_simulcast_streams =
1064 media_type == cricket::MEDIA_TYPE_VIDEO ? kMaxSimulcastStreams : 1u;
1065 if (parameters.encodings.size() > max_simulcast_streams) {
Amit Hilbuchaa584152019-02-06 17:09:52 -08001066 parameters.encodings.erase(
Florent Castellie1b685a2021-04-30 19:11:37 +02001067 parameters.encodings.begin() + max_simulcast_streams,
Amit Hilbuchaa584152019-02-06 17:09:52 -08001068 parameters.encodings.end());
1069 }
1070
1071 // Single RID should be removed.
1072 if (parameters.encodings.size() == 1 &&
1073 !parameters.encodings[0].rid.empty()) {
1074 RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
1075 parameters.encodings[0].rid.clear();
1076 }
1077
1078 // If RIDs were not provided, they are generated for simulcast scenario.
1079 if (parameters.encodings.size() > 1 && num_rids == 0) {
1080 rtc::UniqueStringGenerator rid_generator;
1081 for (RtpEncodingParameters& encoding : parameters.encodings) {
1082 encoding.rid = rid_generator();
1083 }
1084 }
1085
Florent Castelli892acf02018-10-01 22:47:20 +02001086 if (UnimplementedRtpParameterHasValue(parameters)) {
1087 LOG_AND_RETURN_ERROR(
1088 RTCErrorType::UNSUPPORTED_PARAMETER,
1089 "Attempted to set an unimplemented parameter of RtpParameters.");
1090 }
Steve Anton9158ef62017-11-27 13:01:52 -08001091
Florent Castellic1a0bcb2019-01-29 14:26:48 +01001092 auto result = cricket::CheckRtpParametersValues(parameters);
1093 if (!result.ok()) {
1094 LOG_AND_RETURN_ERROR(result.type(), result.message());
1095 }
1096
Steve Anton3d954a62018-04-02 11:27:23 -07001097 RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
1098 << " transceiver in response to a call to AddTransceiver.";
Steve Anton07563732018-06-26 11:13:50 -07001099 // Set the sender ID equal to the track ID if the track is specified unless
1100 // that sender ID is already in use.
Harald Alvestrande15fb152020-10-19 13:28:05 +00001101 std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
1102 ? track->id()
1103 : rtc::CreateRandomUuid());
1104 auto sender = rtp_manager()->CreateSender(
1105 media_type, sender_id, track, init.stream_ids, parameters.encodings);
1106 auto receiver =
1107 rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
1108 auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
Steve Anton02ee47c2018-01-10 16:26:06 -08001109 transceiver->internal()->set_direction(init.direction);
1110
Guido Urdaneta70c2db12019-04-16 12:24:14 +02001111 if (update_negotiation_needed) {
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001112 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton22da89f2018-01-25 13:58:07 -08001113 }
Steve Antonf9381f02017-12-14 10:23:57 -08001114
1115 return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
1116}
1117
Steve Anton52d86772018-02-20 15:48:12 -08001118void PeerConnection::OnNegotiationNeeded() {
1119 RTC_DCHECK_RUN_ON(signaling_thread());
1120 RTC_DCHECK(!IsClosed());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001121 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton52d86772018-02-20 15:48:12 -08001122}
1123
deadbeeffac06552015-11-25 11:26:01 -08001124rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
deadbeefbd7d8f72015-12-18 16:58:44 -08001125 const std::string& kind,
1126 const std::string& stream_id) {
Karl Wiberg5966c502019-02-21 23:55:09 +01001127 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00001128 if (!ConfiguredForMedia()) {
1129 RTC_LOG(LS_ERROR) << "Not configured for media";
1130 return nullptr;
1131 }
Steve Antonfc853712018-03-01 13:48:58 -08001132 RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified "
1133 "Plan SdpSemantics. Please use AddTransceiver "
1134 "instead.";
Peter Boström1a9d6152015-12-08 22:15:17 +01001135 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
zhihuang29ff8442016-07-27 11:07:25 -07001136 if (IsClosed()) {
1137 return nullptr;
1138 }
Steve Anton4171afb2017-11-20 10:20:22 -08001139
Seth Hampson5b4f0752018-04-02 16:31:36 -07001140 // Internally we need to have one stream with Plan B semantics, so we
1141 // generate a random stream ID if not specified.
Seth Hampson845e8782018-03-02 11:34:10 -08001142 std::vector<std::string> stream_ids;
Seth Hampson5b4f0752018-04-02 16:31:36 -07001143 if (stream_id.empty()) {
1144 stream_ids.push_back(rtc::CreateRandomUuid());
1145 RTC_LOG(LS_INFO)
1146 << "No stream_id specified for sender. Generated stream ID: "
1147 << stream_ids[0];
1148 } else {
Seth Hampson845e8782018-03-02 11:34:10 -08001149 stream_ids.push_back(stream_id);
Steve Anton02ee47c2018-01-10 16:26:06 -08001150 }
1151
Steve Anton4171afb2017-11-20 10:20:22 -08001152 // TODO(steveanton): Move construction of the RtpSenders to RtpTransceiver.
deadbeefa601f5c2016-06-06 14:27:39 -07001153 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
deadbeeffac06552015-11-25 11:26:01 -08001154 if (kind == MediaStreamTrackInterface::kAudioKind) {
Amit Hilbuchea7ef2a2019-02-19 15:20:21 -08001155 auto audio_sender = AudioRtpSender::Create(
Harald Alvestrande15fb152020-10-19 13:28:05 +00001156 worker_thread(), rtc::CreateRandomUuid(), stats_.get(), rtp_manager());
1157 audio_sender->SetMediaChannel(rtp_manager()->voice_media_channel());
deadbeefa601f5c2016-06-06 14:27:39 -07001158 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-10 16:26:06 -08001159 signaling_thread(), audio_sender);
Harald Alvestrande15fb152020-10-19 13:28:05 +00001160 rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 11:26:01 -08001161 } else if (kind == MediaStreamTrackInterface::kVideoKind) {
Harald Alvestrande15fb152020-10-19 13:28:05 +00001162 auto video_sender = VideoRtpSender::Create(
1163 worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
1164 video_sender->SetMediaChannel(rtp_manager()->video_media_channel());
deadbeefa601f5c2016-06-06 14:27:39 -07001165 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-10 16:26:06 -08001166 signaling_thread(), video_sender);
Harald Alvestrande15fb152020-10-19 13:28:05 +00001167 rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 11:26:01 -08001168 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001169 RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
Steve Anton4171afb2017-11-20 10:20:22 -08001170 return nullptr;
deadbeeffac06552015-11-25 11:26:01 -08001171 }
Henrik Andreasssoncc189172019-05-20 09:01:38 +00001172 new_sender->internal()->set_stream_ids(stream_ids);
Steve Anton4171afb2017-11-20 10:20:22 -08001173
deadbeefe1f9d832016-01-14 15:35:42 -08001174 return new_sender;
deadbeeffac06552015-11-25 11:26:01 -08001175}
1176
deadbeef70ab1a12015-09-28 16:53:55 -07001177std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
1178 const {
Karl Wiberga58e1692019-03-26 13:33:43 +01001179 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 14:27:39 -07001180 std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
Harald Alvestrande15fb152020-10-19 13:28:05 +00001181 for (const auto& sender : rtp_manager()->GetSendersInternal()) {
Steve Anton4171afb2017-11-20 10:20:22 -08001182 ret.push_back(sender);
deadbeefa601f5c2016-06-06 14:27:39 -07001183 }
1184 return ret;
deadbeef70ab1a12015-09-28 16:53:55 -07001185}
1186
1187std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
1188PeerConnection::GetReceivers() const {
Karl Wiberga58e1692019-03-26 13:33:43 +01001189 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 14:27:39 -07001190 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
Harald Alvestrande15fb152020-10-19 13:28:05 +00001191 for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
Steve Anton4171afb2017-11-20 10:20:22 -08001192 ret.push_back(receiver);
deadbeefa601f5c2016-06-06 14:27:39 -07001193 }
1194 return ret;
deadbeef70ab1a12015-09-28 16:53:55 -07001195}
1196
Steve Anton9158ef62017-11-27 13:01:52 -08001197std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
1198PeerConnection::GetTransceivers() const {
Karl Wiberg5966c502019-02-21 23:55:09 +01001199 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 13:48:58 -08001200 RTC_CHECK(IsUnifiedPlan())
1201 << "GetTransceivers is only supported with Unified Plan SdpSemantics.";
Steve Anton9158ef62017-11-27 13:01:52 -08001202 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
Harald Alvestrande15fb152020-10-19 13:28:05 +00001203 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
Harald Alvestrand936f1af2020-09-22 07:41:50 +00001204 all_transceivers.push_back(transceiver);
Steve Anton9158ef62017-11-27 13:01:52 -08001205 }
1206 return all_transceivers;
1207}
1208
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001209bool PeerConnection::GetStats(StatsObserver* observer,
wu@webrtc.orgb9a088b2014-02-13 23:18:49 +00001210 MediaStreamTrackInterface* track,
1211 StatsOutputLevel level) {
Peter Boström1a9d6152015-12-08 22:15:17 +01001212 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 09:57:01 +01001213 RTC_DCHECK_RUN_ON(signaling_thread());
nisse7ce109a2017-01-31 00:57:56 -08001214 if (!observer) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001215 RTC_LOG(LS_ERROR) << "GetStats - observer is NULL.";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001216 return false;
1217 }
1218
Tommife041642021-04-07 10:08:28 +02001219 RTC_LOG_THREAD_BLOCK_COUNT();
1220
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001221 stats_->UpdateStats(level);
Tommi19015512022-02-02 11:49:35 +01001222
1223 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(4);
1224
zhihuange9e94c32016-11-04 11:38:15 -07001225 // The StatsCollector is used to tell if a track is valid because it may
1226 // remember tracks that the PeerConnection previously removed.
1227 if (track && !stats_->IsValidTrack(track->id())) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01001228 RTC_LOG(LS_WARNING) << "GetStats is called with an invalid track: "
1229 << track->id();
zhihuange9e94c32016-11-04 11:38:15 -07001230 return false;
1231 }
Harald Alvestrand1090e442020-10-05 07:01:09 +00001232 message_handler_.PostGetStats(observer, stats_.get(), track);
Tommife041642021-04-07 10:08:28 +02001233
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001234 return true;
1235}
1236
hbos74e1a4f2016-09-15 23:33:01 -07001237void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
Henrik Boström1df1bf82018-03-20 13:24:20 +01001238 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 09:57:01 +01001239 RTC_DCHECK_RUN_ON(signaling_thread());
hbos74e1a4f2016-09-15 23:33:01 -07001240 RTC_DCHECK(stats_collector_);
Henrik Boström1df1bf82018-03-20 13:24:20 +01001241 RTC_DCHECK(callback);
Tommife041642021-04-07 10:08:28 +02001242 RTC_LOG_THREAD_BLOCK_COUNT();
Niels Möllere7cc8832022-01-04 15:20:03 +01001243 stats_collector_->GetStatsReport(
1244 rtc::scoped_refptr<RTCStatsCollectorCallback>(callback));
hbos74e1a4f2016-09-15 23:33:01 -07001245}
1246
Henrik Boström1df1bf82018-03-20 13:24:20 +01001247void PeerConnection::GetStats(
1248 rtc::scoped_refptr<RtpSenderInterface> selector,
1249 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1250 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 09:57:01 +01001251 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 13:24:20 +01001252 RTC_DCHECK(callback);
1253 RTC_DCHECK(stats_collector_);
1254 rtc::scoped_refptr<RtpSenderInternal> internal_sender;
1255 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:05 +00001256 for (const auto& proxy_transceiver :
1257 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 13:24:20 +01001258 for (const auto& proxy_sender :
1259 proxy_transceiver->internal()->senders()) {
1260 if (proxy_sender == selector) {
1261 internal_sender = proxy_sender->internal();
1262 break;
1263 }
1264 }
1265 if (internal_sender)
1266 break;
1267 }
1268 }
Artem Titov880fa812021-07-30 22:30:23 +02001269 // If there is no `internal_sender` then `selector` is either null or does not
Henrik Boström1df1bf82018-03-20 13:24:20 +01001270 // belong to the PeerConnection (in Plan B, senders can be removed from the
1271 // PeerConnection). This means that "all the stats objects representing the
1272 // selector" is an empty set. Invoking GetStatsReport() with a null selector
1273 // produces an empty stats report.
1274 stats_collector_->GetStatsReport(internal_sender, callback);
1275}
1276
1277void PeerConnection::GetStats(
1278 rtc::scoped_refptr<RtpReceiverInterface> selector,
1279 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1280 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 09:57:01 +01001281 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 13:24:20 +01001282 RTC_DCHECK(callback);
1283 RTC_DCHECK(stats_collector_);
1284 rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
1285 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:05 +00001286 for (const auto& proxy_transceiver :
1287 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 13:24:20 +01001288 for (const auto& proxy_receiver :
1289 proxy_transceiver->internal()->receivers()) {
1290 if (proxy_receiver == selector) {
1291 internal_receiver = proxy_receiver->internal();
1292 break;
1293 }
1294 }
1295 if (internal_receiver)
1296 break;
1297 }
1298 }
Artem Titov880fa812021-07-30 22:30:23 +02001299 // If there is no `internal_receiver` then `selector` is either null or does
Henrik Boström1df1bf82018-03-20 13:24:20 +01001300 // not belong to the PeerConnection (in Plan B, receivers can be removed from
1301 // the PeerConnection). This means that "all the stats objects representing
1302 // the selector" is an empty set. Invoking GetStatsReport() with a null
1303 // selector produces an empty stats report.
1304 stats_collector_->GetStatsReport(internal_receiver, callback);
1305}
1306
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001307PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
Karl Wiberg8d2e2282019-02-17 13:00:07 +01001308 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001309 return sdp_handler_->signaling_state();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001310}
1311
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312PeerConnectionInterface::IceConnectionState
1313PeerConnection::ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 13:00:07 +01001314 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001315 return ice_connection_state_;
1316}
1317
Alex Loiko9289eda2018-11-23 16:18:59 +00001318PeerConnectionInterface::IceConnectionState
1319PeerConnection::standardized_ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 13:00:07 +01001320 RTC_DCHECK_RUN_ON(signaling_thread());
Alex Loiko9289eda2018-11-23 16:18:59 +00001321 return standardized_ice_connection_state_;
1322}
1323
Jonas Olsson635474e2018-10-18 15:58:17 +02001324PeerConnectionInterface::PeerConnectionState
1325PeerConnection::peer_connection_state() {
Karl Wiberg8d2e2282019-02-17 13:00:07 +01001326 RTC_DCHECK_RUN_ON(signaling_thread());
Jonas Olsson635474e2018-10-18 15:58:17 +02001327 return connection_state_;
1328}
1329
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001330PeerConnectionInterface::IceGatheringState
1331PeerConnection::ice_gathering_state() {
Karl Wiberg8d2e2282019-02-17 13:00:07 +01001332 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001333 return ice_gathering_state_;
1334}
1335
Harald Alvestrand61f74d92020-03-02 11:20:00 +01001336absl::optional<bool> PeerConnection::can_trickle_ice_candidates() {
1337 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001338 const SessionDescriptionInterface* description = current_remote_description();
Harald Alvestrand61f74d92020-03-02 11:20:00 +01001339 if (!description) {
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001340 description = pending_remote_description();
Harald Alvestrand61f74d92020-03-02 11:20:00 +01001341 }
1342 if (!description) {
1343 return absl::nullopt;
1344 }
1345 // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
1346 if (description->description()->transport_infos().size() < 1) {
1347 return absl::nullopt;
1348 }
1349 return description->description()->transport_infos()[0].description.HasOption(
1350 "trickle");
1351}
1352
Harald Alvestranda9af50f2021-05-21 13:33:51 +00001353RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>
1354PeerConnection::CreateDataChannelOrError(const std::string& label,
1355 const DataChannelInit* config) {
Karl Wiberg106d92d2019-02-14 10:17:47 +01001356 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 22:15:17 +01001357 TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
zhihuang9763d562016-08-05 11:14:50 -07001358
Harald Alvestrand05e4d082019-12-03 14:04:21 +01001359 bool first_datachannel = !data_channel_controller_.HasDataChannels();
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001360
kwibergd1fe2812016-04-27 06:47:29 -07001361 std::unique_ptr<InternalDataChannelInit> internal_config;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00001362 if (config) {
1363 internal_config.reset(new InternalDataChannelInit(*config));
1364 }
Harald Alvestranda9af50f2021-05-21 13:33:51 +00001365 // TODO(bugs.webrtc.org/12796): Return a more specific error.
Taylor Brandstetter3a034e12020-07-09 15:32:34 -07001366 rtc::scoped_refptr<DataChannelInterface> channel(
1367 data_channel_controller_.InternalCreateDataChannelWithProxy(
Harald Alvestrand00cf34c2019-12-02 09:56:02 +01001368 label, internal_config.get()));
deadbeefab9b2d12015-10-14 11:33:11 -07001369 if (!channel.get()) {
Harald Alvestranda9af50f2021-05-21 13:33:51 +00001370 return RTCError(RTCErrorType::INTERNAL_ERROR,
1371 "Data channel creation failed");
deadbeefab9b2d12015-10-14 11:33:11 -07001372 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001373
Harald Alvestrand48171ec2021-04-20 15:06:03 +00001374 // Trigger the onRenegotiationNeeded event for
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001375 // the first SCTP DataChannel.
Harald Alvestrand7af57c62021-04-16 11:12:14 +00001376 if (first_datachannel) {
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001377 sdp_handler_->UpdateNegotiationNeeded();
jiayl@webrtc.org001fd2d2014-05-29 15:31:11 +00001378 }
Harald Alvestrand8ebba742018-05-31 14:00:34 +02001379 NoteUsageEvent(UsageEvent::DATA_ADDED);
Taylor Brandstetter3a034e12020-07-09 15:32:34 -07001380 return channel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001381}
1382
Henrik Boström79b69802019-07-18 11:16:56 +02001383void PeerConnection::RestartIce() {
1384 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001385 sdp_handler_->RestartIce();
Henrik Boström79b69802019-07-18 11:16:56 +02001386}
1387
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001389 const RTCOfferAnswerOptions& options) {
Karl Wiberg5966c502019-02-21 23:55:09 +01001390 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001391 sdp_handler_->CreateOffer(observer, options);
Henrik Boströma3728d32019-10-28 12:09:49 +01001392}
1393
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001394void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
1395 const RTCOfferAnswerOptions& options) {
Henrik Boströma3728d32019-10-28 12:09:49 +01001396 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001397 sdp_handler_->CreateAnswer(observer, options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398}
1399
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001400void PeerConnection::SetLocalDescription(
1401 SetSessionDescriptionObserver* observer,
Steve Anton80dd7b52018-02-16 17:08:42 -08001402 SessionDescriptionInterface* desc_ptr) {
Karl Wiberg5966c502019-02-21 23:55:09 +01001403 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001404 sdp_handler_->SetLocalDescription(observer, desc_ptr);
Henrik Boström831ae4e2020-07-29 12:04:00 +02001405}
1406
1407void PeerConnection::SetLocalDescription(
1408 std::unique_ptr<SessionDescriptionInterface> desc,
1409 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1410 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001411 sdp_handler_->SetLocalDescription(std::move(desc), observer);
Henrik Boströma3728d32019-10-28 12:09:49 +01001412}
Steve Anton8a006912017-12-04 15:25:56 -08001413
Henrik Boström4e196702019-10-30 10:35:50 +01001414void PeerConnection::SetLocalDescription(
1415 SetSessionDescriptionObserver* observer) {
1416 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001417 sdp_handler_->SetLocalDescription(observer);
Henrik Boström831ae4e2020-07-29 12:04:00 +02001418}
1419
1420void PeerConnection::SetLocalDescription(
1421 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1422 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001423 sdp_handler_->SetLocalDescription(observer);
Henrik Boström4e196702019-10-30 10:35:50 +01001424}
1425
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001426void PeerConnection::SetRemoteDescription(
Henrik Boströma4ecf552017-11-23 14:17:07 +00001427 SetSessionDescriptionObserver* observer,
Henrik Boströma3728d32019-10-28 12:09:49 +01001428 SessionDescriptionInterface* desc_ptr) {
1429 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001430 sdp_handler_->SetRemoteDescription(observer, desc_ptr);
Henrik Boström31638672017-11-23 17:48:32 +01001431}
1432
1433void PeerConnection::SetRemoteDescription(
1434 std::unique_ptr<SessionDescriptionInterface> desc,
1435 rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
Karl Wiberg5966c502019-02-21 23:55:09 +01001436 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001437 sdp_handler_->SetRemoteDescription(std::move(desc), observer);
Henrik Boströmafa07dd2018-12-20 11:06:02 +01001438}
1439
deadbeef46c73892016-11-16 19:42:04 -08001440PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
Karl Wiberg5966c502019-02-21 23:55:09 +01001441 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeef46c73892016-11-16 19:42:04 -08001442 return configuration_;
1443}
1444
Niels Möller2579f0c2019-08-19 09:58:17 +02001445RTCError PeerConnection::SetConfiguration(
1446 const RTCConfiguration& configuration) {
Karl Wiberg5966c502019-02-21 23:55:09 +01001447 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 22:15:17 +01001448 TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
Steve Antonc79268f2018-04-24 09:54:10 -07001449 if (IsClosed()) {
Niels Möller2579f0c2019-08-19 09:58:17 +02001450 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1451 "SetConfiguration: PeerConnection is closed.");
Steve Antonc79268f2018-04-24 09:54:10 -07001452 }
1453
Qingsi Wanga2d60672018-04-11 16:57:45 -07001454 // According to JSEP, after setLocalDescription, changing the candidate pool
1455 // size is not allowed, and changing the set of ICE servers will not result
1456 // in new candidates being gathered.
Steve Anton75737c02017-11-06 10:37:17 -08001457 if (local_description() && configuration.ice_candidate_pool_size !=
1458 configuration_.ice_candidate_pool_size) {
Niels Möller2579f0c2019-08-19 09:58:17 +02001459 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1460 "Can't change candidate pool size after calling "
1461 "SetLocalDescription.");
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00001462 }
Taylor Brandstettera1c30352016-05-13 08:15:11 -07001463
Piotr (Peter) Slatalaaa1e7c22018-10-16 10:04:45 -07001464 if (local_description() &&
Benjamin Wright8c27cca2018-10-25 10:16:44 -07001465 configuration.crypto_options != configuration_.crypto_options) {
Niels Möller2579f0c2019-08-19 09:58:17 +02001466 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1467 "Can't change crypto_options after calling "
1468 "SetLocalDescription.");
Benjamin Wright8c27cca2018-10-25 10:16:44 -07001469 }
1470
deadbeef293e9262017-01-11 12:28:30 -08001471 // The simplest (and most future-compatible) way to tell if the config was
1472 // modified in an invalid way is to copy each property we do support
1473 // modifying, then use operator==. There are far more properties we don't
1474 // support modifying than those we do, and more could be added.
1475 RTCConfiguration modified_config = configuration_;
1476 modified_config.servers = configuration.servers;
1477 modified_config.type = configuration.type;
1478 modified_config.ice_candidate_pool_size =
1479 configuration.ice_candidate_pool_size;
1480 modified_config.prune_turn_ports = configuration.prune_turn_ports;
Honghai Zhangf8998cf2019-10-14 11:27:50 -07001481 modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy;
Qingsi Wangbca14852019-06-26 14:56:02 -07001482 modified_config.surface_ice_candidates_on_ice_transport_type_changed =
1483 configuration.surface_ice_candidates_on_ice_transport_type_changed;
skvladd1f5fda2017-02-03 16:54:05 -08001484 modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
Qingsi Wange6826d22018-03-08 14:55:14 -08001485 modified_config.ice_check_interval_strong_connectivity =
1486 configuration.ice_check_interval_strong_connectivity;
1487 modified_config.ice_check_interval_weak_connectivity =
1488 configuration.ice_check_interval_weak_connectivity;
Qingsi Wang22e623a2018-03-13 10:53:57 -07001489 modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
1490 modified_config.ice_unwritable_min_checks =
1491 configuration.ice_unwritable_min_checks;
Jiawei Ou9d4fd5552018-12-06 23:30:17 -08001492 modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
Qingsi Wangdb53f8e2018-02-20 14:45:49 -08001493 modified_config.stun_candidate_keepalive_interval =
1494 configuration.stun_candidate_keepalive_interval;
Jonas Orelandbdcee282017-10-10 14:01:40 +02001495 modified_config.turn_customizer = configuration.turn_customizer;
Qingsi Wang9a5c6f82018-02-01 10:38:40 -08001496 modified_config.network_preference = configuration.network_preference;
Zhi Huangb57e1692018-06-12 11:41:11 -07001497 modified_config.active_reset_srtp_params =
1498 configuration.active_reset_srtp_params;
Jonas Oreland3c028422019-08-22 16:16:35 +02001499 modified_config.turn_logging_id = configuration.turn_logging_id;
philipel16cec3b2019-10-25 12:23:02 +02001500 modified_config.allow_codec_switching = configuration.allow_codec_switching;
Derek Bailey6c127a12021-04-15 12:42:41 -07001501 modified_config.stable_writable_connection_ping_interval_ms =
1502 configuration.stable_writable_connection_ping_interval_ms;
deadbeef293e9262017-01-11 12:28:30 -08001503 if (configuration != modified_config) {
Niels Möller2579f0c2019-08-19 09:58:17 +02001504 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1505 "Modifying the configuration in an unsupported way.");
deadbeef293e9262017-01-11 12:28:30 -08001506 }
1507
Steve Anton038834f2017-07-14 15:59:59 -07001508 // Validate the modified configuration.
1509 RTCError validate_error = ValidateConfiguration(modified_config);
1510 if (!validate_error.ok()) {
Niels Möller2579f0c2019-08-19 09:58:17 +02001511 return validate_error;
Steve Anton038834f2017-07-14 15:59:59 -07001512 }
1513
deadbeef293e9262017-01-11 12:28:30 -08001514 // Note that this isn't possible through chromium, since it's an unsigned
1515 // short in WebIDL.
1516 if (configuration.ice_candidate_pool_size < 0 ||
Wez939eb802018-05-03 03:34:17 -07001517 configuration.ice_candidate_pool_size > static_cast<int>(UINT16_MAX)) {
Niels Möller2579f0c2019-08-19 09:58:17 +02001518 return RTCError(RTCErrorType::INVALID_RANGE);
deadbeef293e9262017-01-11 12:28:30 -08001519 }
1520
1521 // Parse ICE servers before hopping to network thread.
1522 cricket::ServerAddresses stun_servers;
1523 std::vector<cricket::RelayServerConfig> turn_servers;
1524 RTCErrorType parse_error =
1525 ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
1526 if (parse_error != RTCErrorType::NONE) {
Philipp Hancke05fadac2021-11-04 09:13:17 +01001527 return RTCError(parse_error, "ICE server parse failed");
deadbeef293e9262017-01-11 12:28:30 -08001528 }
Jonas Oreland3c028422019-08-22 16:16:35 +02001529 // Add the turn logging id to all turn servers
1530 for (cricket::RelayServerConfig& turn_server : turn_servers) {
1531 turn_server.turn_logging_id = configuration.turn_logging_id;
1532 }
1533
Harald Alvestrand8ebba742018-05-31 14:00:34 +02001534 // Note if STUN or TURN servers were supplied.
1535 if (!stun_servers.empty()) {
1536 NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
1537 }
1538 if (!turn_servers.empty()) {
1539 NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
1540 }
deadbeef293e9262017-01-11 12:28:30 -08001541
Niels Möller4bab23f2021-01-18 09:24:33 +01001542 const bool has_local_description = local_description() != nullptr;
1543
Tomas Gunnarsson20f74562021-02-04 10:22:50 +01001544 const bool needs_ice_restart =
1545 modified_config.servers != configuration_.servers ||
1546 NeedIceRestart(
1547 configuration_.surface_ice_candidates_on_ice_transport_type_changed,
1548 configuration_.type, modified_config.type) ||
1549 modified_config.GetTurnPortPrunePolicy() !=
1550 configuration_.GetTurnPortPrunePolicy();
1551 cricket::IceConfig ice_config = ParseIceConfig(modified_config);
1552
1553 // Apply part of the configuration on the network thread. In theory this
1554 // shouldn't fail.
deadbeef293e9262017-01-11 12:28:30 -08001555 if (!network_thread()->Invoke<bool>(
Tomas Gunnarsson20f74562021-02-04 10:22:50 +01001556 RTC_FROM_HERE,
1557 [this, needs_ice_restart, &ice_config, &stun_servers, &turn_servers,
1558 &modified_config, has_local_description] {
Harald Alvestrandbc32c562022-02-09 12:08:47 +00001559 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson20f74562021-02-04 10:22:50 +01001560 // As described in JSEP, calling setConfiguration with new ICE
1561 // servers or candidate policy must set a "needs-ice-restart" bit so
1562 // that the next offer triggers an ICE restart which will pick up
1563 // the changes.
1564 if (needs_ice_restart)
1565 transport_controller_->SetNeedsIceRestartFlag();
1566
1567 transport_controller_->SetIceConfig(ice_config);
Niels Möller4bab23f2021-01-18 09:24:33 +01001568 return ReconfigurePortAllocator_n(
1569 stun_servers, turn_servers, modified_config.type,
1570 modified_config.ice_candidate_pool_size,
1571 modified_config.GetTurnPortPrunePolicy(),
1572 modified_config.turn_customizer,
1573 modified_config.stun_candidate_keepalive_interval,
1574 has_local_description);
1575 })) {
Niels Möller2579f0c2019-08-19 09:58:17 +02001576 LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
1577 "Failed to apply configuration to PortAllocator.");
deadbeef293e9262017-01-11 12:28:30 -08001578 }
Honghai Zhang4cedf2b2016-08-31 08:18:11 -07001579
Zhi Huangb57e1692018-06-12 11:41:11 -07001580 if (configuration_.active_reset_srtp_params !=
1581 modified_config.active_reset_srtp_params) {
Harald Alvestrandbc32c562022-02-09 12:08:47 +00001582 // TODO(tommi): merge invokes
1583 network_thread()->Invoke<void>(RTC_FROM_HERE, [this, &modified_config] {
1584 RTC_DCHECK_RUN_ON(network_thread());
1585 transport_controller_->SetActiveResetSrtpParams(
1586 modified_config.active_reset_srtp_params);
1587 });
Zhi Huangb57e1692018-06-12 11:41:11 -07001588 }
1589
philipel16cec3b2019-10-25 12:23:02 +02001590 if (modified_config.allow_codec_switching.has_value()) {
Tomas Gunnarssond41c2a62020-09-21 15:56:42 +02001591 std::vector<cricket::VideoMediaChannel*> channels;
Harald Alvestrande15fb152020-10-19 13:28:05 +00001592 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
Tomas Gunnarssond41c2a62020-09-21 15:56:42 +02001593 if (transceiver->media_type() != cricket::MEDIA_TYPE_VIDEO)
Taylor Brandstetter6b381c72020-08-24 13:28:47 -07001594 continue;
Tomas Gunnarssond41c2a62020-09-21 15:56:42 +02001595
Harald Alvestrand2c761b22022-04-30 16:27:40 +00001596 auto* video_channel = transceiver->internal()->channel();
Tomas Gunnarssond41c2a62020-09-21 15:56:42 +02001597 if (video_channel)
Harald Alvestrand2c761b22022-04-30 16:27:40 +00001598 channels.push_back(static_cast<cricket::VideoMediaChannel*>(
1599 video_channel->media_channel()));
philipel01294f02019-11-14 13:03:25 +01001600 }
Tomas Gunnarssond41c2a62020-09-21 15:56:42 +02001601
1602 worker_thread()->Invoke<void>(
1603 RTC_FROM_HERE,
1604 [channels = std::move(channels),
1605 allow_codec_switching = *modified_config.allow_codec_switching]() {
1606 for (auto* ch : channels)
1607 ch->SetVideoCodecSwitchingEnabled(allow_codec_switching);
1608 });
philipel16cec3b2019-10-25 12:23:02 +02001609 }
1610
deadbeef293e9262017-01-11 12:28:30 -08001611 configuration_ = modified_config;
Niels Möller2579f0c2019-08-19 09:58:17 +02001612 return RTCError::OK();
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00001613}
1614
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001615bool PeerConnection::AddIceCandidate(
1616 const IceCandidateInterface* ice_candidate) {
Karl Wiberg744310f2019-02-14 10:18:56 +01001617 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001618 return sdp_handler_->AddIceCandidate(ice_candidate);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619}
1620
Henrik Boströmee6f4f62019-11-06 12:36:12 +01001621void PeerConnection::AddIceCandidate(
1622 std::unique_ptr<IceCandidateInterface> candidate,
1623 std::function<void(RTCError)> callback) {
1624 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001625 sdp_handler_->AddIceCandidate(std::move(candidate), callback);
Henrik Boströmee6f4f62019-11-06 12:36:12 +01001626}
1627
Honghai Zhang7fb69db2016-03-14 11:59:18 -07001628bool PeerConnection::RemoveIceCandidates(
1629 const std::vector<cricket::Candidate>& candidates) {
1630 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
Karl Wiberg2cc368f2019-04-02 11:31:56 +02001631 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001632 return sdp_handler_->RemoveIceCandidates(candidates);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07001633}
1634
Niels Möller0c4f7be2018-05-07 14:01:37 +02001635RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
Steve Anton978b8762017-09-29 12:15:02 -07001636 if (!worker_thread()->IsCurrent()) {
1637 return worker_thread()->Invoke<RTCError>(
Yves Gerey665174f2018-06-19 15:03:05 +02001638 RTC_FROM_HERE, [&]() { return SetBitrate(bitrate); });
zstein4b979802017-06-02 14:37:37 -07001639 }
Karl Wiberg6cab5c82019-03-26 09:57:01 +01001640 RTC_DCHECK_RUN_ON(worker_thread());
zstein4b979802017-06-02 14:37:37 -07001641
Niels Möller0c4f7be2018-05-07 14:01:37 +02001642 const bool has_min = bitrate.min_bitrate_bps.has_value();
1643 const bool has_start = bitrate.start_bitrate_bps.has_value();
1644 const bool has_max = bitrate.max_bitrate_bps.has_value();
zstein4b979802017-06-02 14:37:37 -07001645 if (has_min && *bitrate.min_bitrate_bps < 0) {
1646 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1647 "min_bitrate_bps <= 0");
1648 }
Niels Möller0c4f7be2018-05-07 14:01:37 +02001649 if (has_start) {
1650 if (has_min && *bitrate.start_bitrate_bps < *bitrate.min_bitrate_bps) {
zstein4b979802017-06-02 14:37:37 -07001651 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 14:01:37 +02001652 "start_bitrate_bps < min_bitrate_bps");
1653 } else if (*bitrate.start_bitrate_bps < 0) {
zstein4b979802017-06-02 14:37:37 -07001654 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1655 "curent_bitrate_bps < 0");
1656 }
1657 }
1658 if (has_max) {
Yves Gerey665174f2018-06-19 15:03:05 +02001659 if (has_start && *bitrate.max_bitrate_bps < *bitrate.start_bitrate_bps) {
zstein4b979802017-06-02 14:37:37 -07001660 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 14:01:37 +02001661 "max_bitrate_bps < start_bitrate_bps");
zstein4b979802017-06-02 14:37:37 -07001662 } else if (has_min && *bitrate.max_bitrate_bps < *bitrate.min_bitrate_bps) {
1663 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1664 "max_bitrate_bps < min_bitrate_bps");
1665 } else if (*bitrate.max_bitrate_bps < 0) {
1666 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1667 "max_bitrate_bps < 0");
1668 }
1669 }
1670
zstein4b979802017-06-02 14:37:37 -07001671 RTC_DCHECK(call_.get());
Piotr (Peter) Slatala7fbfaa42019-03-18 10:31:54 -07001672 call_->SetClientBitratePreferences(bitrate);
zstein4b979802017-06-02 14:37:37 -07001673
1674 return RTCError::OK();
1675}
1676
henrika5f6bf242017-11-01 11:06:56 +01001677void PeerConnection::SetAudioPlayout(bool playout) {
1678 if (!worker_thread()->IsCurrent()) {
1679 worker_thread()->Invoke<void>(
Niels Möller4bab23f2021-01-18 09:24:33 +01001680 RTC_FROM_HERE, [this, playout] { SetAudioPlayout(playout); });
henrika5f6bf242017-11-01 11:06:56 +01001681 return;
1682 }
1683 auto audio_state =
Harald Alvestranda39689c2020-10-15 08:34:31 +00001684 context_->channel_manager()->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 11:06:56 +01001685 audio_state->SetPlayout(playout);
1686}
1687
1688void PeerConnection::SetAudioRecording(bool recording) {
1689 if (!worker_thread()->IsCurrent()) {
1690 worker_thread()->Invoke<void>(
Niels Möller4bab23f2021-01-18 09:24:33 +01001691 RTC_FROM_HERE, [this, recording] { SetAudioRecording(recording); });
henrika5f6bf242017-11-01 11:06:56 +01001692 return;
1693 }
1694 auto audio_state =
Harald Alvestranda39689c2020-10-15 08:34:31 +00001695 context_->channel_manager()->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 11:06:56 +01001696 audio_state->SetRecording(recording);
1697}
1698
Henrik Boström4c1e7cc2020-06-11 12:26:53 +02001699void PeerConnection::AddAdaptationResource(
1700 rtc::scoped_refptr<Resource> resource) {
1701 if (!worker_thread()->IsCurrent()) {
1702 return worker_thread()->Invoke<void>(RTC_FROM_HERE, [this, resource]() {
1703 return AddAdaptationResource(resource);
1704 });
1705 }
1706 RTC_DCHECK_RUN_ON(worker_thread());
1707 if (!call_) {
1708 // The PeerConnection has been closed.
1709 return;
1710 }
1711 call_->AddAdaptationResource(resource);
1712}
1713
Harald Alvestrand35ba0c52022-05-05 07:37:41 +00001714bool PeerConnection::ConfiguredForMedia() const {
1715 return context_->channel_manager()->media_engine();
1716}
1717
Bjorn Tereliusde939432017-11-20 17:38:14 +01001718bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
1719 int64_t output_period_ms) {
Bjorn Tereliusde939432017-11-20 17:38:14 +01001720 return worker_thread()->Invoke<bool>(
Danil Chapovalov116ffe72019-09-05 10:21:11 +02001721 RTC_FROM_HERE,
1722 [this, output = std::move(output), output_period_ms]() mutable {
1723 return StartRtcEventLog_w(std::move(output), output_period_ms);
1724 });
ivoc14d5dbe2016-07-04 07:06:55 -07001725}
1726
Niels Möllerf00ca1a2019-05-10 11:33:12 +02001727bool PeerConnection::StartRtcEventLog(
1728 std::unique_ptr<RtcEventLogOutput> output) {
Niels Möller695cf6a2019-05-13 12:27:23 +02001729 int64_t output_period_ms = webrtc::RtcEventLog::kImmediateOutput;
Jonas Oreland6c7f9842022-04-19 17:24:10 +02001730 if (trials().IsEnabled("WebRTC-RtcEventLogNewFormat")) {
Niels Möller695cf6a2019-05-13 12:27:23 +02001731 output_period_ms = 5000;
1732 }
1733 return StartRtcEventLog(std::move(output), output_period_ms);
Niels Möllerf00ca1a2019-05-10 11:33:12 +02001734}
1735
ivoc14d5dbe2016-07-04 07:06:55 -07001736void PeerConnection::StopRtcEventLog() {
Niels Möller4bab23f2021-01-18 09:24:33 +01001737 worker_thread()->Invoke<void>(RTC_FROM_HERE, [this] { StopRtcEventLog_w(); });
ivoc14d5dbe2016-07-04 07:06:55 -07001738}
1739
Harald Alvestrandad88c882018-11-28 16:47:46 +01001740rtc::scoped_refptr<DtlsTransportInterface>
1741PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
Tomas Gunnarsson2aeab5e2021-02-23 21:36:14 +01001742 RTC_DCHECK_RUN_ON(network_thread());
Harald Alvestrandad88c882018-11-28 16:47:46 +01001743 return transport_controller_->LookupDtlsTransportByMid(mid);
1744}
1745
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +01001746rtc::scoped_refptr<DtlsTransport>
1747PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
Karl Wiberg2cc368f2019-04-02 11:31:56 +02001748 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:47 +00001749 // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
1750 // This might be done by caching the value on the signaling thread.
1751 return network_thread()->Invoke<rtc::scoped_refptr<DtlsTransport>>(
1752 RTC_FROM_HERE, [this, mid]() {
1753 RTC_DCHECK_RUN_ON(network_thread());
1754 return transport_controller_->LookupDtlsTransportByMid(mid);
1755 });
Harald Alvestrand4a7b3ac2019-01-17 10:39:40 +01001756}
1757
Harald Alvestrandc85328f2019-02-28 07:51:00 +01001758rtc::scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport()
1759 const {
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01001760 RTC_DCHECK_RUN_ON(network_thread());
1761 if (!sctp_mid_n_)
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -07001762 return nullptr;
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01001763
1764 return transport_controller_->GetSctpTransport(*sctp_mid_n_);
Harald Alvestrandc85328f2019-02-28 07:51:00 +01001765}
1766
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001767const SessionDescriptionInterface* PeerConnection::local_description() const {
Karl Wiberg739506e2019-04-03 11:37:28 +02001768 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001769 return sdp_handler_->local_description();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770}
1771
1772const SessionDescriptionInterface* PeerConnection::remote_description() const {
Karl Wiberg739506e2019-04-03 11:37:28 +02001773 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001774 return sdp_handler_->remote_description();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001775}
1776
deadbeeffe4a8a42016-12-20 17:56:17 -08001777const SessionDescriptionInterface* PeerConnection::current_local_description()
1778 const {
Karl Wiberg739506e2019-04-03 11:37:28 +02001779 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001780 return sdp_handler_->current_local_description();
deadbeeffe4a8a42016-12-20 17:56:17 -08001781}
1782
1783const SessionDescriptionInterface* PeerConnection::current_remote_description()
1784 const {
Karl Wiberg739506e2019-04-03 11:37:28 +02001785 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001786 return sdp_handler_->current_remote_description();
deadbeeffe4a8a42016-12-20 17:56:17 -08001787}
1788
1789const SessionDescriptionInterface* PeerConnection::pending_local_description()
1790 const {
Karl Wiberg739506e2019-04-03 11:37:28 +02001791 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001792 return sdp_handler_->pending_local_description();
deadbeeffe4a8a42016-12-20 17:56:17 -08001793}
1794
1795const SessionDescriptionInterface* PeerConnection::pending_remote_description()
1796 const {
Karl Wiberg739506e2019-04-03 11:37:28 +02001797 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001798 return sdp_handler_->pending_remote_description();
deadbeeffe4a8a42016-12-20 17:56:17 -08001799}
1800
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801void PeerConnection::Close() {
Karl Wiberg744310f2019-02-14 10:18:56 +01001802 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 22:15:17 +01001803 TRACE_EVENT0("webrtc", "PeerConnection::Close");
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001804
Tommife041642021-04-07 10:08:28 +02001805 RTC_LOG_THREAD_BLOCK_COUNT();
1806
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001807 if (IsClosed()) {
1808 return;
1809 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001810 // Update stats here so that we have the most recent stats for tracks and
1811 // streams before the channels are closed.
tommi@webrtc.org03505bc2014-07-14 20:15:26 +00001812 stats_->UpdateStats(kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001813
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001814 ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed;
1815 Observer()->OnIceConnectionChange(ice_connection_state_);
1816 standardized_ice_connection_state_ =
1817 PeerConnectionInterface::IceConnectionState::kIceConnectionClosed;
1818 connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
1819 Observer()->OnConnectionChange(connection_state_);
1820
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001821 sdp_handler_->Close();
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001822
Harald Alvestrand8ebba742018-05-31 14:00:34 +02001823 NoteUsageEvent(UsageEvent::CLOSE_CALLED);
Steve Anton3fe1b152017-12-12 10:20:08 -08001824
Harald Alvestrande15fb152020-10-19 13:28:05 +00001825 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
Harald Alvestrand6060df52020-08-11 09:54:02 +02001826 transceiver->internal()->SetPeerConnectionClosed();
1827 if (!transceiver->stopped())
1828 transceiver->StopInternal();
Steve Anton8af21862017-12-15 11:20:13 -08001829 }
Steve Anton25cfeb92018-04-26 11:44:00 -07001830
1831 // Ensure that all asynchronous stats requests are completed before destroying
1832 // the transport controller below.
1833 if (stats_collector_) {
1834 stats_collector_->WaitForPendingRequest();
1835 }
1836
1837 // Don't destroy BaseChannels until after stats has been cleaned up so that
1838 // the last stats request can still read from the channels.
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001839 sdp_handler_->DestroyAllChannels();
Steve Anton75737c02017-11-06 10:37:17 -08001840
Qingsi Wang93a84392018-01-30 17:13:09 -08001841 // The event log is used in the transport controller, which must be outlived
1842 // by the former. CreateOffer by the peer connection is implemented
1843 // asynchronously and if the peer connection is closed without resetting the
1844 // WebRTC session description factory, the session description factory would
1845 // call the transport controller.
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00001846 sdp_handler_->ResetSessionDescFactory();
Harald Alvestrande15fb152020-10-19 13:28:05 +00001847 rtp_manager_->Close();
Qingsi Wang93a84392018-01-30 17:13:09 -08001848
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01001849 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
Tomas Gunnarssond69e0702021-04-07 15:14:43 +02001850 // Data channels will already have been unset via the DestroyAllChannels()
1851 // call above, which triggers a call to TeardownDataChannelTransport_n().
1852 // TODO(tommi): ^^ That's not exactly optimal since this is yet another
1853 // blocking hop to the network thread during Close(). Further still, the
1854 // voice/video/data channels will be cleared on the worker thread.
Harald Alvestrandbc32c562022-02-09 12:08:47 +00001855 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01001856 transport_controller_.reset();
1857 port_allocator_->DiscardCandidatePool();
1858 if (network_thread_safety_) {
1859 network_thread_safety_->SetNotAlive();
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01001860 }
1861 });
nisseeaabdf62017-05-05 02:23:02 -07001862
Steve Anton978b8762017-09-29 12:15:02 -07001863 worker_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
Karl Wibergb03ab712019-02-14 11:59:57 +01001864 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:08 +00001865 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 05:18:15 -07001866 call_.reset();
1867 // The event log must outlive call (and any other object that uses it).
1868 event_log_.reset();
1869 });
Harald Alvestrand8ebba742018-05-31 14:00:34 +02001870 ReportUsagePattern();
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +02001871 // The .h file says that observer can be discarded after close() returns.
1872 // Make sure this is true.
1873 observer_ = nullptr;
Tomas Gunnarsson2efb8a52021-04-01 16:26:57 +02001874
1875 // Signal shutdown to the sdp handler. This invalidates weak pointers for
1876 // internal pending callbacks.
1877 sdp_handler_->PrepareForShutdown();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001878}
1879
Steve Antonba818672017-11-06 10:21:57 -08001880void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00001881 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonba818672017-11-06 10:21:57 -08001882 if (ice_connection_state_ == new_state) {
1883 return;
1884 }
1885
deadbeefcbecd352015-09-23 11:50:27 -07001886 // After transitioning to "closed", ignore any additional states from
Steve Antonba818672017-11-06 10:21:57 -08001887 // TransportController (such as "disconnected").
deadbeefab9b2d12015-10-14 11:33:11 -07001888 if (IsClosed()) {
deadbeefcbecd352015-09-23 11:50:27 -07001889 return;
1890 }
Steve Antonba818672017-11-06 10:21:57 -08001891
Mirko Bonadei675513b2017-11-09 11:09:25 +01001892 RTC_LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1893 << " => " << new_state;
Steve Antonba818672017-11-06 10:21:57 -08001894 RTC_DCHECK(ice_connection_state_ !=
1895 PeerConnectionInterface::kIceConnectionClosed);
1896
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001897 ice_connection_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +02001898 Observer()->OnIceConnectionChange(ice_connection_state_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001899}
1900
Alex Loiko9289eda2018-11-23 16:18:59 +00001901void PeerConnection::SetStandardizedIceConnectionState(
1902 PeerConnectionInterface::IceConnectionState new_state) {
Qingsi Wang36e31472019-05-29 11:37:26 -07001903 if (standardized_ice_connection_state_ == new_state) {
Alex Loiko9289eda2018-11-23 16:18:59 +00001904 return;
Qingsi Wang36e31472019-05-29 11:37:26 -07001905 }
1906
1907 if (IsClosed()) {
Alex Loiko9289eda2018-11-23 16:18:59 +00001908 return;
Qingsi Wang36e31472019-05-29 11:37:26 -07001909 }
1910
1911 RTC_LOG(LS_INFO) << "Changing standardized IceConnectionState "
1912 << standardized_ice_connection_state_ << " => " << new_state;
1913
Alex Loiko9289eda2018-11-23 16:18:59 +00001914 standardized_ice_connection_state_ = new_state;
Jonas Olsson12046902018-12-06 11:25:14 +01001915 Observer()->OnStandardizedIceConnectionChange(new_state);
Alex Loiko9289eda2018-11-23 16:18:59 +00001916}
1917
Jonas Olsson635474e2018-10-18 15:58:17 +02001918void PeerConnection::SetConnectionState(
1919 PeerConnectionInterface::PeerConnectionState new_state) {
Jonas Olsson635474e2018-10-18 15:58:17 +02001920 if (connection_state_ == new_state)
1921 return;
1922 if (IsClosed())
1923 return;
1924 connection_state_ = new_state;
1925 Observer()->OnConnectionChange(new_state);
Philipp Hanckebb8f32f2021-02-04 21:50:50 +01001926
Philipp Hanckecd0373f2021-02-24 11:04:30 +01001927 if (new_state == PeerConnectionState::kConnected && !was_ever_connected_) {
1928 was_ever_connected_ = true;
1929
1930 // The first connection state change to connected happens once per
1931 // connection which makes it a good point to report metrics.
Philipp Hanckebb8f32f2021-02-04 21:50:50 +01001932 // Record bundle-policy from configuration. Done here from
1933 // connectionStateChange to limit to actually established connections.
1934 BundlePolicyUsage policy = kBundlePolicyUsageMax;
1935 switch (configuration_.bundle_policy) {
1936 case kBundlePolicyBalanced:
1937 policy = kBundlePolicyUsageBalanced;
1938 break;
1939 case kBundlePolicyMaxBundle:
1940 policy = kBundlePolicyUsageMaxBundle;
1941 break;
1942 case kBundlePolicyMaxCompat:
1943 policy = kBundlePolicyUsageMaxCompat;
1944 break;
1945 }
1946 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundlePolicy", policy,
1947 kBundlePolicyUsageMax);
Philipp Hancke89736552021-03-05 12:07:05 +01001948
1949 // Record configured ice candidate pool size depending on the
1950 // BUNDLE policy. See
1951 // https://w3c.github.io/webrtc-pc/#dom-rtcconfiguration-icecandidatepoolsize
1952 // The ICE candidate pool size is an optimization and it may be desirable
1953 // to restrict the maximum size of the pre-gathered candidates.
1954 switch (configuration_.bundle_policy) {
1955 case kBundlePolicyBalanced:
1956 RTC_HISTOGRAM_COUNTS_LINEAR(
1957 "WebRTC.PeerConnection.CandidatePoolUsage.Balanced",
1958 configuration_.ice_candidate_pool_size, 0, 255, 256);
1959 break;
1960 case kBundlePolicyMaxBundle:
1961 RTC_HISTOGRAM_COUNTS_LINEAR(
1962 "WebRTC.PeerConnection.CandidatePoolUsage.MaxBundle",
1963 configuration_.ice_candidate_pool_size, 0, 255, 256);
1964 break;
1965 case kBundlePolicyMaxCompat:
1966 RTC_HISTOGRAM_COUNTS_LINEAR(
1967 "WebRTC.PeerConnection.CandidatePoolUsage.MaxCompat",
1968 configuration_.ice_candidate_pool_size, 0, 255, 256);
1969 break;
1970 }
Philipp Hancke1b4807f2021-06-11 11:49:54 +02001971
1972 // Record whether there was a local or remote provisional answer.
1973 ProvisionalAnswerUsage pranswer = kProvisionalAnswerNotUsed;
1974 if (local_description()->GetType() == SdpType::kPrAnswer) {
1975 pranswer = kProvisionalAnswerLocal;
1976 } else if (remote_description()->GetType() == SdpType::kPrAnswer) {
1977 pranswer = kProvisionalAnswerRemote;
1978 }
1979 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ProvisionalAnswer",
1980 pranswer, kProvisionalAnswerMax);
Philipp Hanckef59d9fb2021-10-13 11:34:15 +02001981
1982 // Record the number of configured ICE servers for connected connections.
1983 RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.PeerConnection.IceServers.Connected",
1984 configuration_.servers.size(), 0, 31, 32);
Philipp Hanckebb8f32f2021-02-04 21:50:50 +01001985 }
Jonas Olsson635474e2018-10-18 15:58:17 +02001986}
1987
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001988void PeerConnection::OnIceGatheringChange(
1989 PeerConnectionInterface::IceGatheringState new_state) {
1990 if (IsClosed()) {
1991 return;
1992 }
1993 ice_gathering_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +02001994 Observer()->OnIceGatheringChange(ice_gathering_state_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001995}
1996
jbauch81bf7b02017-03-25 08:31:12 -07001997void PeerConnection::OnIceCandidate(
1998 std::unique_ptr<IceCandidateInterface> candidate) {
zhihuang29ff8442016-07-27 11:07:25 -07001999 if (IsClosed()) {
2000 return;
2001 }
Qingsi Wang1ba5dec2019-08-19 11:57:17 -07002002 ReportIceCandidateCollected(candidate->candidate());
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +02002003 Observer()->OnIceCandidate(candidate.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002004}
2005
Eldar Rello0095d372019-12-02 22:22:07 +02002006void PeerConnection::OnIceCandidateError(const std::string& address,
2007 int port,
Eldar Relloda13ea22019-06-01 12:23:43 +03002008 const std::string& url,
2009 int error_code,
2010 const std::string& error_text) {
2011 if (IsClosed()) {
2012 return;
2013 }
Eldar Rello0095d372019-12-02 22:22:07 +02002014 Observer()->OnIceCandidateError(address, port, url, error_code, error_text);
Eldar Relloda13ea22019-06-01 12:23:43 +03002015}
2016
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002017void PeerConnection::OnIceCandidatesRemoved(
2018 const std::vector<cricket::Candidate>& candidates) {
zhihuang29ff8442016-07-27 11:07:25 -07002019 if (IsClosed()) {
2020 return;
2021 }
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +02002022 Observer()->OnIceCandidatesRemoved(candidates);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002023}
2024
Alex Drake00c7ecf2019-08-06 10:54:47 -07002025void PeerConnection::OnSelectedCandidatePairChanged(
2026 const cricket::CandidatePairChangeEvent& event) {
2027 if (IsClosed()) {
2028 return;
2029 }
Qingsi Wang1ba5dec2019-08-19 11:57:17 -07002030
Qingsi Wangcc46b102019-09-12 11:19:01 -07002031 if (event.selected_candidate_pair.local_candidate().type() ==
2032 LOCAL_PORT_TYPE &&
2033 event.selected_candidate_pair.remote_candidate().type() ==
2034 LOCAL_PORT_TYPE) {
2035 NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
2036 }
2037
Alex Drake00c7ecf2019-08-06 10:54:47 -07002038 Observer()->OnIceSelectedCandidatePairChanged(event);
2039}
2040
Danil Chapovalov66cadcc2018-06-19 16:47:43 +02002041absl::optional<std::string> PeerConnection::GetDataMid() const {
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00002042 RTC_DCHECK_RUN_ON(signaling_thread());
Florent Castelli516e2842021-04-19 15:29:50 +02002043 return sctp_mid_s_;
Steve Antonfa2260d2017-12-28 16:38:23 -08002044}
2045
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002046void PeerConnection::SetSctpDataMid(const std::string& mid) {
2047 RTC_DCHECK_RUN_ON(signaling_thread());
2048 sctp_mid_s_ = mid;
2049}
2050
2051void PeerConnection::ResetSctpDataMid() {
2052 RTC_DCHECK_RUN_ON(signaling_thread());
2053 sctp_mid_s_.reset();
2054 sctp_transport_name_s_.clear();
2055}
2056
Taylor Brandstetter3a034e12020-07-09 15:32:34 -07002057void PeerConnection::OnSctpDataChannelClosed(DataChannelInterface* channel) {
Harald Alvestrand00cf34c2019-12-02 09:56:02 +01002058 // Since data_channel_controller doesn't do signals, this
2059 // signal is relayed here.
Taylor Brandstetter3a034e12020-07-09 15:32:34 -07002060 data_channel_controller_.OnSctpDataChannelClosed(
2061 static_cast<SctpDataChannel*>(channel));
deadbeefab9b2d12015-10-14 11:33:11 -07002062}
2063
Karl Wibergfb3be392019-03-22 14:13:22 +01002064PeerConnection::InitializePortAllocatorResult
2065PeerConnection::InitializePortAllocator_n(
Harald Alvestrandb2a74782018-06-28 13:54:07 +02002066 const cricket::ServerAddresses& stun_servers,
2067 const std::vector<cricket::RelayServerConfig>& turn_servers,
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002068 const RTCConfiguration& configuration) {
Karl Wibergfb3be392019-03-22 14:13:22 +01002069 RTC_DCHECK_RUN_ON(network_thread());
2070
Taylor Brandstetterf8e65772016-06-27 17:20:15 -07002071 port_allocator_->Initialize();
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002072 // To handle both internal and externally created port allocator, we will
2073 // enable BUNDLE here.
Karl Wibergfb3be392019-03-22 14:13:22 +01002074 int port_allocator_flags = port_allocator_->flags();
2075 port_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
2076 cricket::PORTALLOCATOR_ENABLE_IPV6 |
2077 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002078 // If the disable-IPv6 flag was specified, we'll not override it
2079 // by experiment.
2080 if (configuration.disable_ipv6) {
Karl Wibergfb3be392019-03-22 14:13:22 +01002081 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
Jonas Oreland6c7f9842022-04-19 17:24:10 +02002082 } else if (trials().IsDisabled("WebRTC-IPv6Default")) {
Karl Wibergfb3be392019-03-22 14:13:22 +01002083 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002084 }
zhihuangb09b3f92017-03-07 14:40:51 -08002085 if (configuration.disable_ipv6_on_wifi) {
Karl Wibergfb3be392019-03-22 14:13:22 +01002086 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
Mirko Bonadei675513b2017-11-09 11:09:25 +01002087 RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled.";
zhihuangb09b3f92017-03-07 14:40:51 -08002088 }
2089
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002090 if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
Karl Wibergfb3be392019-03-22 14:13:22 +01002091 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
Mirko Bonadei675513b2017-11-09 11:09:25 +01002092 RTC_LOG(LS_INFO) << "TCP candidates are disabled.";
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002093 }
2094
honghaiz60347052016-05-31 18:29:12 -07002095 if (configuration.candidate_network_policy ==
2096 kCandidateNetworkPolicyLowCost) {
Karl Wibergfb3be392019-03-22 14:13:22 +01002097 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
Mirko Bonadei675513b2017-11-09 11:09:25 +01002098 RTC_LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
honghaiz60347052016-05-31 18:29:12 -07002099 }
2100
Daniel Lazarenko2870b0a2018-01-25 10:30:22 +01002101 if (configuration.disable_link_local_networks) {
Karl Wibergfb3be392019-03-22 14:13:22 +01002102 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS;
Daniel Lazarenko2870b0a2018-01-25 10:30:22 +01002103 RTC_LOG(LS_INFO) << "Disable candidates on link-local network interfaces.";
2104 }
2105
Karl Wibergfb3be392019-03-22 14:13:22 +01002106 port_allocator_->set_flags(port_allocator_flags);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002107 // No step delay is used while allocating ports.
2108 port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
Qingsi Wangc129c352019-04-18 10:41:58 -07002109 port_allocator_->SetCandidateFilter(
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002110 ConvertIceTransportTypeToCandidateFilter(configuration.type));
deadbeefd21eab32017-07-26 16:50:11 -07002111 port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002112
Harald Alvestrandb2a74782018-06-28 13:54:07 +02002113 auto turn_servers_copy = turn_servers;
Benjamin Wright6f80f092018-08-13 17:06:26 -07002114 for (auto& turn_server : turn_servers_copy) {
2115 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
Benjamin Wrightd6f86e82018-05-08 13:12:25 -07002116 }
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002117 // Call this last since it may create pooled allocator sessions using the
2118 // properties set above.
Qingsi Wangdb53f8e2018-02-20 14:45:49 -08002119 port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-13 17:06:26 -07002120 stun_servers, std::move(turn_servers_copy),
Honghai Zhangf8998cf2019-10-14 11:27:50 -07002121 configuration.ice_candidate_pool_size,
2122 configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer,
Qingsi Wangdb53f8e2018-02-20 14:45:49 -08002123 configuration.stun_candidate_keepalive_interval);
Karl Wibergfb3be392019-03-22 14:13:22 +01002124
2125 InitializePortAllocatorResult res;
2126 res.enable_ipv6 = port_allocator_flags & cricket::PORTALLOCATOR_ENABLE_IPV6;
2127 return res;
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002128}
2129
deadbeef91dd5672016-05-18 16:55:30 -07002130bool PeerConnection::ReconfigurePortAllocator_n(
deadbeef293e9262017-01-11 12:28:30 -08002131 const cricket::ServerAddresses& stun_servers,
2132 const std::vector<cricket::RelayServerConfig>& turn_servers,
2133 IceTransportsType type,
2134 int candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 11:27:50 -07002135 PortPrunePolicy turn_port_prune_policy,
Qingsi Wangdb53f8e2018-02-20 14:45:49 -08002136 webrtc::TurnCustomizer* turn_customizer,
Karl Wiberg739506e2019-04-03 11:37:28 +02002137 absl::optional<int> stun_candidate_keepalive_interval,
2138 bool have_local_description) {
Harald Alvestrandf598e492020-11-04 05:54:10 +00002139 RTC_DCHECK_RUN_ON(network_thread());
Qingsi Wangc129c352019-04-18 10:41:58 -07002140 port_allocator_->SetCandidateFilter(
deadbeef293e9262017-01-11 12:28:30 -08002141 ConvertIceTransportTypeToCandidateFilter(type));
Qingsi Wanga2d60672018-04-11 16:57:45 -07002142 // According to JSEP, after setLocalDescription, changing the candidate pool
2143 // size is not allowed, and changing the set of ICE servers will not result
2144 // in new candidates being gathered.
Karl Wiberg739506e2019-04-03 11:37:28 +02002145 if (have_local_description) {
Qingsi Wanga2d60672018-04-11 16:57:45 -07002146 port_allocator_->FreezeCandidatePool();
2147 }
Benjamin Wright6f80f092018-08-13 17:06:26 -07002148 // Add the custom tls turn servers if they exist.
2149 auto turn_servers_copy = turn_servers;
2150 for (auto& turn_server : turn_servers_copy) {
2151 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
2152 }
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002153 // Call this last since it may create pooled allocator sessions using the
2154 // candidate filter set above.
deadbeef6de92f92016-12-12 18:49:32 -08002155 return port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-13 17:06:26 -07002156 stun_servers, std::move(turn_servers_copy), candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 11:27:50 -07002157 turn_port_prune_policy, turn_customizer,
2158 stun_candidate_keepalive_interval);
Taylor Brandstettera1c30352016-05-13 08:15:11 -07002159}
2160
Elad Alon99c3fe52017-10-13 16:29:40 +02002161bool PeerConnection::StartRtcEventLog_w(
Bjorn Tereliusde939432017-11-20 17:38:14 +01002162 std::unique_ptr<RtcEventLogOutput> output,
2163 int64_t output_period_ms) {
Karl Wibergb03ab712019-02-14 11:59:57 +01002164 RTC_DCHECK_RUN_ON(worker_thread());
zhihuang77985012017-02-07 15:45:16 -08002165 if (!event_log_) {
2166 return false;
2167 }
Bjorn Tereliusde939432017-11-20 17:38:14 +01002168 return event_log_->StartLogging(std::move(output), output_period_ms);
ivoc14d5dbe2016-07-04 07:06:55 -07002169}
2170
2171void PeerConnection::StopRtcEventLog_w() {
Karl Wibergb03ab712019-02-14 11:59:57 +01002172 RTC_DCHECK_RUN_ON(worker_thread());
zhihuang77985012017-02-07 15:45:16 -08002173 if (event_log_) {
2174 event_log_->StopLogging();
2175 }
ivoc14d5dbe2016-07-04 07:06:55 -07002176}
nisseeaabdf62017-05-05 02:23:02 -07002177
Steve Anton75737c02017-11-06 10:37:17 -08002178bool PeerConnection::GetSctpSslRole(rtc::SSLRole* role) {
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08002179 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton75737c02017-11-06 10:37:17 -08002180 if (!local_description() || !remote_description()) {
Harald Alvestrand977b2652019-12-12 13:40:50 +01002181 RTC_LOG(LS_VERBOSE)
Mirko Bonadei675513b2017-11-09 11:09:25 +01002182 << "Local and Remote descriptions must be applied to get the "
Jonas Olsson45cc8902018-02-13 10:37:07 +01002183 "SSL Role of the SCTP transport.";
Steve Anton75737c02017-11-06 10:37:17 -08002184 return false;
2185 }
Harald Alvestrand00cf34c2019-12-02 09:56:02 +01002186 if (!data_channel_controller_.data_channel_transport()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01002187 RTC_LOG(LS_INFO) << "Non-rejected SCTP m= section is needed to get the "
Jonas Olsson45cc8902018-02-13 10:37:07 +01002188 "SSL Role of the SCTP transport.";
Steve Anton75737c02017-11-06 10:37:17 -08002189 return false;
2190 }
2191
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08002192 absl::optional<rtc::SSLRole> dtls_role;
Harald Alvestrand7a829a82020-02-12 07:38:21 +01002193 if (sctp_mid_s_) {
Harald Alvestrandbc32c562022-02-09 12:08:47 +00002194 dtls_role = network_thread()->Invoke<absl::optional<rtc::SSLRole>>(
2195 RTC_FROM_HERE, [this] {
2196 RTC_DCHECK_RUN_ON(network_thread());
2197 return transport_controller_->GetDtlsRole(*sctp_mid_n_);
2198 });
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00002199 if (!dtls_role && sdp_handler_->is_caller().has_value()) {
Harald Alvestrand321ec3b2022-02-10 13:42:18 +00002200 // This works fine if we are the offerer, but can be a mistake if
Harald Alvestrand06c87a12022-02-11 13:12:16 +00002201 // we are the answerer and the remote offer is ACTIVE. In that
Harald Alvestrand321ec3b2022-02-10 13:42:18 +00002202 // case, we will guess the role wrong.
2203 // TODO(bugs.webrtc.org/13668): Check if this actually happens.
Harald Alvestrand06c87a12022-02-11 13:12:16 +00002204 RTC_LOG(LS_ERROR)
2205 << "Possible risk: DTLS role guesser is active, is_caller is "
2206 << *sdp_handler_->is_caller();
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00002207 dtls_role =
2208 *sdp_handler_->is_caller() ? rtc::SSL_SERVER : rtc::SSL_CLIENT;
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -07002209 }
Harald Alvestrand321ec3b2022-02-10 13:42:18 +00002210 if (dtls_role) {
2211 *role = *dtls_role;
2212 return true;
2213 }
Zhi Huange830e682018-03-30 10:48:35 -07002214 }
2215 return false;
Steve Anton75737c02017-11-06 10:37:17 -08002216}
2217
2218bool PeerConnection::GetSslRole(const std::string& content_name,
2219 rtc::SSLRole* role) {
Karl Wiberg2cc368f2019-04-02 11:31:56 +02002220 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton75737c02017-11-06 10:37:17 -08002221 if (!local_description() || !remote_description()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01002222 RTC_LOG(LS_INFO)
2223 << "Local and Remote descriptions must be applied to get the "
Jonas Olsson45cc8902018-02-13 10:37:07 +01002224 "SSL Role of the session.";
Steve Anton75737c02017-11-06 10:37:17 -08002225 return false;
2226 }
2227
Harald Alvestrandbc32c562022-02-09 12:08:47 +00002228 auto dtls_role = network_thread()->Invoke<absl::optional<rtc::SSLRole>>(
2229 RTC_FROM_HERE, [this, content_name]() {
2230 RTC_DCHECK_RUN_ON(network_thread());
2231 return transport_controller_->GetDtlsRole(content_name);
2232 });
Zhi Huange830e682018-03-30 10:48:35 -07002233 if (dtls_role) {
2234 *role = *dtls_role;
2235 return true;
2236 }
2237 return false;
Steve Anton75737c02017-11-06 10:37:17 -08002238}
2239
Steve Anton75737c02017-11-06 10:37:17 -08002240bool PeerConnection::GetTransportDescription(
2241 const SessionDescription* description,
2242 const std::string& content_name,
2243 cricket::TransportDescription* tdesc) {
2244 if (!description || !tdesc) {
2245 return false;
2246 }
2247 const TransportInfo* transport_info =
2248 description->GetTransportInfoByName(content_name);
2249 if (!transport_info) {
2250 return false;
2251 }
2252 *tdesc = transport_info->description;
2253 return true;
2254}
2255
Taylor Brandstetter3a034e12020-07-09 15:32:34 -07002256std::vector<DataChannelStats> PeerConnection::GetDataChannelStats() const {
Tomas Gunnarsson2e94de52020-06-16 16:54:10 +02002257 RTC_DCHECK_RUN_ON(signaling_thread());
2258 return data_channel_controller_.GetDataChannelStats();
2259}
2260
Danil Chapovalov66cadcc2018-06-19 16:47:43 +02002261absl::optional<std::string> PeerConnection::sctp_transport_name() const {
Karl Wiberg2cc368f2019-04-02 11:31:56 +02002262 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:47 +00002263 if (sctp_mid_s_ && transport_controller_copy_)
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002264 return sctp_transport_name_s_;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +02002265 return absl::optional<std::string>();
Zhi Huange830e682018-03-30 10:48:35 -07002266}
2267
Tomas Gunnarssonbfd9ba82021-04-18 11:55:57 +02002268absl::optional<std::string> PeerConnection::sctp_mid() const {
2269 RTC_DCHECK_RUN_ON(signaling_thread());
2270 return sctp_mid_s_;
2271}
2272
Qingsi Wang72a43a12018-02-20 16:03:18 -08002273cricket::CandidateStatsList PeerConnection::GetPooledCandidateStats() const {
Tomas Gunnarssone1c8a432021-04-08 15:15:28 +02002274 RTC_DCHECK_RUN_ON(network_thread());
2275 if (!network_thread_safety_->alive())
2276 return {};
Qingsi Wang72a43a12018-02-20 16:03:18 -08002277 cricket::CandidateStatsList candidate_states_list;
Tomas Gunnarssone1c8a432021-04-08 15:15:28 +02002278 port_allocator_->GetCandidateStatsFromPooledSessions(&candidate_states_list);
Qingsi Wang72a43a12018-02-20 16:03:18 -08002279 return candidate_states_list;
2280}
2281
Steve Anton5dfde182018-02-06 10:34:40 -08002282std::map<std::string, cricket::TransportStats>
2283PeerConnection::GetTransportStatsByNames(
2284 const std::set<std::string>& transport_names) {
Markus Handell518669d2021-06-07 13:30:46 +02002285 TRACE_EVENT0("webrtc", "PeerConnection::GetTransportStatsByNames");
Karl Wiberg2cc368f2019-04-02 11:31:56 +02002286 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarssone1c8a432021-04-08 15:15:28 +02002287 if (!network_thread_safety_->alive())
2288 return {};
2289
2290 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton5dfde182018-02-06 10:34:40 -08002291 std::map<std::string, cricket::TransportStats> transport_stats_by_name;
2292 for (const std::string& transport_name : transport_names) {
2293 cricket::TransportStats transport_stats;
2294 bool success =
2295 transport_controller_->GetStats(transport_name, &transport_stats);
2296 if (success) {
2297 transport_stats_by_name[transport_name] = std::move(transport_stats);
2298 } else {
2299 RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
2300 << transport_name;
2301 }
2302 }
2303 return transport_stats_by_name;
Steve Anton75737c02017-11-06 10:37:17 -08002304}
2305
2306bool PeerConnection::GetLocalCertificate(
2307 const std::string& transport_name,
2308 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
Tomas Gunnarssone1c8a432021-04-08 15:15:28 +02002309 RTC_DCHECK_RUN_ON(network_thread());
2310 if (!network_thread_safety_->alive() || !certificate) {
Zhi Huange830e682018-03-30 10:48:35 -07002311 return false;
2312 }
2313 *certificate = transport_controller_->GetLocalCertificate(transport_name);
2314 return *certificate != nullptr;
Steve Anton75737c02017-11-06 10:37:17 -08002315}
2316
Taylor Brandstetterc3928662018-02-23 13:04:51 -08002317std::unique_ptr<rtc::SSLCertChain> PeerConnection::GetRemoteSSLCertChain(
Steve Anton75737c02017-11-06 10:37:17 -08002318 const std::string& transport_name) {
Tomas Gunnarssone1c8a432021-04-08 15:15:28 +02002319 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstetterc3928662018-02-23 13:04:51 -08002320 return transport_controller_->GetRemoteSSLCertChain(transport_name);
Steve Anton75737c02017-11-06 10:37:17 -08002321}
2322
Steve Anton75737c02017-11-06 10:37:17 -08002323bool PeerConnection::IceRestartPending(const std::string& content_name) const {
Karl Wibergf73f7d62019-04-08 15:36:53 +02002324 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00002325 return sdp_handler_->IceRestartPending(content_name);
Steve Anton75737c02017-11-06 10:37:17 -08002326}
2327
Steve Anton75737c02017-11-06 10:37:17 -08002328bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
Tommic3257d02021-02-10 17:40:08 +00002329 return network_thread()->Invoke<bool>(RTC_FROM_HERE, [this, &content_name] {
2330 RTC_DCHECK_RUN_ON(network_thread());
2331 return transport_controller_->NeedsIceRestart(content_name);
2332 });
Steve Anton75737c02017-11-06 10:37:17 -08002333}
2334
Alex Loiko9289eda2018-11-23 16:18:59 +00002335void PeerConnection::OnTransportControllerConnectionState(
2336 cricket::IceConnectionState state) {
2337 switch (state) {
2338 case cricket::kIceConnectionConnecting:
2339 // If the current state is Connected or Completed, then there were
2340 // writable channels but now there are not, so the next state must
2341 // be Disconnected.
2342 // kIceConnectionConnecting is currently used as the default,
2343 // un-connected state by the TransportController, so its only use is
2344 // detecting disconnections.
2345 if (ice_connection_state_ ==
2346 PeerConnectionInterface::kIceConnectionConnected ||
2347 ice_connection_state_ ==
2348 PeerConnectionInterface::kIceConnectionCompleted) {
2349 SetIceConnectionState(
2350 PeerConnectionInterface::kIceConnectionDisconnected);
2351 }
2352 break;
2353 case cricket::kIceConnectionFailed:
2354 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
2355 break;
2356 case cricket::kIceConnectionConnected:
2357 RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
2358 "all transports are writable.";
2359 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2360 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2361 break;
2362 case cricket::kIceConnectionCompleted:
2363 RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
2364 "all transports are complete.";
2365 if (ice_connection_state_ !=
2366 PeerConnectionInterface::kIceConnectionConnected) {
2367 // If jumping directly from "checking" to "connected",
2368 // signal "connected" first.
2369 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2370 }
2371 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
Tomas Gunnarsson2001dc32021-04-06 11:36:00 +02002372
Alex Loiko9289eda2018-11-23 16:18:59 +00002373 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
Alex Loiko9289eda2018-11-23 16:18:59 +00002374 break;
2375 default:
Artem Titovd3251962021-11-15 16:57:07 +01002376 RTC_DCHECK_NOTREACHED();
Alex Loiko9289eda2018-11-23 16:18:59 +00002377 }
2378}
2379
Steve Anton75737c02017-11-06 10:37:17 -08002380void PeerConnection::OnTransportControllerCandidatesGathered(
2381 const std::string& transport_name,
2382 const cricket::Candidates& candidates) {
Tomas Gunnarsson20f74562021-02-04 10:22:50 +01002383 // TODO(bugs.webrtc.org/12427): Expect this to come in on the network thread
2384 // (not signaling as it currently does), handle appropriately.
Steve Anton75737c02017-11-06 10:37:17 -08002385 int sdp_mline_index;
2386 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01002387 RTC_LOG(LS_ERROR)
2388 << "OnTransportControllerCandidatesGathered: content name "
2389 << transport_name << " not found";
Steve Anton75737c02017-11-06 10:37:17 -08002390 return;
2391 }
2392
2393 for (cricket::Candidates::const_iterator citer = candidates.begin();
2394 citer != candidates.end(); ++citer) {
2395 // Use transport_name as the candidate media id.
2396 std::unique_ptr<JsepIceCandidate> candidate(
2397 new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00002398 sdp_handler_->AddLocalIceCandidate(candidate.get());
Steve Anton75737c02017-11-06 10:37:17 -08002399 OnIceCandidate(std::move(candidate));
2400 }
2401}
2402
Eldar Relloda13ea22019-06-01 12:23:43 +03002403void PeerConnection::OnTransportControllerCandidateError(
2404 const cricket::IceCandidateErrorEvent& event) {
Eldar Rello0095d372019-12-02 22:22:07 +02002405 OnIceCandidateError(event.address, event.port, event.url, event.error_code,
Eldar Relloda13ea22019-06-01 12:23:43 +03002406 event.error_text);
2407}
2408
Steve Anton75737c02017-11-06 10:37:17 -08002409void PeerConnection::OnTransportControllerCandidatesRemoved(
2410 const std::vector<cricket::Candidate>& candidates) {
Steve Anton75737c02017-11-06 10:37:17 -08002411 // Sanity check.
2412 for (const cricket::Candidate& candidate : candidates) {
2413 if (candidate.transport_name().empty()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +01002414 RTC_LOG(LS_ERROR) << "OnTransportControllerCandidatesRemoved: "
Jonas Olsson45cc8902018-02-13 10:37:07 +01002415 "empty content name in candidate "
Mirko Bonadei675513b2017-11-09 11:09:25 +01002416 << candidate.ToString();
Steve Anton75737c02017-11-06 10:37:17 -08002417 return;
2418 }
2419 }
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00002420 sdp_handler_->RemoveLocalIceCandidates(candidates);
Steve Anton75737c02017-11-06 10:37:17 -08002421 OnIceCandidatesRemoved(candidates);
2422}
2423
Alex Drake00c7ecf2019-08-06 10:54:47 -07002424void PeerConnection::OnTransportControllerCandidateChanged(
2425 const cricket::CandidatePairChangeEvent& event) {
2426 OnSelectedCandidatePairChanged(event);
2427}
2428
Steve Anton75737c02017-11-06 10:37:17 -08002429void PeerConnection::OnTransportControllerDtlsHandshakeError(
2430 rtc::SSLHandshakeError error) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002431 RTC_HISTOGRAM_ENUMERATION(
2432 "WebRTC.PeerConnection.DtlsHandshakeError", static_cast<int>(error),
2433 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
Steve Anton75737c02017-11-06 10:37:17 -08002434}
2435
Steve Anton75737c02017-11-06 10:37:17 -08002436// Returns the media index for a local ice candidate given the content name.
2437bool PeerConnection::GetLocalCandidateMediaIndex(
2438 const std::string& content_name,
2439 int* sdp_mline_index) {
2440 if (!local_description() || !sdp_mline_index) {
2441 return false;
2442 }
2443
2444 bool content_found = false;
2445 const ContentInfos& contents = local_description()->description()->contents();
2446 for (size_t index = 0; index < contents.size(); ++index) {
2447 if (contents[index].name == content_name) {
2448 *sdp_mline_index = static_cast<int>(index);
2449 content_found = true;
2450 break;
2451 }
2452 }
2453 return content_found;
2454}
2455
Steve Anton75737c02017-11-06 10:37:17 -08002456Call::Stats PeerConnection::GetCallStats() {
2457 if (!worker_thread()->IsCurrent()) {
2458 return worker_thread()->Invoke<Call::Stats>(
Niels Möller4bab23f2021-01-18 09:24:33 +01002459 RTC_FROM_HERE, [this] { return GetCallStats(); });
Steve Anton75737c02017-11-06 10:37:17 -08002460 }
Karl Wiberg6cab5c82019-03-26 09:57:01 +01002461 RTC_DCHECK_RUN_ON(worker_thread());
Henrik Boströme88c95e2020-07-08 11:18:50 +02002462 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton75737c02017-11-06 10:37:17 -08002463 if (call_) {
2464 return call_->GetStats();
2465 } else {
2466 return Call::Stats();
2467 }
2468}
2469
Bjorn A Mellemb689af42019-08-21 10:44:59 -07002470bool PeerConnection::SetupDataChannelTransport_n(const std::string& mid) {
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -07002471 DataChannelTransportInterface* transport =
2472 transport_controller_->GetDataChannelTransport(mid);
2473 if (!transport) {
Piotr (Peter) Slatalab1ae10b2019-03-01 11:14:05 -08002474 RTC_LOG(LS_ERROR)
Bjorn A Mellemb689af42019-08-21 10:44:59 -07002475 << "Data channel transport is not available for data channels, mid="
2476 << mid;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08002477 return false;
2478 }
Bjorn A Mellemb689af42019-08-21 10:44:59 -07002479 RTC_LOG(LS_INFO) << "Setting up data channel transport for mid=" << mid;
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08002480
Harald Alvestrand00cf34c2019-12-02 09:56:02 +01002481 data_channel_controller_.set_data_channel_transport(transport);
2482 data_channel_controller_.SetupDataChannelTransport_n();
Harald Alvestrand7a829a82020-02-12 07:38:21 +01002483 sctp_mid_n_ = mid;
Tomas Gunnarssone1c8a432021-04-08 15:15:28 +02002484 cricket::DtlsTransportInternal* dtls_transport =
2485 transport_controller_->GetDtlsTransport(mid);
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002486 if (dtls_transport) {
2487 signaling_thread()->PostTask(
2488 ToQueuedTask(signaling_thread_safety_.flag(),
2489 [this, name = dtls_transport->transport_name()] {
2490 RTC_DCHECK_RUN_ON(signaling_thread());
2491 sctp_transport_name_s_ = std::move(name);
2492 }));
2493 }
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -07002494
2495 // Note: setting the data sink and checking initial state must be done last,
2496 // after setting up the data channel. Setting the data sink may trigger
2497 // callbacks to PeerConnection which require the transport to be completely
2498 // set up (eg. OnReadyToSend()).
Harald Alvestrand00cf34c2019-12-02 09:56:02 +01002499 transport->SetDataSink(&data_channel_controller_);
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08002500 return true;
2501}
2502
Tomas Gunnarssond69e0702021-04-07 15:14:43 +02002503void PeerConnection::TeardownDataChannelTransport_n() {
Tomas Gunnarssond69e0702021-04-07 15:14:43 +02002504 if (sctp_mid_n_) {
Artem Titov880fa812021-07-30 22:30:23 +02002505 // `sctp_mid_` may still be active through an SCTP transport. If not, unset
Tomas Gunnarssond69e0702021-04-07 15:14:43 +02002506 // it.
2507 RTC_LOG(LS_INFO) << "Tearing down data channel transport for mid="
2508 << *sctp_mid_n_;
2509 sctp_mid_n_.reset();
2510 }
2511
Harald Alvestrand00cf34c2019-12-02 09:56:02 +01002512 data_channel_controller_.TeardownDataChannelTransport_n();
Bjorn Mellem175aa2e2018-11-08 11:23:22 -08002513}
2514
Steve Anton75737c02017-11-06 10:37:17 -08002515// Returns false if bundle is enabled and rtcp_mux is disabled.
Henrik Boströmf8187e02021-04-26 21:04:26 +02002516bool PeerConnection::ValidateBundleSettings(
2517 const SessionDescription* desc,
2518 const std::map<std::string, const cricket::ContentGroup*>&
2519 bundle_groups_by_mid) {
2520 if (bundle_groups_by_mid.empty())
Steve Anton75737c02017-11-06 10:37:17 -08002521 return true;
2522
Steve Anton75737c02017-11-06 10:37:17 -08002523 const cricket::ContentInfos& contents = desc->contents();
2524 for (cricket::ContentInfos::const_iterator citer = contents.begin();
2525 citer != contents.end(); ++citer) {
2526 const cricket::ContentInfo* content = (&*citer);
2527 RTC_DCHECK(content != NULL);
Henrik Boströmf8187e02021-04-26 21:04:26 +02002528 auto it = bundle_groups_by_mid.find(content->name);
2529 if (it != bundle_groups_by_mid.end() && !content->rejected &&
Steve Anton5adfafd2017-12-20 16:34:00 -08002530 content->type == MediaProtocolType::kRtp) {
Steve Anton75737c02017-11-06 10:37:17 -08002531 if (!HasRtcpMuxEnabled(content))
2532 return false;
2533 }
2534 }
2535 // RTCP-MUX is enabled in all the contents.
2536 return true;
2537}
2538
Steve Anton8e20f172018-03-06 10:55:04 -08002539void PeerConnection::ReportSdpFormatReceived(
Philipp Hancke844c7592021-01-18 11:25:31 +01002540 const SessionDescriptionInterface& remote_description) {
Steve Anton8e20f172018-03-06 10:55:04 -08002541 int num_audio_mlines = 0;
2542 int num_video_mlines = 0;
2543 int num_audio_tracks = 0;
2544 int num_video_tracks = 0;
Philipp Hancke844c7592021-01-18 11:25:31 +01002545 for (const ContentInfo& content :
2546 remote_description.description()->contents()) {
Steve Anton8e20f172018-03-06 10:55:04 -08002547 cricket::MediaType media_type = content.media_description()->type();
2548 int num_tracks = std::max(
2549 1, static_cast<int>(content.media_description()->streams().size()));
2550 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2551 num_audio_mlines += 1;
2552 num_audio_tracks += num_tracks;
2553 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2554 num_video_mlines += 1;
2555 num_video_tracks += num_tracks;
2556 }
2557 }
2558 SdpFormatReceived format = kSdpFormatReceivedNoTracks;
2559 if (num_audio_mlines > 1 || num_video_mlines > 1) {
2560 format = kSdpFormatReceivedComplexUnifiedPlan;
2561 } else if (num_audio_tracks > 1 || num_video_tracks > 1) {
2562 format = kSdpFormatReceivedComplexPlanB;
2563 } else if (num_audio_tracks > 0 || num_video_tracks > 0) {
2564 format = kSdpFormatReceivedSimple;
2565 }
Philipp Hancke844c7592021-01-18 11:25:31 +01002566 switch (remote_description.GetType()) {
Philipp Hanckeb8ca2a12020-10-07 12:47:10 +02002567 case SdpType::kOffer:
2568 // Historically only offers were counted.
2569 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceived",
2570 format, kSdpFormatReceivedMax);
2571 break;
2572 case SdpType::kAnswer:
2573 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceivedAnswer",
2574 format, kSdpFormatReceivedMax);
2575 break;
2576 default:
2577 RTC_LOG(LS_ERROR) << "Can not report SdpFormatReceived for "
Philipp Hancke844c7592021-01-18 11:25:31 +01002578 << SdpTypeToString(remote_description.GetType());
Philipp Hanckeb8ca2a12020-10-07 12:47:10 +02002579 break;
2580 }
Steve Anton8e20f172018-03-06 10:55:04 -08002581}
2582
Philipp Hancke54b925c2021-01-28 09:56:39 +01002583void PeerConnection::ReportSdpBundleUsage(
2584 const SessionDescriptionInterface& remote_description) {
2585 RTC_DCHECK_RUN_ON(signaling_thread());
2586
2587 bool using_bundle =
2588 remote_description.description()->HasGroup(cricket::GROUP_TYPE_BUNDLE);
2589 int num_audio_mlines = 0;
2590 int num_video_mlines = 0;
2591 int num_data_mlines = 0;
2592 for (const ContentInfo& content :
2593 remote_description.description()->contents()) {
2594 cricket::MediaType media_type = content.media_description()->type();
2595 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2596 num_audio_mlines += 1;
2597 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2598 num_video_mlines += 1;
2599 } else if (media_type == cricket::MEDIA_TYPE_DATA) {
2600 num_data_mlines += 1;
2601 }
2602 }
2603 bool simple = num_audio_mlines <= 1 && num_video_mlines <= 1;
2604 BundleUsage usage = kBundleUsageMax;
2605 if (num_audio_mlines == 0 && num_video_mlines == 0) {
2606 if (num_data_mlines > 0) {
2607 usage = using_bundle ? kBundleUsageBundleDatachannelOnly
2608 : kBundleUsageNoBundleDatachannelOnly;
2609 } else {
2610 usage = kBundleUsageEmpty;
2611 }
Harald Alvestrandfa67aef2021-12-08 14:30:55 +00002612 } else if (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
Philipp Hancke54b925c2021-01-28 09:56:39 +01002613 // In plan-b, simple/complex usage will not show up in the number of
2614 // m-lines or BUNDLE.
2615 usage = using_bundle ? kBundleUsageBundlePlanB : kBundleUsageNoBundlePlanB;
2616 } else {
2617 if (simple) {
2618 usage =
2619 using_bundle ? kBundleUsageBundleSimple : kBundleUsageNoBundleSimple;
2620 } else {
2621 usage = using_bundle ? kBundleUsageBundleComplex
2622 : kBundleUsageNoBundleComplex;
2623 }
2624 }
2625 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundleUsage", usage,
2626 kBundleUsageMax);
2627}
2628
Qingsi Wang1ba5dec2019-08-19 11:57:17 -07002629void PeerConnection::ReportIceCandidateCollected(
2630 const cricket::Candidate& candidate) {
2631 NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
2632 if (candidate.address().IsPrivateIP()) {
2633 NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
2634 }
2635 if (candidate.address().IsUnresolvedIP()) {
2636 NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
2637 }
2638 if (candidate.address().family() == AF_INET6) {
2639 NoteUsageEvent(UsageEvent::IPV6_CANDIDATE_COLLECTED);
2640 }
2641}
2642
Harald Alvestrand8ebba742018-05-31 14:00:34 +02002643void PeerConnection::NoteUsageEvent(UsageEvent event) {
2644 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand44d0dff2020-10-09 05:43:53 +00002645 usage_pattern_.NoteUsageEvent(event);
Harald Alvestrand8ebba742018-05-31 14:00:34 +02002646}
2647
Tomas Gunnarsson8cb97062021-02-08 18:57:04 +01002648// Asynchronously adds remote candidates on the network thread.
2649void PeerConnection::AddRemoteCandidate(const std::string& mid,
2650 const cricket::Candidate& candidate) {
2651 RTC_DCHECK_RUN_ON(signaling_thread());
2652
2653 network_thread()->PostTask(ToQueuedTask(
2654 network_thread_safety_, [this, mid = mid, candidate = candidate] {
2655 RTC_DCHECK_RUN_ON(network_thread());
2656 std::vector<cricket::Candidate> candidates = {candidate};
2657 RTCError error =
2658 transport_controller_->AddRemoteCandidates(mid, candidates);
2659 if (error.ok()) {
2660 signaling_thread()->PostTask(ToQueuedTask(
2661 signaling_thread_safety_.flag(),
2662 [this, candidate = std::move(candidate)] {
2663 ReportRemoteIceCandidateAdded(candidate);
2664 // Candidates successfully submitted for checking.
2665 if (ice_connection_state() ==
2666 PeerConnectionInterface::kIceConnectionNew ||
2667 ice_connection_state() ==
2668 PeerConnectionInterface::kIceConnectionDisconnected) {
2669 // If state is New, then the session has just gotten its first
2670 // remote ICE candidates, so go to Checking. If state is
2671 // Disconnected, the session is re-using old candidates or
2672 // receiving additional ones, so go to Checking. If state is
2673 // Connected, stay Connected.
2674 // TODO(bemasc): If state is Connected, and the new candidates
2675 // are for a newly added transport, then the state actually
2676 // _should_ move to checking. Add a way to distinguish that
2677 // case.
2678 SetIceConnectionState(
2679 PeerConnectionInterface::kIceConnectionChecking);
2680 }
2681 // TODO(bemasc): If state is Completed, go back to Connected.
2682 }));
2683 } else {
2684 RTC_LOG(LS_WARNING) << error.message();
2685 }
2686 }));
2687}
2688
Harald Alvestrand8ebba742018-05-31 14:00:34 +02002689void PeerConnection::ReportUsagePattern() const {
Harald Alvestrand44d0dff2020-10-09 05:43:53 +00002690 usage_pattern_.ReportUsagePattern(observer_);
Harald Alvestrand8ebba742018-05-31 14:00:34 +02002691}
2692
Tomas Gunnarsson8cb97062021-02-08 18:57:04 +01002693void PeerConnection::ReportRemoteIceCandidateAdded(
2694 const cricket::Candidate& candidate) {
2695 RTC_DCHECK_RUN_ON(signaling_thread());
2696
2697 NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED);
2698
2699 if (candidate.address().IsPrivateIP()) {
2700 NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED);
2701 }
2702 if (candidate.address().IsUnresolvedIP()) {
2703 NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED);
2704 }
2705 if (candidate.address().family() == AF_INET6) {
2706 NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED);
2707 }
2708}
2709
Steve Anton75737c02017-11-06 10:37:17 -08002710bool PeerConnection::SrtpRequired() const {
Tomas Gunnarsson3278a712021-03-30 17:23:42 +02002711 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand0d018412021-11-04 13:52:31 +00002712 return (dtls_enabled_ ||
2713 sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() ==
2714 cricket::SEC_REQUIRED);
Steve Anton75737c02017-11-06 10:37:17 -08002715}
2716
2717void PeerConnection::OnTransportControllerGatheringState(
2718 cricket::IceGatheringState state) {
2719 RTC_DCHECK(signaling_thread()->IsCurrent());
2720 if (state == cricket::kIceGatheringGathering) {
2721 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
2722 } else if (state == cricket::kIceGatheringComplete) {
2723 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
Harald Alvestrandbedb6052020-08-20 14:50:10 +02002724 } else if (state == cricket::kIceGatheringNew) {
2725 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew);
2726 } else {
2727 RTC_LOG(LS_ERROR) << "Unknown state received: " << state;
Artem Titovd3251962021-11-15 16:57:07 +01002728 RTC_DCHECK_NOTREACHED();
Steve Anton75737c02017-11-06 10:37:17 -08002729 }
2730}
2731
Tomas Gunnarsson2001dc32021-04-06 11:36:00 +02002732// Runs on network_thread().
Steve Anton75737c02017-11-06 10:37:17 -08002733void PeerConnection::ReportTransportStats() {
Markus Handell518669d2021-06-07 13:30:46 +02002734 TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
Tommic3257d02021-02-10 17:40:08 +00002735 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Antonc7b964c2018-02-01 14:39:45 -08002736 std::map<std::string, std::set<cricket::MediaType>>
2737 media_types_by_transport_name;
Harald Alvestrand85466662021-04-19 21:21:36 +00002738 for (const auto& transceiver : rtp_manager()->transceivers()->UnsafeList()) {
Steve Antonc7b964c2018-02-01 14:39:45 -08002739 if (transceiver->internal()->channel()) {
Tomas Gunnarsson94f01942022-01-03 14:59:12 +00002740 std::string transport_name(
2741 transceiver->internal()->channel()->transport_name());
Steve Antonc7b964c2018-02-01 14:39:45 -08002742 media_types_by_transport_name[transport_name].insert(
Steve Anton69470252018-02-09 11:43:08 -08002743 transceiver->media_type());
Steve Antonc7b964c2018-02-01 14:39:45 -08002744 }
Steve Anton75737c02017-11-06 10:37:17 -08002745 }
Tomas Gunnarsson2001dc32021-04-06 11:36:00 +02002746
Tomas Gunnarsson2001dc32021-04-06 11:36:00 +02002747 if (sctp_mid_n_) {
Tomas Gunnarssone1c8a432021-04-08 15:15:28 +02002748 cricket::DtlsTransportInternal* dtls_transport =
2749 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson2001dc32021-04-06 11:36:00 +02002750 if (dtls_transport) {
2751 media_types_by_transport_name[dtls_transport->transport_name()].insert(
2752 cricket::MEDIA_TYPE_DATA);
2753 }
Steve Anton75737c02017-11-06 10:37:17 -08002754 }
Zhi Huange830e682018-03-30 10:48:35 -07002755
Tomas Gunnarsson2001dc32021-04-06 11:36:00 +02002756 for (const auto& entry : media_types_by_transport_name) {
2757 const std::string& transport_name = entry.first;
2758 const std::set<cricket::MediaType> media_types = entry.second;
2759 cricket::TransportStats stats;
2760 if (transport_controller_->GetStats(transport_name, &stats)) {
2761 ReportBestConnectionState(stats);
2762 ReportNegotiatedCiphers(dtls_enabled_, stats, media_types);
2763 }
2764 }
Steve Anton75737c02017-11-06 10:37:17 -08002765}
Tomas Gunnarsson2001dc32021-04-06 11:36:00 +02002766
Steve Anton75737c02017-11-06 10:37:17 -08002767// Walk through the ConnectionInfos to gather best connection usage
2768// for IPv4 and IPv6.
Tommic3257d02021-02-10 17:40:08 +00002769// static (no member state required)
Steve Anton75737c02017-11-06 10:37:17 -08002770void PeerConnection::ReportBestConnectionState(
2771 const cricket::TransportStats& stats) {
Steve Antonc7b964c2018-02-01 14:39:45 -08002772 for (const cricket::TransportChannelStats& channel_stats :
2773 stats.channel_stats) {
2774 for (const cricket::ConnectionInfo& connection_info :
Jonas Oreland149dc722019-08-28 08:10:27 +02002775 channel_stats.ice_transport_stats.connection_infos) {
Steve Antonc7b964c2018-02-01 14:39:45 -08002776 if (!connection_info.best_connection) {
Steve Anton75737c02017-11-06 10:37:17 -08002777 continue;
2778 }
2779
Steve Antonc7b964c2018-02-01 14:39:45 -08002780 const cricket::Candidate& local = connection_info.local_candidate;
2781 const cricket::Candidate& remote = connection_info.remote_candidate;
Steve Anton75737c02017-11-06 10:37:17 -08002782
2783 // Increment the counter for IceCandidatePairType.
2784 if (local.protocol() == cricket::TCP_PROTOCOL_NAME ||
2785 (local.type() == RELAY_PORT_TYPE &&
2786 local.relay_protocol() == cricket::TCP_PROTOCOL_NAME)) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002787 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_TCP",
2788 GetIceCandidatePairCounter(local, remote),
2789 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 10:37:17 -08002790 } else if (local.protocol() == cricket::UDP_PROTOCOL_NAME) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002791 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_UDP",
2792 GetIceCandidatePairCounter(local, remote),
2793 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 10:37:17 -08002794 } else {
Karl Wibergc95b9392020-11-08 00:49:37 +01002795 RTC_CHECK_NOTREACHED();
Steve Anton75737c02017-11-06 10:37:17 -08002796 }
Steve Anton75737c02017-11-06 10:37:17 -08002797
2798 // Increment the counter for IP type.
2799 if (local.address().family() == AF_INET) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002800 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2801 kBestConnections_IPv4,
2802 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 10:37:17 -08002803 } else if (local.address().family() == AF_INET6) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002804 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2805 kBestConnections_IPv6,
2806 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 10:37:17 -08002807 } else {
Qingsi Wang1dac6d82018-12-12 15:28:47 -08002808 RTC_CHECK(!local.address().hostname().empty() &&
2809 local.address().IsUnresolvedIP());
Steve Anton75737c02017-11-06 10:37:17 -08002810 }
2811
2812 return;
2813 }
2814 }
2815}
2816
Tommic3257d02021-02-10 17:40:08 +00002817// static
Steve Anton75737c02017-11-06 10:37:17 -08002818void PeerConnection::ReportNegotiatedCiphers(
Tommic3257d02021-02-10 17:40:08 +00002819 bool dtls_enabled,
Steve Antonc7b964c2018-02-01 14:39:45 -08002820 const cricket::TransportStats& stats,
2821 const std::set<cricket::MediaType>& media_types) {
Tommic3257d02021-02-10 17:40:08 +00002822 if (!dtls_enabled || stats.channel_stats.empty()) {
Steve Anton75737c02017-11-06 10:37:17 -08002823 return;
2824 }
2825
2826 int srtp_crypto_suite = stats.channel_stats[0].srtp_crypto_suite;
2827 int ssl_cipher_suite = stats.channel_stats[0].ssl_cipher_suite;
Mirko Bonadei7750d802021-07-26 17:27:42 +02002828 if (srtp_crypto_suite == rtc::kSrtpInvalidCryptoSuite &&
2829 ssl_cipher_suite == rtc::kTlsNullWithNullNull) {
Steve Anton75737c02017-11-06 10:37:17 -08002830 return;
2831 }
2832
Mirko Bonadei7750d802021-07-26 17:27:42 +02002833 if (srtp_crypto_suite != rtc::kSrtpInvalidCryptoSuite) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002834 for (cricket::MediaType media_type : media_types) {
2835 switch (media_type) {
2836 case cricket::MEDIA_TYPE_AUDIO:
2837 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2838 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio", srtp_crypto_suite,
Mirko Bonadei7750d802021-07-26 17:27:42 +02002839 rtc::kSrtpCryptoSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002840 break;
2841 case cricket::MEDIA_TYPE_VIDEO:
2842 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2843 "WebRTC.PeerConnection.SrtpCryptoSuite.Video", srtp_crypto_suite,
Mirko Bonadei7750d802021-07-26 17:27:42 +02002844 rtc::kSrtpCryptoSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002845 break;
2846 case cricket::MEDIA_TYPE_DATA:
2847 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2848 "WebRTC.PeerConnection.SrtpCryptoSuite.Data", srtp_crypto_suite,
Mirko Bonadei7750d802021-07-26 17:27:42 +02002849 rtc::kSrtpCryptoSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002850 break;
2851 default:
Artem Titovd3251962021-11-15 16:57:07 +01002852 RTC_DCHECK_NOTREACHED();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002853 continue;
2854 }
Steve Antonc7b964c2018-02-01 14:39:45 -08002855 }
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002856 }
2857
Mirko Bonadei7750d802021-07-26 17:27:42 +02002858 if (ssl_cipher_suite != rtc::kTlsNullWithNullNull) {
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002859 for (cricket::MediaType media_type : media_types) {
2860 switch (media_type) {
2861 case cricket::MEDIA_TYPE_AUDIO:
2862 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2863 "WebRTC.PeerConnection.SslCipherSuite.Audio", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 17:27:42 +02002864 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002865 break;
2866 case cricket::MEDIA_TYPE_VIDEO:
2867 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2868 "WebRTC.PeerConnection.SslCipherSuite.Video", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 17:27:42 +02002869 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002870 break;
2871 case cricket::MEDIA_TYPE_DATA:
2872 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2873 "WebRTC.PeerConnection.SslCipherSuite.Data", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 17:27:42 +02002874 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002875 break;
2876 default:
Artem Titovd3251962021-11-15 16:57:07 +01002877 RTC_DCHECK_NOTREACHED();
Qingsi Wang7fc821d2018-07-12 12:54:53 -07002878 continue;
2879 }
Steve Antonc7b964c2018-02-01 14:39:45 -08002880 }
Steve Anton75737c02017-11-06 10:37:17 -08002881 }
2882}
2883
Taylor Brandstettercbaa2542018-04-16 16:42:14 -07002884bool PeerConnection::OnTransportChanged(
Zhi Huange830e682018-03-30 10:48:35 -07002885 const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 16:42:14 -07002886 RtpTransportInternal* rtp_transport,
Harald Alvestrandc85328f2019-02-28 07:51:00 +01002887 rtc::scoped_refptr<DtlsTransport> dtls_transport,
Bjorn A Mellembc3eebc2019-09-23 14:53:54 -07002888 DataChannelTransportInterface* data_channel_transport) {
Karl Wibergac025892019-03-26 13:08:37 +01002889 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstettercbaa2542018-04-16 16:42:14 -07002890 bool ret = true;
Harald Alvestrand19ebabc2022-04-28 13:31:17 +00002891 for (const auto& transceiver : rtp_manager()->transceivers()->UnsafeList()) {
2892 cricket::ChannelInterface* channel = transceiver->internal()->channel();
2893 if (channel && channel->mid() == mid) {
2894 ret = channel->SetRtpTransport(rtp_transport);
2895 }
Zhi Huange830e682018-03-30 10:48:35 -07002896 }
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002897
Harald Alvestrand7a829a82020-02-12 07:38:21 +01002898 if (mid == sctp_mid_n_) {
Harald Alvestrand00cf34c2019-12-02 09:56:02 +01002899 data_channel_controller_.OnTransportChanged(data_channel_transport);
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002900 if (dtls_transport) {
2901 signaling_thread()->PostTask(ToQueuedTask(
2902 signaling_thread_safety_.flag(),
Tomas Gunnarsson94f01942022-01-03 14:59:12 +00002903 [this,
2904 name = std::string(dtls_transport->internal()->transport_name())] {
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002905 RTC_DCHECK_RUN_ON(signaling_thread());
2906 sctp_transport_name_s_ = std::move(name);
2907 }));
2908 }
Bjorn A Mellemb689af42019-08-21 10:44:59 -07002909 }
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002910
Taylor Brandstettercbaa2542018-04-16 16:42:14 -07002911 return ret;
Steve Anton75737c02017-11-06 10:37:17 -08002912}
2913
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +02002914PeerConnectionObserver* PeerConnection::Observer() const {
Harald Alvestrand05e4d082019-12-03 14:04:21 +01002915 RTC_DCHECK_RUN_ON(signaling_thread());
2916 RTC_DCHECK(observer_);
Harald Alvestrand7a1c7f72018-08-01 10:50:16 +02002917 return observer_;
2918}
2919
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002920void PeerConnection::StartSctpTransport(int local_port,
2921 int remote_port,
2922 int max_message_size) {
2923 RTC_DCHECK_RUN_ON(signaling_thread());
2924 if (!sctp_mid_s_)
2925 return;
2926
2927 network_thread()->PostTask(ToQueuedTask(
2928 network_thread_safety_,
2929 [this, mid = *sctp_mid_s_, local_port, remote_port, max_message_size] {
2930 rtc::scoped_refptr<SctpTransport> sctp_transport =
Harald Alvestrandbc32c562022-02-09 12:08:47 +00002931 transport_controller_n()->GetSctpTransport(mid);
Tomas Gunnarsson92eebef2021-02-10 13:05:44 +01002932 if (sctp_transport)
2933 sctp_transport->Start(local_port, remote_port, max_message_size);
2934 }));
2935}
2936
Benjamin Wright8c27cca2018-10-25 10:16:44 -07002937CryptoOptions PeerConnection::GetCryptoOptions() {
Harald Alvestrandc06e3742020-10-01 10:23:33 +00002938 RTC_DCHECK_RUN_ON(signaling_thread());
Benjamin Wright8c27cca2018-10-25 10:16:44 -07002939 // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions
2940 // after it has been removed.
2941 return configuration_.crypto_options.has_value()
2942 ? *configuration_.crypto_options
Harald Alvestrand4da4a872020-11-04 10:34:21 +00002943 : options_.crypto_options;
Benjamin Wright8c27cca2018-10-25 10:16:44 -07002944}
2945
Harald Alvestrand89061872018-01-02 14:08:34 +01002946void PeerConnection::ClearStatsCache() {
Karl Wiberg6cab5c82019-03-26 09:57:01 +01002947 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand89061872018-01-02 14:08:34 +01002948 if (stats_collector_) {
2949 stats_collector_->ClearCachedStatsReport();
2950 }
2951}
2952
Henrik Boströme574a312020-08-25 10:20:11 +02002953bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
2954 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:43 +00002955 return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
Eldar Rello5ab79e62019-10-09 18:29:44 +03002956}
2957
Harald Alvestrand1090e442020-10-05 07:01:09 +00002958void PeerConnection::RequestUsagePatternReportForTesting() {
Harald Alvestrand00c62ed2021-10-20 08:52:12 +00002959 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand1090e442020-10-05 07:01:09 +00002960 message_handler_.RequestUsagePatternReport(
2961 [this]() {
2962 RTC_DCHECK_RUN_ON(signaling_thread());
2963 ReportUsagePattern();
2964 },
2965 /* delay_ms= */ 0);
2966}
2967
Tomas Gunnarsson1e40a0c2020-09-28 10:39:31 +02002968std::function<void(const rtc::CopyOnWriteBuffer& packet,
2969 int64_t packet_time_us)>
2970PeerConnection::InitializeRtcpCallback() {
Tommic3257d02021-02-10 17:40:08 +00002971 RTC_DCHECK_RUN_ON(network_thread());
Tommicae1f1d2021-05-31 10:51:09 +02002972 return [this](const rtc::CopyOnWriteBuffer& packet, int64_t packet_time_us) {
Tomas Gunnarsson1e40a0c2020-09-28 10:39:31 +02002973 RTC_DCHECK_RUN_ON(network_thread());
Tommicae1f1d2021-05-31 10:51:09 +02002974 call_ptr_->Receiver()->DeliverPacket(MediaType::ANY, packet,
2975 packet_time_us);
Tomas Gunnarsson1e40a0c2020-09-28 10:39:31 +02002976 };
2977}
Harald Alvestrandcdcfab02020-09-28 13:02:07 +00002978
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002979} // namespace webrtc