blob: cde3d910475e2c1dc97d8fb694fa3259765b74b3 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:361/*
kjellanderb24317b2016-02-10 15:54:432 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:363 *
kjellanderb24317b2016-02-10 15:54:434 * 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:369 */
10
Steve Anton10542f22019-01-11 17:11:0011#include "pc/peer_connection.h"
henrike@webrtc.org28e20752013-07-10 00:45:3612
Harald Alvestrand1f7eab62020-10-18 16:51:4713#include <limits.h>
14#include <stddef.h>
Harald Alvestrand0ccfbd22021-04-08 07:25:0415
deadbeefeb459812015-12-16 03:24:4316#include <algorithm>
Harald Alvestrande15fb152020-10-19 13:28:0517#include <memory>
Harald Alvestrande15fb152020-10-19 13:28:0518#include <set>
Harald Alvestrand0d4af122022-01-31 09:36:0519#include <string>
Harald Alvestrand3eaee6b2020-10-19 06:35:5520#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:3621
Steve Anton64b626b2019-01-29 01:25:2622#include "absl/algorithm/container.h"
Fredrik Solenberg41f3a432018-12-17 20:02:2223#include "absl/strings/match.h"
Harald Alvestrand0d4af122022-01-31 09:36:0524#include "absl/strings/string_view.h"
Fredrik Hernqvistefbe7532023-01-13 15:42:3625#include "absl/types/optional.h"
Steve Anton10542f22019-01-11 17:11:0026#include "api/jsep_ice_candidate.h"
Per Ke1e94ad2023-03-30 14:53:5927#include "api/media_types.h"
Harald Alvestrand763f5a92020-10-22 10:39:4028#include "api/rtp_parameters.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4729#include "api/rtp_transceiver_direction.h"
Steve Anton10542f22019-01-11 17:11:0030#include "api/uma_metrics.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4731#include "api/video/video_codec_constants.h"
32#include "call/audio_state.h"
33#include "call/packet_receiver.h"
Harald Alvestrand763f5a92020-10-22 10:39:4034#include "media/base/media_channel.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4735#include "media/base/media_config.h"
Harald Alvestrand0d4af122022-01-31 09:36:0536#include "media/base/media_engine.h"
Amit Hilbuchf4770402019-04-08 21:11:5737#include "media/base/rid_description.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4738#include "media/base/stream_params.h"
39#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Harald Alvestrand0ccfbd22021-04-08 07:25:0440#include "p2p/base/basic_async_resolver_factory.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4741#include "p2p/base/connection.h"
42#include "p2p/base/connection_info.h"
43#include "p2p/base/dtls_transport_internal.h"
44#include "p2p/base/p2p_constants.h"
45#include "p2p/base/p2p_transport_channel.h"
46#include "p2p/base/transport_info.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4747#include "pc/ice_server_parsing.h"
Harald Alvestrand763f5a92020-10-22 10:39:4048#include "pc/rtp_receiver.h"
Harald Alvestrand0d4af122022-01-31 09:36:0549#include "pc/rtp_receiver_proxy.h"
Harald Alvestrand763f5a92020-10-22 10:39:4050#include "pc/rtp_sender.h"
Harald Alvestrand0d4af122022-01-31 09:36:0551#include "pc/rtp_sender_proxy.h"
Harald Alvestrandc85328f2019-02-28 06:51:0052#include "pc/sctp_transport.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4753#include "pc/simulcast_description.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4754#include "pc/webrtc_session_description_factory.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4755#include "rtc_base/helpers.h"
56#include "rtc_base/ip_address.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3157#include "rtc_base/logging.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4758#include "rtc_base/net_helper.h"
Harald Alvestrand0d4af122022-01-31 09:36:0559#include "rtc_base/network.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4760#include "rtc_base/network_constants.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4761#include "rtc_base/socket_address.h"
Steve Anton10542f22019-01-11 17:11:0062#include "rtc_base/string_encode.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3163#include "rtc_base/trace_event.h"
Harald Alvestrand763f5a92020-10-22 10:39:4064#include "rtc_base/unique_id_generator.h"
Qingsi Wang7fc821d2018-07-12 19:54:5365#include "system_wrappers/include/metrics.h"
henrike@webrtc.org28e20752013-07-10 00:45:3666
Steve Anton75737c02017-11-06 18:37:1767using cricket::ContentInfo;
68using cricket::ContentInfos;
69using cricket::MediaContentDescription;
Steve Anton5adfafd2017-12-21 00:34:0070using cricket::MediaProtocolType;
Amit Hilbuchbcd39d42019-01-26 01:13:5671using cricket::RidDescription;
72using cricket::RidDirection;
Amit Hilbuchc63ddb22019-01-02 18:13:5873using cricket::SessionDescription;
Amit Hilbuchbcd39d42019-01-26 01:13:5674using cricket::SimulcastDescription;
75using cricket::SimulcastLayer;
Amit Hilbuchc63ddb22019-01-02 18:13:5876using cricket::SimulcastLayerList;
Amit Hilbuchbcd39d42019-01-26 01:13:5677using cricket::StreamParams;
Steve Anton75737c02017-11-06 18:37:1778using cricket::TransportInfo;
79
80using cricket::LOCAL_PORT_TYPE;
Steve Anton75737c02017-11-06 18:37:1781using cricket::PRFLX_PORT_TYPE;
Jeroen de Borstaf242c82019-04-24 20:13:4882using cricket::RELAY_PORT_TYPE;
83using cricket::STUN_PORT_TYPE;
Steve Anton75737c02017-11-06 18:37:1784
Steve Antonba818672017-11-06 18:21:5785namespace webrtc {
86
Steve Anton75737c02017-11-06 18:37:1787namespace {
henrike@webrtc.org28e20752013-07-10 00:45:3688
Amit Hilbuche2a284d2019-03-05 20:36:3189// UMA metric names.
Amit Hilbuche2a284d2019-03-05 20:36:3190const char kSimulcastNumberOfEncodings[] =
91 "WebRTC.PeerConnection.Simulcast.NumberOfSendEncodings";
Amit Hilbuche2a284d2019-03-05 20:36:3192
Harald Alvestrand19793842018-06-25 10:03:5093static const int REPORT_USAGE_PATTERN_DELAY_MS = 60000;
94
Taylor Brandstettera1c30352016-05-13 15:15:1195uint32_t ConvertIceTransportTypeToCandidateFilter(
96 PeerConnectionInterface::IceTransportsType type) {
97 switch (type) {
98 case PeerConnectionInterface::kNone:
99 return cricket::CF_NONE;
100 case PeerConnectionInterface::kRelay:
101 return cricket::CF_RELAY;
102 case PeerConnectionInterface::kNoHost:
103 return (cricket::CF_ALL & ~cricket::CF_HOST);
104 case PeerConnectionInterface::kAll:
105 return cricket::CF_ALL;
106 default:
Artem Titovd3251962021-11-15 15:57:07107 RTC_DCHECK_NOTREACHED();
Taylor Brandstettera1c30352016-05-13 15:15:11108 }
109 return cricket::CF_NONE;
110}
111
Steve Anton75737c02017-11-06 18:37:17112IceCandidatePairType GetIceCandidatePairCounter(
113 const cricket::Candidate& local,
114 const cricket::Candidate& remote) {
115 const auto& l = local.type();
116 const auto& r = remote.type();
117 const auto& host = LOCAL_PORT_TYPE;
118 const auto& srflx = STUN_PORT_TYPE;
119 const auto& relay = RELAY_PORT_TYPE;
120 const auto& prflx = PRFLX_PORT_TYPE;
121 if (l == host && r == host) {
Jeroen de Borst833979f2018-12-13 16:25:54122 bool local_hostname =
123 !local.address().hostname().empty() && local.address().IsUnresolvedIP();
124 bool remote_hostname = !remote.address().hostname().empty() &&
125 remote.address().IsUnresolvedIP();
Steve Anton75737c02017-11-06 18:37:17126 bool local_private = IPIsPrivate(local.address().ipaddr());
127 bool remote_private = IPIsPrivate(remote.address().ipaddr());
Jeroen de Borst833979f2018-12-13 16:25:54128 if (local_hostname) {
129 if (remote_hostname) {
130 return kIceCandidatePairHostNameHostName;
131 } else if (remote_private) {
132 return kIceCandidatePairHostNameHostPrivate;
133 } else {
134 return kIceCandidatePairHostNameHostPublic;
135 }
136 } else if (local_private) {
137 if (remote_hostname) {
138 return kIceCandidatePairHostPrivateHostName;
139 } else if (remote_private) {
Steve Anton75737c02017-11-06 18:37:17140 return kIceCandidatePairHostPrivateHostPrivate;
141 } else {
142 return kIceCandidatePairHostPrivateHostPublic;
143 }
144 } else {
Jeroen de Borst833979f2018-12-13 16:25:54145 if (remote_hostname) {
146 return kIceCandidatePairHostPublicHostName;
147 } else if (remote_private) {
Steve Anton75737c02017-11-06 18:37:17148 return kIceCandidatePairHostPublicHostPrivate;
149 } else {
150 return kIceCandidatePairHostPublicHostPublic;
151 }
152 }
153 }
154 if (l == host && r == srflx)
155 return kIceCandidatePairHostSrflx;
156 if (l == host && r == relay)
157 return kIceCandidatePairHostRelay;
158 if (l == host && r == prflx)
159 return kIceCandidatePairHostPrflx;
160 if (l == srflx && r == host)
161 return kIceCandidatePairSrflxHost;
162 if (l == srflx && r == srflx)
163 return kIceCandidatePairSrflxSrflx;
164 if (l == srflx && r == relay)
165 return kIceCandidatePairSrflxRelay;
166 if (l == srflx && r == prflx)
167 return kIceCandidatePairSrflxPrflx;
168 if (l == relay && r == host)
169 return kIceCandidatePairRelayHost;
170 if (l == relay && r == srflx)
171 return kIceCandidatePairRelaySrflx;
172 if (l == relay && r == relay)
173 return kIceCandidatePairRelayRelay;
174 if (l == relay && r == prflx)
175 return kIceCandidatePairRelayPrflx;
176 if (l == prflx && r == host)
177 return kIceCandidatePairPrflxHost;
178 if (l == prflx && r == srflx)
179 return kIceCandidatePairPrflxSrflx;
180 if (l == prflx && r == relay)
181 return kIceCandidatePairPrflxRelay;
182 return kIceCandidatePairMax;
183}
184
Danil Chapovalov66cadcc2018-06-19 14:47:43185absl::optional<int> RTCConfigurationToIceConfigOptionalInt(
Qingsi Wang866e08d2018-03-23 00:54:23186 int rtc_configuration_parameter) {
187 if (rtc_configuration_parameter ==
188 webrtc::PeerConnectionInterface::RTCConfiguration::kUndefined) {
Danil Chapovalov66cadcc2018-06-19 14:47:43189 return absl::nullopt;
Qingsi Wang866e08d2018-03-23 00:54:23190 }
191 return rtc_configuration_parameter;
192}
193
Jonas Orelande3096512020-05-27 07:01:05194// Check if the changes of IceTransportsType motives an ice restart.
195bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,
196 PeerConnectionInterface::IceTransportsType current,
197 PeerConnectionInterface::IceTransportsType modified) {
198 if (current == modified) {
199 return false;
200 }
201
202 if (!surface_ice_candidates_on_ice_transport_type_changed) {
203 return true;
204 }
205
206 auto current_filter = ConvertIceTransportTypeToCandidateFilter(current);
207 auto modified_filter = ConvertIceTransportTypeToCandidateFilter(modified);
208
209 // If surface_ice_candidates_on_ice_transport_type_changed is true and we
210 // extend the filter, then no ice restart is needed.
211 return (current_filter & modified_filter) != current_filter;
212}
213
Harald Alvestrand62166932020-10-26 08:30:41214cricket::IceConfig ParseIceConfig(
215 const PeerConnectionInterface::RTCConfiguration& config) {
216 cricket::ContinualGatheringPolicy gathering_policy;
217 switch (config.continual_gathering_policy) {
218 case PeerConnectionInterface::GATHER_ONCE:
219 gathering_policy = cricket::GATHER_ONCE;
220 break;
221 case PeerConnectionInterface::GATHER_CONTINUALLY:
222 gathering_policy = cricket::GATHER_CONTINUALLY;
223 break;
224 default:
Artem Titovd3251962021-11-15 15:57:07225 RTC_DCHECK_NOTREACHED();
Harald Alvestrand62166932020-10-26 08:30:41226 gathering_policy = cricket::GATHER_ONCE;
227 }
228
229 cricket::IceConfig ice_config;
230 ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt(
231 config.ice_connection_receiving_timeout);
232 ice_config.prioritize_most_likely_candidate_pairs =
233 config.prioritize_most_likely_ice_candidate_pairs;
234 ice_config.backup_connection_ping_interval =
235 RTCConfigurationToIceConfigOptionalInt(
236 config.ice_backup_candidate_pair_ping_interval);
237 ice_config.continual_gathering_policy = gathering_policy;
238 ice_config.presume_writable_when_fully_relayed =
239 config.presume_writable_when_fully_relayed;
240 ice_config.surface_ice_candidates_on_ice_transport_type_changed =
241 config.surface_ice_candidates_on_ice_transport_type_changed;
242 ice_config.ice_check_interval_strong_connectivity =
243 config.ice_check_interval_strong_connectivity;
244 ice_config.ice_check_interval_weak_connectivity =
245 config.ice_check_interval_weak_connectivity;
246 ice_config.ice_check_min_interval = config.ice_check_min_interval;
247 ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout;
248 ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks;
249 ice_config.ice_inactive_timeout = config.ice_inactive_timeout;
250 ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
251 ice_config.network_preference = config.network_preference;
Derek Bailey6c127a12021-04-15 19:42:41252 ice_config.stable_writable_connection_ping_interval =
253 config.stable_writable_connection_ping_interval_ms;
Harald Alvestrand62166932020-10-26 08:30:41254 return ice_config;
255}
256
257// Ensures the configuration doesn't have any parameters with invalid values,
258// or values that conflict with other parameters.
259//
260// Returns RTCError::OK() if there are no issues.
261RTCError ValidateConfiguration(
262 const PeerConnectionInterface::RTCConfiguration& config) {
263 return cricket::P2PTransportChannel::ValidateIceConfig(
264 ParseIceConfig(config));
265}
266
267bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) {
268 return content->media_description()->rtcp_mux();
269}
270
Tommic3257d02021-02-10 17:40:08271bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration,
272 const PeerConnectionFactoryInterface::Options& options,
273 const PeerConnectionDependencies& dependencies) {
274 if (options.disable_encryption)
275 return false;
276
277 // Enable DTLS by default if we have an identity store or a certificate.
278 bool default_enabled =
279 (dependencies.cert_generator || !configuration.certificates.empty());
280
Harald Alvestrandca327932022-04-04 15:37:31281#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06282 // The `configuration` can override the default value.
283 return configuration.enable_dtls_srtp.value_or(default_enabled);
Harald Alvestrandca327932022-04-04 15:37:31284#else
285 return default_enabled;
286#endif
Tommic3257d02021-02-10 17:40:08287}
288
Steve Anton75737c02017-11-06 18:37:17289} // namespace
290
deadbeef293e9262017-01-11 20:28:30291bool PeerConnectionInterface::RTCConfiguration::operator==(
292 const PeerConnectionInterface::RTCConfiguration& o) const {
293 // This static_assert prevents us from accidentally breaking operator==.
Steve Anton300bf8e2017-07-14 17:13:10294 // Note: Order matters! Fields must be ordered the same as RTCConfiguration.
deadbeef293e9262017-01-11 20:28:30295 struct stuff_being_tested_for_equality {
Magnus Jedvert3beb2072017-07-14 14:23:56296 IceServers servers;
Steve Anton300bf8e2017-07-14 17:13:10297 IceTransportsType type;
deadbeef293e9262017-01-11 20:28:30298 BundlePolicy bundle_policy;
299 RtcpMuxPolicy rtcp_mux_policy;
Steve Anton300bf8e2017-07-14 17:13:10300 std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
301 int ice_candidate_pool_size;
Steve Anton300bf8e2017-07-14 17:13:10302 bool disable_ipv6_on_wifi;
deadbeefd21eab3e2017-07-26 23:50:11303 int max_ipv6_networks;
Daniel Lazarenko2870b0a2018-01-25 09:30:22304 bool disable_link_local_networks;
Danil Chapovalov66cadcc2018-06-19 14:47:43305 absl::optional<int> screencast_min_bitrate;
Harald Alvestrandca327932022-04-04 15:37:31306#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06307 absl::optional<bool> enable_dtls_srtp;
Harald Alvestrandca327932022-04-04 15:37:31308#endif
deadbeef293e9262017-01-11 20:28:30309 TcpCandidatePolicy tcp_candidate_policy;
310 CandidateNetworkPolicy candidate_network_policy;
311 int audio_jitter_buffer_max_packets;
312 bool audio_jitter_buffer_fast_accelerate;
Jakob Ivarsson10403ae2018-11-27 14:45:20313 int audio_jitter_buffer_min_delay_ms;
deadbeef293e9262017-01-11 20:28:30314 int ice_connection_receiving_timeout;
315 int ice_backup_candidate_pair_ping_interval;
316 ContinualGatheringPolicy continual_gathering_policy;
deadbeef293e9262017-01-11 20:28:30317 bool prioritize_most_likely_ice_candidate_pairs;
318 struct cricket::MediaConfig media_config;
deadbeef293e9262017-01-11 20:28:30319 bool prune_turn_ports;
Honghai Zhangf8998cf2019-10-14 18:27:50320 PortPrunePolicy turn_port_prune_policy;
deadbeef293e9262017-01-11 20:28:30321 bool presume_writable_when_fully_relayed;
322 bool enable_ice_renomination;
323 bool redetermine_role_on_ice_restart;
Qingsi Wang1fe119f2019-05-31 23:55:33324 bool surface_ice_candidates_on_ice_transport_type_changed;
Danil Chapovalov66cadcc2018-06-19 14:47:43325 absl::optional<int> ice_check_interval_strong_connectivity;
326 absl::optional<int> ice_check_interval_weak_connectivity;
327 absl::optional<int> ice_check_min_interval;
328 absl::optional<int> ice_unwritable_timeout;
329 absl::optional<int> ice_unwritable_min_checks;
Jiawei Ou9d4fd5552018-12-07 07:30:17330 absl::optional<int> ice_inactive_timeout;
Danil Chapovalov66cadcc2018-06-19 14:47:43331 absl::optional<int> stun_candidate_keepalive_interval;
Jonas Orelandbdcee282017-10-10 12:01:40332 webrtc::TurnCustomizer* turn_customizer;
Steve Anton79e79602017-11-20 18:25:56333 SdpSemantics sdp_semantics;
Danil Chapovalov66cadcc2018-06-19 14:47:43334 absl::optional<rtc::AdapterType> network_preference;
Zhi Huangb57e1692018-06-12 18:41:11335 bool active_reset_srtp_params;
Benjamin Wright8c27cca2018-10-25 17:16:44336 absl::optional<CryptoOptions> crypto_options;
Johannes Kron89f874e2018-11-12 09:25:48337 bool offer_extmap_allow_mixed;
Jonas Oreland3c028422019-08-22 14:16:35338 std::string turn_logging_id;
Eldar Rello5ab79e62019-10-09 15:29:44339 bool enable_implicit_rollback;
philipel16cec3b2019-10-25 10:23:02340 absl::optional<bool> allow_codec_switching;
Harald Alvestrand62166932020-10-26 08:30:41341 absl::optional<int> report_usage_pattern_delay_ms;
Derek Bailey6c127a12021-04-15 19:42:41342 absl::optional<int> stable_writable_connection_ping_interval_ms;
Jonas Orelandc8fa1ee2021-08-25 06:58:04343 webrtc::VpnPreference vpn_preference;
Jonas Oreland2ee0e642021-08-25 13:43:02344 std::vector<rtc::NetworkMask> vpn_list;
Niels Möller73d07742021-12-02 12:58:01345 PortAllocatorConfig port_allocator_config;
Henrik Boströmcf2856b2022-11-15 08:23:19346 absl::optional<TimeDelta> pacer_burst_interval;
deadbeef293e9262017-01-11 20:28:30347 };
348 static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
349 "Did you add something to RTCConfiguration and forget to "
350 "update operator==?");
351 return type == o.type && servers == o.servers &&
352 bundle_policy == o.bundle_policy &&
353 rtcp_mux_policy == o.rtcp_mux_policy &&
354 tcp_candidate_policy == o.tcp_candidate_policy &&
355 candidate_network_policy == o.candidate_network_policy &&
356 audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
357 audio_jitter_buffer_fast_accelerate ==
358 o.audio_jitter_buffer_fast_accelerate &&
Jakob Ivarsson10403ae2018-11-27 14:45:20359 audio_jitter_buffer_min_delay_ms ==
360 o.audio_jitter_buffer_min_delay_ms &&
deadbeef293e9262017-01-11 20:28:30361 ice_connection_receiving_timeout ==
362 o.ice_connection_receiving_timeout &&
363 ice_backup_candidate_pair_ping_interval ==
364 o.ice_backup_candidate_pair_ping_interval &&
365 continual_gathering_policy == o.continual_gathering_policy &&
366 certificates == o.certificates &&
367 prioritize_most_likely_ice_candidate_pairs ==
368 o.prioritize_most_likely_ice_candidate_pairs &&
Henrik Boström24e03372022-10-27 11:49:10369 media_config == o.media_config &&
zhihuangb09b3f92017-03-07 22:40:51370 disable_ipv6_on_wifi == o.disable_ipv6_on_wifi &&
deadbeefd21eab3e2017-07-26 23:50:11371 max_ipv6_networks == o.max_ipv6_networks &&
Daniel Lazarenko2870b0a2018-01-25 09:30:22372 disable_link_local_networks == o.disable_link_local_networks &&
deadbeef293e9262017-01-11 20:28:30373 screencast_min_bitrate == o.screencast_min_bitrate &&
Harald Alvestrandca327932022-04-04 15:37:31374#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06375 enable_dtls_srtp == o.enable_dtls_srtp &&
Harald Alvestrandca327932022-04-04 15:37:31376#endif
deadbeef293e9262017-01-11 20:28:30377 ice_candidate_pool_size == o.ice_candidate_pool_size &&
378 prune_turn_ports == o.prune_turn_ports &&
Honghai Zhangf8998cf2019-10-14 18:27:50379 turn_port_prune_policy == o.turn_port_prune_policy &&
deadbeef293e9262017-01-11 20:28:30380 presume_writable_when_fully_relayed ==
381 o.presume_writable_when_fully_relayed &&
382 enable_ice_renomination == o.enable_ice_renomination &&
skvlad51072462017-02-02 19:50:14383 redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
Qingsi Wang1fe119f2019-05-31 23:55:33384 surface_ice_candidates_on_ice_transport_type_changed ==
385 o.surface_ice_candidates_on_ice_transport_type_changed &&
Qingsi Wange6826d22018-03-08 22:55:14386 ice_check_interval_strong_connectivity ==
387 o.ice_check_interval_strong_connectivity &&
388 ice_check_interval_weak_connectivity ==
389 o.ice_check_interval_weak_connectivity &&
Steve Anton300bf8e2017-07-14 17:13:10390 ice_check_min_interval == o.ice_check_min_interval &&
Qingsi Wang22e623a2018-03-13 17:53:57391 ice_unwritable_timeout == o.ice_unwritable_timeout &&
392 ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
Jiawei Ou9d4fd5552018-12-07 07:30:17393 ice_inactive_timeout == o.ice_inactive_timeout &&
Qingsi Wangdb53f8e2018-02-20 22:45:49394 stun_candidate_keepalive_interval ==
395 o.stun_candidate_keepalive_interval &&
Steve Anton79e79602017-11-20 18:25:56396 turn_customizer == o.turn_customizer &&
Qingsi Wang9a5c6f82018-02-01 18:38:40397 sdp_semantics == o.sdp_semantics &&
Zhi Huangb57e1692018-06-12 18:41:11398 network_preference == o.network_preference &&
Piotr (Peter) Slatalae0c2e972018-10-08 16:43:21399 active_reset_srtp_params == o.active_reset_srtp_params &&
Johannes Kron89f874e2018-11-12 09:25:48400 crypto_options == o.crypto_options &&
Jonas Oreland3c028422019-08-22 14:16:35401 offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
Eldar Rello5ab79e62019-10-09 15:29:44402 turn_logging_id == o.turn_logging_id &&
philipel16cec3b2019-10-25 10:23:02403 enable_implicit_rollback == o.enable_implicit_rollback &&
Harald Alvestrand62166932020-10-26 08:30:41404 allow_codec_switching == o.allow_codec_switching &&
Derek Bailey6c127a12021-04-15 19:42:41405 report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms &&
406 stable_writable_connection_ping_interval_ms ==
Jonas Orelandc8fa1ee2021-08-25 06:58:04407 o.stable_writable_connection_ping_interval_ms &&
Niels Möller73d07742021-12-02 12:58:01408 vpn_preference == o.vpn_preference && vpn_list == o.vpn_list &&
409 port_allocator_config.min_port == o.port_allocator_config.min_port &&
410 port_allocator_config.max_port == o.port_allocator_config.max_port &&
Henrik Boströmcf2856b2022-11-15 08:23:19411 port_allocator_config.flags == o.port_allocator_config.flags &&
412 pacer_burst_interval == o.pacer_burst_interval;
deadbeef293e9262017-01-11 20:28:30413}
414
415bool PeerConnectionInterface::RTCConfiguration::operator!=(
416 const PeerConnectionInterface::RTCConfiguration& o) const {
417 return !(*this == o);
deadbeef3edec7c2016-12-10 19:44:26418}
419
Harald Alvestranda3dd7722020-11-27 08:05:42420RTCErrorOr<rtc::scoped_refptr<PeerConnection>> PeerConnection::Create(
Harald Alvestrand62166932020-10-26 08:30:41421 rtc::scoped_refptr<ConnectionContext> context,
Harald Alvestrand4da4a872020-11-04 10:34:21422 const PeerConnectionFactoryInterface::Options& options,
Harald Alvestrand62166932020-10-26 08:30:41423 std::unique_ptr<RtcEventLog> event_log,
424 std::unique_ptr<Call> call,
425 const PeerConnectionInterface::RTCConfiguration& configuration,
426 PeerConnectionDependencies dependencies) {
Henrik Boström62995db2022-01-03 08:58:10427 // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
Henrik Boström6d2fe892022-01-21 08:51:07428 if (configuration.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
429 RTC_LOG(LS_WARNING)
430 << "PeerConnection constructed with legacy SDP semantics!";
431 }
Henrik Boström62995db2022-01-03 08:58:10432
Harald Alvestrand62166932020-10-26 08:30:41433 RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
434 ParseIceConfig(configuration));
435 if (!config_error.ok()) {
Harald Alvestranda3dd7722020-11-27 08:05:42436 RTC_LOG(LS_ERROR) << "Invalid ICE configuration: "
437 << config_error.message();
438 return config_error;
Harald Alvestrand62166932020-10-26 08:30:41439 }
440
441 if (!dependencies.allocator) {
442 RTC_LOG(LS_ERROR)
443 << "PeerConnection initialized without a PortAllocator? "
444 "This shouldn't happen if using PeerConnectionFactory.";
Harald Alvestranda3dd7722020-11-27 08:05:42445 return RTCError(
446 RTCErrorType::INVALID_PARAMETER,
447 "Attempt to create a PeerConnection without a PortAllocatorFactory");
Harald Alvestrand62166932020-10-26 08:30:41448 }
449
450 if (!dependencies.observer) {
451 // TODO(deadbeef): Why do we do this?
452 RTC_LOG(LS_ERROR) << "PeerConnection initialized without a "
453 "PeerConnectionObserver";
Harald Alvestranda3dd7722020-11-27 08:05:42454 return RTCError(RTCErrorType::INVALID_PARAMETER,
455 "Attempt to create a PeerConnection without an observer");
Harald Alvestrand62166932020-10-26 08:30:41456 }
457
458 bool is_unified_plan =
459 configuration.sdp_semantics == SdpSemantics::kUnifiedPlan;
Tommic3257d02021-02-10 17:40:08460 bool dtls_enabled = DtlsEnabled(configuration, options, dependencies);
Harald Alvestrand0ccfbd22021-04-08 07:25:04461
462 // Interim code: If an AsyncResolverFactory is given, but not an
463 // AsyncDnsResolverFactory, wrap it in a WrappingAsyncDnsResolverFactory
Harald Alvestrandb8617d12023-08-23 09:01:53464 // If neither is given, create a BasicAsyncDnsResolverFactory.
Harald Alvestrand0ccfbd22021-04-08 07:25:04465 // TODO(bugs.webrtc.org/12598): Remove code once all callers pass a
466 // AsyncDnsResolverFactory.
Harald Alvestrand4d25a772023-08-25 11:07:28467#pragma clang diagnostic push
468#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Harald Alvestrand0ccfbd22021-04-08 07:25:04469 if (dependencies.async_dns_resolver_factory &&
470 dependencies.async_resolver_factory) {
471 RTC_LOG(LS_ERROR)
472 << "Attempt to set both old and new type of DNS resolver factory";
473 return RTCError(RTCErrorType::INVALID_PARAMETER,
474 "Both old and new type of DNS resolver given");
475 }
Harald Alvestrand4d25a772023-08-25 11:07:28476 if (!dependencies.async_dns_resolver_factory) {
477 if (dependencies.async_resolver_factory) {
478 dependencies.async_dns_resolver_factory =
479 std::make_unique<WrappingAsyncDnsResolverFactory>(
480 std::move(dependencies.async_resolver_factory));
481 } else {
482 dependencies.async_dns_resolver_factory =
483 std::make_unique<BasicAsyncDnsResolverFactory>();
484 }
Harald Alvestrand0ccfbd22021-04-08 07:25:04485 }
Harald Alvestrand4d25a772023-08-25 11:07:28486#pragma clang diagnostic pop
Harald Alvestrand0ccfbd22021-04-08 07:25:04487
Harald Alvestrandfd9a8f82020-10-26 14:17:02488 // The PeerConnection constructor consumes some, but not all, dependencies.
Tommi87f70902021-04-27 12:43:08489 auto pc = rtc::make_ref_counted<PeerConnection>(
490 context, options, is_unified_plan, std::move(event_log), std::move(call),
491 dependencies, dtls_enabled);
Harald Alvestranda3dd7722020-11-27 08:05:42492 RTCError init_error = pc->Initialize(configuration, std::move(dependencies));
493 if (!init_error.ok()) {
494 RTC_LOG(LS_ERROR) << "PeerConnection initialization failed";
495 return init_error;
Harald Alvestrand62166932020-10-26 08:30:41496 }
497 return pc;
498}
499
Harald Alvestrand4da4a872020-11-04 10:34:21500PeerConnection::PeerConnection(
501 rtc::scoped_refptr<ConnectionContext> context,
502 const PeerConnectionFactoryInterface::Options& options,
503 bool is_unified_plan,
504 std::unique_ptr<RtcEventLog> event_log,
505 std::unique_ptr<Call> call,
Tommic3257d02021-02-10 17:40:08506 PeerConnectionDependencies& dependencies,
507 bool dtls_enabled)
Harald Alvestranda39689c2020-10-15 08:34:31508 : context_(context),
Jonas Oreland6c7f9842022-04-19 15:24:10509 trials_(std::move(dependencies.trials), &context->field_trials()),
Harald Alvestrand4da4a872020-11-04 10:34:21510 options_(options),
Harald Alvestrandfd9a8f82020-10-26 14:17:02511 observer_(dependencies.observer),
Harald Alvestrand62166932020-10-26 08:30:41512 is_unified_plan_(is_unified_plan),
zhihuang38ede132017-06-15 19:52:32513 event_log_(std::move(event_log)),
Karl Wibergb03ab712019-02-14 10:59:57514 event_log_ptr_(event_log_.get()),
Harald Alvestrand0ccfbd22021-04-08 07:25:04515 async_dns_resolver_factory_(
516 std::move(dependencies.async_dns_resolver_factory)),
Harald Alvestrandfd9a8f82020-10-26 14:17:02517 port_allocator_(std::move(dependencies.allocator)),
518 ice_transport_factory_(std::move(dependencies.ice_transport_factory)),
519 tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
Karl Wiberg6cab5c82019-03-26 08:57:01520 call_(std::move(call)),
Henrik Boström79b69802019-07-18 09:16:56521 call_ptr_(call_.get()),
Tomas Gunnarsson97a387d2021-03-29 19:04:29522 // RFC 3264: The numeric value of the session id and version in the
523 // o line MUST be representable with a "64 bit signed integer".
Artem Titov880fa812021-07-30 20:30:23524 // Due to this constraint session id `session_id_` is max limited to
Tomas Gunnarsson97a387d2021-03-29 19:04:29525 // LLONG_MAX.
526 session_id_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
Tommic3257d02021-02-10 17:40:08527 dtls_enabled_(dtls_enabled),
Harald Alvestrand1090e442020-10-05 07:01:09528 data_channel_controller_(this),
Lahiru Ginnaliya Gamathige70f9e242021-01-28 07:32:46529 message_handler_(signaling_thread()),
Tommic3257d02021-02-10 17:40:08530 weak_factory_(this) {
Danil Chapovalov9e09a1f2022-09-08 16:38:10531 worker_thread()->BlockingCall([this] {
Tommic3257d02021-02-10 17:40:08532 RTC_DCHECK_RUN_ON(worker_thread());
533 worker_thread_safety_ = PendingTaskSafetyFlag::Create();
534 if (!call_)
535 worker_thread_safety_->SetNotAlive();
536 });
537}
henrike@webrtc.org28e20752013-07-10 00:45:36538
539PeerConnection::~PeerConnection() {
Peter Boström1a9d6152015-12-08 21:15:17540 TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
Steve Anton4171afb2017-11-20 18:20:22541 RTC_DCHECK_RUN_ON(signaling_thread());
542
Harald Alvestrand9cd199d2020-10-27 07:10:43543 if (sdp_handler_) {
544 sdp_handler_->PrepareForShutdown();
545 }
Henrik Boströma3728d32019-10-28 11:09:49546
Tommi94774d42023-04-24 09:31:45547 // In case `Close()` wasn't called, always make sure the controller cancels
548 // potentially pending operations.
549 data_channel_controller_.PrepareForShutdown();
550
Steve Anton8af21862017-12-15 19:20:13551 // Need to stop transceivers before destroying the stats collector because
Henrik Boströmf7859892022-07-04 12:36:37552 // AudioRtpSender has a reference to the LegacyStatsCollector it will update
553 // when stopping.
Harald Alvestrande15fb152020-10-19 13:28:05554 if (rtp_manager()) {
555 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
556 transceiver->StopInternal();
557 }
Steve Anton8af21862017-12-15 19:20:13558 }
Steve Anton4171afb2017-11-20 18:20:22559
Henrik Boströmf7859892022-07-04 12:36:37560 legacy_stats_.reset(nullptr);
hbosb78306a2016-12-19 13:06:57561 if (stats_collector_) {
562 stats_collector_->WaitForPendingRequest();
563 stats_collector_ = nullptr;
564 }
Steve Anton75737c02017-11-06 18:37:17565
Harald Alvestrand9cd199d2020-10-27 07:10:43566 if (sdp_handler_) {
567 // Don't destroy BaseChannels until after stats has been cleaned up so that
568 // the last stats request can still read from the channels.
569 sdp_handler_->DestroyAllChannels();
Steve Anton8af21862017-12-15 19:20:13570
Harald Alvestrand9cd199d2020-10-27 07:10:43571 RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
Steve Anton75737c02017-11-06 18:37:17572
Harald Alvestrand9cd199d2020-10-27 07:10:43573 sdp_handler_->ResetSessionDescFactory();
574 }
Steve Anton75737c02017-11-06 18:37:17575
Tomas Gunnarsson92eebef2021-02-10 12:05:44576 // port_allocator_ and transport_controller_ live on the network thread and
577 // should be destroyed there.
Harald Alvestrandbc32c562022-02-09 12:08:47578 transport_controller_copy_ = nullptr;
Danil Chapovalov9e09a1f2022-09-08 16:38:10579 network_thread()->BlockingCall([this] {
Karl Wibergfb3be392019-03-22 13:13:22580 RTC_DCHECK_RUN_ON(network_thread());
Tommib00d63c2023-04-12 17:49:53581 TeardownDataChannelTransport_n(RTCError::OK());
Tomas Gunnarsson92eebef2021-02-10 12:05:44582 transport_controller_.reset();
Karl Wibergfb3be392019-03-22 13:13:22583 port_allocator_.reset();
Tommic3257d02021-02-10 17:40:08584 if (network_thread_safety_)
Tomas Gunnarsson92eebef2021-02-10 12:05:44585 network_thread_safety_->SetNotAlive();
Karl Wibergfb3be392019-03-22 13:13:22586 });
Tomas Gunnarssond69e0702021-04-07 13:14:43587
eladalon248fd4f2017-09-06 12:18:15588 // call_ and event_log_ must be destroyed on the worker thread.
Danil Chapovalov9e09a1f2022-09-08 16:38:10589 worker_thread()->BlockingCall([this] {
Karl Wibergb03ab712019-02-14 10:59:57590 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:08591 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 12:18:15592 call_.reset();
Qingsi Wang93a84392018-01-31 01:13:09593 // The event log must outlive call (and any other object that uses it).
eladalon248fd4f2017-09-06 12:18:15594 event_log_.reset();
595 });
Tommi52719652023-04-04 09:59:55596
597 data_channel_controller_.PrepareForShutdown();
henrike@webrtc.org28e20752013-07-10 00:45:36598}
599
Harald Alvestranda3dd7722020-11-27 08:05:42600RTCError PeerConnection::Initialize(
buildbot@webrtc.org41451d42014-05-03 05:39:45601 const PeerConnectionInterface::RTCConfiguration& configuration,
Benjamin Wrightcab588882018-05-02 22:12:47602 PeerConnectionDependencies dependencies) {
Karl Wiberg744310f2019-02-14 09:18:56603 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:17604 TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
Steve Anton038834f2017-07-14 22:59:59605
Harald Alvestrandb2a74782018-06-28 11:54:07606 cricket::ServerAddresses stun_servers;
607 std::vector<cricket::RelayServerConfig> turn_servers;
608
Philipp Hancke633dc2f2022-10-12 08:16:14609 RTCError parse_error = ParseIceServersOrError(configuration.servers,
610 &stun_servers, &turn_servers);
611 if (!parse_error.ok()) {
612 return parse_error;
Harald Alvestrandb2a74782018-06-28 11:54:07613 }
614
Philipp Hancke41a83572022-11-28 13:47:45615 // Restrict number of TURN servers.
Philipp Hancke3e224c72023-03-20 07:22:49616 if (turn_servers.size() > cricket::kMaxTurnServers) {
Philipp Hancke41a83572022-11-28 13:47:45617 RTC_LOG(LS_WARNING) << "Number of configured TURN servers is "
618 << turn_servers.size()
619 << " which exceeds the maximum allowed number of "
620 << cricket::kMaxTurnServers;
621 turn_servers.resize(cricket::kMaxTurnServers);
622 }
623
Jonas Oreland3c028422019-08-22 14:16:35624 // Add the turn logging id to all turn servers
625 for (cricket::RelayServerConfig& turn_server : turn_servers) {
626 turn_server.turn_logging_id = configuration.turn_logging_id;
627 }
628
Harald Alvestrandfd9a8f82020-10-26 14:17:02629 // Note if STUN or TURN servers were supplied.
Harald Alvestrandb2a74782018-06-28 11:54:07630 if (!stun_servers.empty()) {
631 NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
632 }
633 if (!turn_servers.empty()) {
634 NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
635 }
henrike@webrtc.org28e20752013-07-10 00:45:36636
Tommic3257d02021-02-10 17:40:08637 // Network thread initialization.
Jared Siskinbceec842023-04-20 21:10:51638 transport_controller_copy_ = network_thread()->BlockingCall([&] {
639 RTC_DCHECK_RUN_ON(network_thread());
640 network_thread_safety_ = PendingTaskSafetyFlag::Create();
641 InitializePortAllocatorResult pa_result =
642 InitializePortAllocator_n(stun_servers, turn_servers, configuration);
643 // Send information about IPv4/IPv6 status.
644 PeerConnectionAddressFamilyCounter address_family =
645 pa_result.enable_ipv6 ? kPeerConnection_IPv6 : kPeerConnection_IPv4;
646 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", address_family,
647 kPeerConnectionAddressFamilyCounter_Max);
648 return InitializeTransportController_n(configuration, dependencies);
649 });
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:45650
Steve Antonba818672017-11-06 18:21:57651 configuration_ = configuration;
652
Henrik Boströmf7859892022-07-04 12:36:37653 legacy_stats_ = std::make_unique<LegacyStatsCollector>(this);
Harald Alvestrande15fb152020-10-19 13:28:05654 stats_collector_ = RTCStatsCollector::Create(this);
655
Harald Alvestrand66c40362022-01-28 17:41:30656 sdp_handler_ = SdpOfferAnswerHandler::Create(this, configuration,
Niels Möllerafb246b2022-04-20 12:26:50657 dependencies, context_.get());
Harald Alvestrand9cd199d2020-10-27 07:10:43658
Artem Titovc6c02ef2022-05-09 08:30:09659 rtp_manager_ = std::make_unique<RtpTransmissionManager>(
Henrik Boströmf7859892022-07-04 12:36:37660 IsUnifiedPlan(), context_.get(), &usage_pattern_, observer_,
661 legacy_stats_.get(), [this]() {
Artem Titovc6c02ef2022-05-09 08:30:09662 RTC_DCHECK_RUN_ON(signaling_thread());
663 sdp_handler_->UpdateNegotiationNeeded();
664 });
Harald Alvestrande15fb152020-10-19 13:28:05665
Artem Titovc6c02ef2022-05-09 08:30:09666 // Add default audio/video transceivers for Plan B SDP.
667 if (!IsUnifiedPlan()) {
668 rtp_manager()->transceivers()->Add(
669 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Harald Alvestrandc3fa7c32022-05-22 10:57:01670 signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
671 cricket::MEDIA_TYPE_AUDIO, context())));
Artem Titovc6c02ef2022-05-09 08:30:09672 rtp_manager()->transceivers()->Add(
673 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Harald Alvestrandc3fa7c32022-05-22 10:57:01674 signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
675 cricket::MEDIA_TYPE_VIDEO, context())));
Steve Anton4171afb2017-11-20 18:20:22676 }
Harald Alvestrand763f5a92020-10-22 10:39:40677
Harald Alvestrand62166932020-10-26 08:30:41678 int delay_ms = configuration.report_usage_pattern_delay_ms
679 ? *configuration.report_usage_pattern_delay_ms
680 : REPORT_USAGE_PATTERN_DELAY_MS;
Harald Alvestrand1090e442020-10-05 07:01:09681 message_handler_.RequestUsagePatternReport(
682 [this]() {
683 RTC_DCHECK_RUN_ON(signaling_thread());
684 ReportUsagePattern();
685 },
686 delay_ms);
Jonas Orelanda3aa9bd2019-04-17 05:38:40687
Harald Alvestranda3dd7722020-11-27 08:05:42688 return RTCError::OK();
henrike@webrtc.org28e20752013-07-10 00:45:36689}
690
Harald Alvestrandbc32c562022-02-09 12:08:47691JsepTransportController* PeerConnection::InitializeTransportController_n(
Tommic3257d02021-02-10 17:40:08692 const RTCConfiguration& configuration,
693 const PeerConnectionDependencies& dependencies) {
694 JsepTransportController::Config config;
695 config.redetermine_role_on_ice_restart =
696 configuration.redetermine_role_on_ice_restart;
697 config.ssl_max_version = options_.ssl_max_version;
698 config.disable_encryption = options_.disable_encryption;
699 config.bundle_policy = configuration.bundle_policy;
700 config.rtcp_mux_policy = configuration.rtcp_mux_policy;
701 // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove
702 // this stub.
703 config.crypto_options = configuration.crypto_options.has_value()
704 ? *configuration.crypto_options
705 : options_.crypto_options;
706 config.transport_observer = this;
707 config.rtcp_handler = InitializeRtcpCallback();
Per Ke1e94ad2023-03-30 14:53:59708 config.un_demuxable_packet_handler = InitializeUnDemuxablePacketHandler();
Tommic3257d02021-02-10 17:40:08709 config.event_log = event_log_ptr_;
710#if defined(ENABLE_EXTERNAL_AUTH)
711 config.enable_external_auth = true;
712#endif
713 config.active_reset_srtp_params = configuration.active_reset_srtp_params;
714
715 // DTLS has to be enabled to use SCTP.
Florent Castelli516e2842021-04-19 13:29:50716 if (dtls_enabled_) {
Tommic3257d02021-02-10 17:40:08717 config.sctp_factory = context_->sctp_transport_factory();
718 }
719
720 config.ice_transport_factory = ice_transport_factory_.get();
721 config.on_dtls_handshake_error_ =
722 [weak_ptr = weak_factory_.GetWeakPtr()](rtc::SSLHandshakeError s) {
723 if (weak_ptr) {
724 weak_ptr->OnTransportControllerDtlsHandshakeError(s);
725 }
726 };
727
Jonas Oreland6c7f9842022-04-19 15:24:10728 config.field_trials = trials_.get();
Jonas Orelanded99dae2022-03-09 08:28:10729
Per Ke1e94ad2023-03-30 14:53:59730 transport_controller_.reset(new JsepTransportController(
731 network_thread(), port_allocator_.get(),
732 async_dns_resolver_factory_.get(), std::move(config)));
Tommic3257d02021-02-10 17:40:08733
734 transport_controller_->SubscribeIceConnectionState(
735 [this](cricket::IceConnectionState s) {
736 RTC_DCHECK_RUN_ON(network_thread());
737 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49738 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08739 RTC_DCHECK_RUN_ON(signaling_thread());
740 OnTransportControllerConnectionState(s);
741 }));
742 });
743 transport_controller_->SubscribeConnectionState(
744 [this](PeerConnectionInterface::PeerConnectionState s) {
745 RTC_DCHECK_RUN_ON(network_thread());
746 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49747 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08748 RTC_DCHECK_RUN_ON(signaling_thread());
749 SetConnectionState(s);
750 }));
751 });
752 transport_controller_->SubscribeStandardizedIceConnectionState(
753 [this](PeerConnectionInterface::IceConnectionState s) {
754 RTC_DCHECK_RUN_ON(network_thread());
755 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49756 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08757 RTC_DCHECK_RUN_ON(signaling_thread());
758 SetStandardizedIceConnectionState(s);
759 }));
760 });
761 transport_controller_->SubscribeIceGatheringState(
762 [this](cricket::IceGatheringState s) {
763 RTC_DCHECK_RUN_ON(network_thread());
764 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49765 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08766 RTC_DCHECK_RUN_ON(signaling_thread());
767 OnTransportControllerGatheringState(s);
768 }));
769 });
770 transport_controller_->SubscribeIceCandidateGathered(
771 [this](const std::string& transport,
772 const std::vector<cricket::Candidate>& candidates) {
773 RTC_DCHECK_RUN_ON(network_thread());
774 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49775 SafeTask(signaling_thread_safety_.flag(),
776 [this, t = transport, c = candidates]() {
777 RTC_DCHECK_RUN_ON(signaling_thread());
778 OnTransportControllerCandidatesGathered(t, c);
779 }));
Tommic3257d02021-02-10 17:40:08780 });
781 transport_controller_->SubscribeIceCandidateError(
782 [this](const cricket::IceCandidateErrorEvent& event) {
783 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalova30439b2022-07-07 08:08:49784 signaling_thread()->PostTask(
785 SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
Tommic3257d02021-02-10 17:40:08786 RTC_DCHECK_RUN_ON(signaling_thread());
787 OnTransportControllerCandidateError(event);
788 }));
789 });
790 transport_controller_->SubscribeIceCandidatesRemoved(
791 [this](const std::vector<cricket::Candidate>& c) {
792 RTC_DCHECK_RUN_ON(network_thread());
793 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49794 SafeTask(signaling_thread_safety_.flag(), [this, c = c]() {
Tommic3257d02021-02-10 17:40:08795 RTC_DCHECK_RUN_ON(signaling_thread());
796 OnTransportControllerCandidatesRemoved(c);
797 }));
798 });
799 transport_controller_->SubscribeIceCandidatePairChanged(
800 [this](const cricket::CandidatePairChangeEvent& event) {
801 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalova30439b2022-07-07 08:08:49802 signaling_thread()->PostTask(
803 SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
Tommic3257d02021-02-10 17:40:08804 RTC_DCHECK_RUN_ON(signaling_thread());
805 OnTransportControllerCandidateChanged(event);
806 }));
807 });
808
809 transport_controller_->SetIceConfig(ParseIceConfig(configuration));
Harald Alvestrandbc32c562022-02-09 12:08:47810 return transport_controller_.get();
Tommic3257d02021-02-10 17:40:08811}
812
Yves Gerey665174f2018-06-19 13:03:05813rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::local_streams() {
Karl Wiberg5966c502019-02-21 22:55:09814 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58815 RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
816 "Plan SdpSemantics. Please use GetSenders "
817 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43818 return sdp_handler_->local_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36819}
820
Yves Gerey665174f2018-06-19 13:03:05821rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
Karl Wiberg5966c502019-02-21 22:55:09822 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58823 RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
824 "Plan SdpSemantics. Please use GetReceivers "
825 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43826 return sdp_handler_->remote_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36827}
828
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29829bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 09:18:56830 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58831 RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
832 "SdpSemantics. Please use AddTrack instead.";
Peter Boström1a9d6152015-12-08 21:15:17833 TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
Harald Alvestrand35ba0c52022-05-05 07:37:41834 if (!ConfiguredForMedia()) {
835 RTC_LOG(LS_ERROR) << "AddStream: Not configured for media";
836 return false;
837 }
Harald Alvestrand9cd199d2020-10-27 07:10:43838 return sdp_handler_->AddStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36839}
840
841void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 09:18:56842 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41843 RTC_DCHECK(ConfiguredForMedia());
Steve Antonfc853712018-03-01 21:48:58844 RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified "
845 "Plan SdpSemantics. Please use RemoveTrack "
846 "instead.";
Peter Boström1a9d6152015-12-08 21:15:17847 TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
Harald Alvestrand9cd199d2020-10-27 07:10:43848 sdp_handler_->RemoveStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36849}
850
Steve Anton2d6c76a2018-01-06 01:10:52851RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
Steve Antonf9381f02017-12-14 18:23:57852 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 19:34:10853 const std::vector<std::string>& stream_ids) {
Jonas Oreland4b2a1062022-10-19 07:24:42854 return AddTrack(std::move(track), stream_ids, nullptr);
855}
856
857RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
858 rtc::scoped_refptr<MediaStreamTrackInterface> track,
859 const std::vector<std::string>& stream_ids,
860 const std::vector<RtpEncodingParameters>& init_send_encodings) {
861 return AddTrack(std::move(track), stream_ids, &init_send_encodings);
862}
863
864RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
865 rtc::scoped_refptr<MediaStreamTrackInterface> track,
866 const std::vector<std::string>& stream_ids,
867 const std::vector<RtpEncodingParameters>* init_send_encodings) {
Karl Wiberg744310f2019-02-14 09:18:56868 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton2d6c76a2018-01-06 01:10:52869 TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
Harald Alvestrand35ba0c52022-05-05 07:37:41870 if (!ConfiguredForMedia()) {
871 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
872 "Not configured for media");
873 }
Steve Antonf9381f02017-12-14 18:23:57874 if (!track) {
875 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Track is null.");
876 }
877 if (!(track->kind() == MediaStreamTrackInterface::kAudioKind ||
878 track->kind() == MediaStreamTrackInterface::kVideoKind)) {
879 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
880 "Track has invalid kind: " + track->kind());
881 }
Steve Antonf9381f02017-12-14 18:23:57882 if (IsClosed()) {
883 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
884 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 23:35:42885 }
Niels Möllerafb246b2022-04-20 12:26:50886 if (rtp_manager()->FindSenderForTrack(track.get())) {
Steve Antonf9381f02017-12-14 18:23:57887 LOG_AND_RETURN_ERROR(
888 RTCErrorType::INVALID_PARAMETER,
889 "Sender already exists for track " + track->id() + ".");
deadbeefe1f9d832016-01-14 23:35:42890 }
Jonas Oreland4b2a1062022-10-19 07:24:42891 auto sender_or_error =
892 rtp_manager()->AddTrack(track, stream_ids, init_send_encodings);
Steve Antonf9381f02017-12-14 18:23:57893 if (sender_or_error.ok()) {
Harald Alvestrand9cd199d2020-10-27 07:10:43894 sdp_handler_->UpdateNegotiationNeeded();
Henrik Boströmf7859892022-07-04 12:36:37895 legacy_stats_->AddTrack(track.get());
Steve Antonf9381f02017-12-14 18:23:57896 }
897 return sender_or_error;
898}
deadbeefe1f9d832016-01-14 23:35:42899
Harald Alvestrand09a0d012022-01-04 19:42:07900RTCError PeerConnection::RemoveTrackOrError(
Steve Antonf9381f02017-12-14 18:23:57901 rtc::scoped_refptr<RtpSenderInterface> sender) {
Karl Wiberg744310f2019-02-14 09:18:56902 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41903 if (!ConfiguredForMedia()) {
904 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
905 "Not configured for media");
906 }
Steve Antonf9381f02017-12-14 18:23:57907 if (!sender) {
908 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Sender is null.");
909 }
deadbeefe1f9d832016-01-14 23:35:42910 if (IsClosed()) {
Steve Antonf9381f02017-12-14 18:23:57911 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
912 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 23:35:42913 }
Steve Antonf9381f02017-12-14 18:23:57914 if (IsUnifiedPlan()) {
915 auto transceiver = FindTransceiverBySender(sender);
916 if (!transceiver || !sender->track()) {
917 return RTCError::OK();
918 }
919 sender->SetTrack(nullptr);
920 if (transceiver->direction() == RtpTransceiverDirection::kSendRecv) {
Steve Anton52d86772018-02-20 23:48:12921 transceiver->internal()->set_direction(
922 RtpTransceiverDirection::kRecvOnly);
Steve Antonf9381f02017-12-14 18:23:57923 } else if (transceiver->direction() == RtpTransceiverDirection::kSendOnly) {
Steve Anton52d86772018-02-20 23:48:12924 transceiver->internal()->set_direction(
925 RtpTransceiverDirection::kInactive);
Steve Antonf9381f02017-12-14 18:23:57926 }
Steve Anton4171afb2017-11-20 18:20:22927 } else {
Steve Antonf9381f02017-12-14 18:23:57928 bool removed;
929 if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
Harald Alvestrande15fb152020-10-19 13:28:05930 removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 12:26:50931 sender.get());
Steve Antonf9381f02017-12-14 18:23:57932 } else {
933 RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
Harald Alvestrande15fb152020-10-19 13:28:05934 removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 12:26:50935 sender.get());
Steve Antonf9381f02017-12-14 18:23:57936 }
937 if (!removed) {
938 LOG_AND_RETURN_ERROR(
939 RTCErrorType::INVALID_PARAMETER,
940 "Couldn't find sender " + sender->id() + " to remove.");
941 }
Steve Anton4171afb2017-11-20 18:20:22942 }
Harald Alvestrand9cd199d2020-10-27 07:10:43943 sdp_handler_->UpdateNegotiationNeeded();
Steve Antonf9381f02017-12-14 18:23:57944 return RTCError::OK();
945}
946
947rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
948PeerConnection::FindTransceiverBySender(
949 rtc::scoped_refptr<RtpSenderInterface> sender) {
Harald Alvestrande15fb152020-10-19 13:28:05950 return rtp_manager()->transceivers()->FindBySender(sender);
deadbeefe1f9d832016-01-14 23:35:42951}
952
Steve Anton9158ef62017-11-27 21:01:52953RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
954PeerConnection::AddTransceiver(
955 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
Harald Alvestrand35ba0c52022-05-05 07:37:41956 if (!ConfiguredForMedia()) {
957 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
958 "Not configured for media");
959 }
960
Steve Anton9158ef62017-11-27 21:01:52961 return AddTransceiver(track, RtpTransceiverInit());
962}
963
Tomas Gunnarsson92eebef2021-02-10 12:05:44964RtpTransportInternal* PeerConnection::GetRtpTransport(const std::string& mid) {
Harald Alvestrandbc32c562022-02-09 12:08:47965 // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
966 // This might be done by caching the value on the signaling thread.
Tomas Gunnarsson92eebef2021-02-10 12:05:44967 RTC_DCHECK_RUN_ON(signaling_thread());
Danil Chapovalov9e09a1f2022-09-08 16:38:10968 return network_thread()->BlockingCall([this, &mid] {
969 RTC_DCHECK_RUN_ON(network_thread());
970 auto rtp_transport = transport_controller_->GetRtpTransport(mid);
971 RTC_DCHECK(rtp_transport);
972 return rtp_transport;
973 });
Tomas Gunnarsson92eebef2021-02-10 12:05:44974}
975
Steve Anton9158ef62017-11-27 21:01:52976RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
977PeerConnection::AddTransceiver(
978 rtc::scoped_refptr<MediaStreamTrackInterface> track,
979 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 09:18:56980 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41981 if (!ConfiguredForMedia()) {
982 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
983 "Not configured for media");
984 }
Steve Antonfc853712018-03-01 21:48:58985 RTC_CHECK(IsUnifiedPlan())
986 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 21:01:52987 if (!track) {
988 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "track is null");
989 }
990 cricket::MediaType media_type;
991 if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
992 media_type = cricket::MEDIA_TYPE_AUDIO;
993 } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
994 media_type = cricket::MEDIA_TYPE_VIDEO;
995 } else {
996 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
997 "Track kind is not audio or video");
998 }
999 return AddTransceiver(media_type, track, init);
1000}
1001
1002RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1003PeerConnection::AddTransceiver(cricket::MediaType media_type) {
1004 return AddTransceiver(media_type, RtpTransceiverInit());
1005}
1006
1007RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1008PeerConnection::AddTransceiver(cricket::MediaType media_type,
1009 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 09:18:561010 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411011 if (!ConfiguredForMedia()) {
1012 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1013 "Not configured for media");
1014 }
Steve Antonfc853712018-03-01 21:48:581015 RTC_CHECK(IsUnifiedPlan())
1016 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 21:01:521017 if (!(media_type == cricket::MEDIA_TYPE_AUDIO ||
1018 media_type == cricket::MEDIA_TYPE_VIDEO)) {
1019 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1020 "media type is not audio or video");
1021 }
1022 return AddTransceiver(media_type, nullptr, init);
1023}
1024
1025RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1026PeerConnection::AddTransceiver(
1027 cricket::MediaType media_type,
1028 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Steve Anton22da89f2018-01-25 21:58:071029 const RtpTransceiverInit& init,
Guido Urdaneta70c2db12019-04-16 10:24:141030 bool update_negotiation_needed) {
Harald Alvestranda474fbf2020-10-01 16:47:231031 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411032 if (!ConfiguredForMedia()) {
1033 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1034 "Not configured for media");
1035 }
Steve Anton9158ef62017-11-27 21:01:521036 RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
1037 media_type == cricket::MEDIA_TYPE_VIDEO));
1038 if (track) {
1039 RTC_DCHECK_EQ(media_type,
1040 (track->kind() == MediaStreamTrackInterface::kAudioKind
1041 ? cricket::MEDIA_TYPE_AUDIO
1042 : cricket::MEDIA_TYPE_VIDEO));
1043 }
1044
Amit Hilbuche2a284d2019-03-05 20:36:311045 RTC_HISTOGRAM_COUNTS_LINEAR(kSimulcastNumberOfEncodings,
1046 init.send_encodings.size(), 0, 7, 8);
1047
Amit Hilbuchaa584152019-02-07 01:09:521048 size_t num_rids = absl::c_count_if(init.send_encodings,
1049 [](const RtpEncodingParameters& encoding) {
1050 return !encoding.rid.empty();
1051 });
1052 if (num_rids > 0 && num_rids != init.send_encodings.size()) {
Amit Hilbuchce470aa2019-02-07 01:09:521053 LOG_AND_RETURN_ERROR(
Amit Hilbuchaa584152019-02-07 01:09:521054 RTCErrorType::INVALID_PARAMETER,
1055 "RIDs must be provided for either all or none of the send encodings.");
Emircan Uysaler78323432019-02-08 20:41:391056 }
1057
Amit Hilbuchf4770402019-04-08 21:11:571058 if (num_rids > 0 && absl::c_any_of(init.send_encodings,
1059 [](const RtpEncodingParameters& encoding) {
1060 return !IsLegalRsidName(encoding.rid);
1061 })) {
1062 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1063 "Invalid RID value provided.");
1064 }
1065
Amit Hilbuchaa584152019-02-07 01:09:521066 if (absl::c_any_of(init.send_encodings,
1067 [](const RtpEncodingParameters& encoding) {
1068 return encoding.ssrc.has_value();
1069 })) {
1070 LOG_AND_RETURN_ERROR(
1071 RTCErrorType::UNSUPPORTED_PARAMETER,
1072 "Attempted to set an unimplemented parameter of RtpParameters.");
Florent Castelli892acf02018-10-01 20:47:201073 }
1074
1075 RtpParameters parameters;
1076 parameters.encodings = init.send_encodings;
Amit Hilbuchaa584152019-02-07 01:09:521077
1078 // Encodings are dropped from the tail if too many are provided.
Florent Castellie1b685a2021-04-30 17:11:371079 size_t max_simulcast_streams =
1080 media_type == cricket::MEDIA_TYPE_VIDEO ? kMaxSimulcastStreams : 1u;
1081 if (parameters.encodings.size() > max_simulcast_streams) {
Amit Hilbuchaa584152019-02-07 01:09:521082 parameters.encodings.erase(
Florent Castellie1b685a2021-04-30 17:11:371083 parameters.encodings.begin() + max_simulcast_streams,
Amit Hilbuchaa584152019-02-07 01:09:521084 parameters.encodings.end());
1085 }
1086
1087 // Single RID should be removed.
1088 if (parameters.encodings.size() == 1 &&
1089 !parameters.encodings[0].rid.empty()) {
1090 RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
1091 parameters.encodings[0].rid.clear();
1092 }
1093
1094 // If RIDs were not provided, they are generated for simulcast scenario.
1095 if (parameters.encodings.size() > 1 && num_rids == 0) {
1096 rtc::UniqueStringGenerator rid_generator;
1097 for (RtpEncodingParameters& encoding : parameters.encodings) {
Harald Alvestrand5ad491e2023-02-10 11:28:041098 encoding.rid = rid_generator.GenerateString();
Amit Hilbuchaa584152019-02-07 01:09:521099 }
1100 }
1101
Florent Castellibd1e5d52023-01-17 17:08:261102 // If no encoding parameters were provided, a default entry is created.
1103 if (parameters.encodings.empty()) {
1104 parameters.encodings.push_back({});
1105 }
1106
Florent Castelli892acf02018-10-01 20:47:201107 if (UnimplementedRtpParameterHasValue(parameters)) {
1108 LOG_AND_RETURN_ERROR(
1109 RTCErrorType::UNSUPPORTED_PARAMETER,
1110 "Attempted to set an unimplemented parameter of RtpParameters.");
1111 }
Steve Anton9158ef62017-11-27 21:01:521112
Florent Castelli725ee242022-10-18 15:05:581113 std::vector<cricket::VideoCodec> codecs;
Florent Castelli43a5dd82023-04-12 10:45:071114 // Gather the current codec capabilities to allow checking scalabilityMode and
1115 // codec selection against supported values.
Florent Castelli725ee242022-10-18 15:05:581116 if (media_type == cricket::MEDIA_TYPE_VIDEO) {
Florent Castelli725ee242022-10-18 15:05:581117 codecs = context_->media_engine()->video().send_codecs(false);
Florent Castelli43a5dd82023-04-12 10:45:071118 } else {
1119 codecs = context_->media_engine()->voice().send_codecs();
Florent Castelli725ee242022-10-18 15:05:581120 }
1121
Florent Castelli43a5dd82023-04-12 10:45:071122 auto result =
1123 cricket::CheckRtpParametersValues(parameters, codecs, absl::nullopt);
Florent Castellic1a0bcb2019-01-29 13:26:481124 if (!result.ok()) {
Florent Castelli43a5dd82023-04-12 10:45:071125 if (result.type() == RTCErrorType::INVALID_MODIFICATION) {
1126 result.set_type(RTCErrorType::UNSUPPORTED_OPERATION);
1127 }
Florent Castellic1a0bcb2019-01-29 13:26:481128 LOG_AND_RETURN_ERROR(result.type(), result.message());
1129 }
1130
Steve Anton3d954a62018-04-02 18:27:231131 RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
1132 << " transceiver in response to a call to AddTransceiver.";
Steve Anton07563732018-06-26 18:13:501133 // Set the sender ID equal to the track ID if the track is specified unless
1134 // that sender ID is already in use.
Harald Alvestrande15fb152020-10-19 13:28:051135 std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
1136 ? track->id()
1137 : rtc::CreateRandomUuid());
1138 auto sender = rtp_manager()->CreateSender(
1139 media_type, sender_id, track, init.stream_ids, parameters.encodings);
1140 auto receiver =
1141 rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
1142 auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
Steve Anton02ee47c2018-01-11 00:26:061143 transceiver->internal()->set_direction(init.direction);
1144
Guido Urdaneta70c2db12019-04-16 10:24:141145 if (update_negotiation_needed) {
Harald Alvestrand9cd199d2020-10-27 07:10:431146 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton22da89f2018-01-25 21:58:071147 }
Steve Antonf9381f02017-12-14 18:23:571148
1149 return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
1150}
1151
Steve Anton52d86772018-02-20 23:48:121152void PeerConnection::OnNegotiationNeeded() {
1153 RTC_DCHECK_RUN_ON(signaling_thread());
1154 RTC_DCHECK(!IsClosed());
Harald Alvestrand9cd199d2020-10-27 07:10:431155 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton52d86772018-02-20 23:48:121156}
1157
deadbeeffac06552015-11-25 19:26:011158rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
deadbeefbd7d8f72015-12-19 00:58:441159 const std::string& kind,
1160 const std::string& stream_id) {
Karl Wiberg5966c502019-02-21 22:55:091161 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411162 if (!ConfiguredForMedia()) {
1163 RTC_LOG(LS_ERROR) << "Not configured for media";
1164 return nullptr;
1165 }
Steve Antonfc853712018-03-01 21:48:581166 RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified "
1167 "Plan SdpSemantics. Please use AddTransceiver "
1168 "instead.";
Peter Boström1a9d6152015-12-08 21:15:171169 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
zhihuang29ff8442016-07-27 18:07:251170 if (IsClosed()) {
1171 return nullptr;
1172 }
Steve Anton4171afb2017-11-20 18:20:221173
Seth Hampson5b4f0752018-04-02 23:31:361174 // Internally we need to have one stream with Plan B semantics, so we
1175 // generate a random stream ID if not specified.
Seth Hampson845e8782018-03-02 19:34:101176 std::vector<std::string> stream_ids;
Seth Hampson5b4f0752018-04-02 23:31:361177 if (stream_id.empty()) {
1178 stream_ids.push_back(rtc::CreateRandomUuid());
1179 RTC_LOG(LS_INFO)
1180 << "No stream_id specified for sender. Generated stream ID: "
1181 << stream_ids[0];
1182 } else {
Seth Hampson845e8782018-03-02 19:34:101183 stream_ids.push_back(stream_id);
Steve Anton02ee47c2018-01-11 00:26:061184 }
1185
Steve Anton4171afb2017-11-20 18:20:221186 // TODO(steveanton): Move construction of the RtpSenders to RtpTransceiver.
deadbeefa601f5c2016-06-06 21:27:391187 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
deadbeeffac06552015-11-25 19:26:011188 if (kind == MediaStreamTrackInterface::kAudioKind) {
Henrik Boströmf7859892022-07-04 12:36:371189 auto audio_sender =
1190 AudioRtpSender::Create(worker_thread(), rtc::CreateRandomUuid(),
1191 legacy_stats_.get(), rtp_manager());
Harald Alvestrandc0d44d92022-12-13 12:57:241192 audio_sender->SetMediaChannel(rtp_manager()->voice_media_send_channel());
deadbeefa601f5c2016-06-06 21:27:391193 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-11 00:26:061194 signaling_thread(), audio_sender);
Harald Alvestrande15fb152020-10-19 13:28:051195 rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 19:26:011196 } else if (kind == MediaStreamTrackInterface::kVideoKind) {
Harald Alvestrande15fb152020-10-19 13:28:051197 auto video_sender = VideoRtpSender::Create(
1198 worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
Harald Alvestrandc0d44d92022-12-13 12:57:241199 video_sender->SetMediaChannel(rtp_manager()->video_media_send_channel());
deadbeefa601f5c2016-06-06 21:27:391200 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-11 00:26:061201 signaling_thread(), video_sender);
Harald Alvestrande15fb152020-10-19 13:28:051202 rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 19:26:011203 } else {
Mirko Bonadei675513b2017-11-09 10:09:251204 RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
Steve Anton4171afb2017-11-20 18:20:221205 return nullptr;
deadbeeffac06552015-11-25 19:26:011206 }
Henrik Andreasssoncc189172019-05-20 09:01:381207 new_sender->internal()->set_stream_ids(stream_ids);
Steve Anton4171afb2017-11-20 18:20:221208
deadbeefe1f9d832016-01-14 23:35:421209 return new_sender;
deadbeeffac06552015-11-25 19:26:011210}
1211
deadbeef70ab1a12015-09-28 23:53:551212std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
1213 const {
Karl Wiberga58e1692019-03-26 12:33:431214 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 21:27:391215 std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
Harald Alvestrand8101e7b2022-05-23 14:57:471216 if (ConfiguredForMedia()) {
1217 for (const auto& sender : rtp_manager()->GetSendersInternal()) {
1218 ret.push_back(sender);
1219 }
deadbeefa601f5c2016-06-06 21:27:391220 }
1221 return ret;
deadbeef70ab1a12015-09-28 23:53:551222}
1223
1224std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
1225PeerConnection::GetReceivers() const {
Karl Wiberga58e1692019-03-26 12:33:431226 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 21:27:391227 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
Harald Alvestrand8101e7b2022-05-23 14:57:471228 if (ConfiguredForMedia()) {
1229 for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
1230 ret.push_back(receiver);
1231 }
deadbeefa601f5c2016-06-06 21:27:391232 }
1233 return ret;
deadbeef70ab1a12015-09-28 23:53:551234}
1235
Steve Anton9158ef62017-11-27 21:01:521236std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
1237PeerConnection::GetTransceivers() const {
Karl Wiberg5966c502019-02-21 22:55:091238 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:581239 RTC_CHECK(IsUnifiedPlan())
1240 << "GetTransceivers is only supported with Unified Plan SdpSemantics.";
Steve Anton9158ef62017-11-27 21:01:521241 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
Harald Alvestrand8101e7b2022-05-23 14:57:471242 if (ConfiguredForMedia()) {
1243 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1244 all_transceivers.push_back(transceiver);
1245 }
Steve Anton9158ef62017-11-27 21:01:521246 }
1247 return all_transceivers;
1248}
1249
henrike@webrtc.org28e20752013-07-10 00:45:361250bool PeerConnection::GetStats(StatsObserver* observer,
wu@webrtc.orgb9a088b2014-02-13 23:18:491251 MediaStreamTrackInterface* track,
1252 StatsOutputLevel level) {
Henrik Boströmf7859892022-07-04 12:36:371253 TRACE_EVENT0("webrtc", "PeerConnection::GetStats (legacy)");
Karl Wiberg6cab5c82019-03-26 08:57:011254 RTC_DCHECK_RUN_ON(signaling_thread());
nisse7ce109a2017-01-31 08:57:561255 if (!observer) {
Henrik Boströmf7859892022-07-04 12:36:371256 RTC_LOG(LS_ERROR) << "Legacy GetStats - observer is NULL.";
henrike@webrtc.org28e20752013-07-10 00:45:361257 return false;
1258 }
1259
Tommife041642021-04-07 08:08:281260 RTC_LOG_THREAD_BLOCK_COUNT();
1261
Henrik Boströmf7859892022-07-04 12:36:371262 legacy_stats_->UpdateStats(level);
Tommi19015512022-02-02 10:49:351263
1264 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(4);
1265
Henrik Boströmf7859892022-07-04 12:36:371266 // The LegacyStatsCollector is used to tell if a track is valid because it may
zhihuange9e94c32016-11-04 18:38:151267 // remember tracks that the PeerConnection previously removed.
Henrik Boströmf7859892022-07-04 12:36:371268 if (track && !legacy_stats_->IsValidTrack(track->id())) {
1269 RTC_LOG(LS_WARNING) << "Legacy GetStats is called with an invalid track: "
Mirko Bonadei675513b2017-11-09 10:09:251270 << track->id();
zhihuange9e94c32016-11-04 18:38:151271 return false;
1272 }
Henrik Boströmf7859892022-07-04 12:36:371273 message_handler_.PostGetStats(observer, legacy_stats_.get(), track);
Tommife041642021-04-07 08:08:281274
henrike@webrtc.org28e20752013-07-10 00:45:361275 return true;
1276}
1277
hbos74e1a4f2016-09-16 06:33:011278void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
Henrik Boström1df1bf82018-03-20 12:24:201279 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011280 RTC_DCHECK_RUN_ON(signaling_thread());
hbos74e1a4f2016-09-16 06:33:011281 RTC_DCHECK(stats_collector_);
Henrik Boström1df1bf82018-03-20 12:24:201282 RTC_DCHECK(callback);
Tommife041642021-04-07 08:08:281283 RTC_LOG_THREAD_BLOCK_COUNT();
Niels Möllere7cc8832022-01-04 14:20:031284 stats_collector_->GetStatsReport(
1285 rtc::scoped_refptr<RTCStatsCollectorCallback>(callback));
Henrik Boström5023ffb2022-07-04 13:47:251286 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
hbos74e1a4f2016-09-16 06:33:011287}
1288
Henrik Boström1df1bf82018-03-20 12:24:201289void PeerConnection::GetStats(
1290 rtc::scoped_refptr<RtpSenderInterface> selector,
1291 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1292 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011293 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 12:24:201294 RTC_DCHECK(callback);
1295 RTC_DCHECK(stats_collector_);
Henrik Boström5023ffb2022-07-04 13:47:251296 RTC_LOG_THREAD_BLOCK_COUNT();
Henrik Boström1df1bf82018-03-20 12:24:201297 rtc::scoped_refptr<RtpSenderInternal> internal_sender;
1298 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:051299 for (const auto& proxy_transceiver :
1300 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 12:24:201301 for (const auto& proxy_sender :
1302 proxy_transceiver->internal()->senders()) {
1303 if (proxy_sender == selector) {
1304 internal_sender = proxy_sender->internal();
1305 break;
1306 }
1307 }
1308 if (internal_sender)
1309 break;
1310 }
1311 }
Artem Titov880fa812021-07-30 20:30:231312 // If there is no `internal_sender` then `selector` is either null or does not
Henrik Boström1df1bf82018-03-20 12:24:201313 // belong to the PeerConnection (in Plan B, senders can be removed from the
1314 // PeerConnection). This means that "all the stats objects representing the
1315 // selector" is an empty set. Invoking GetStatsReport() with a null selector
1316 // produces an empty stats report.
1317 stats_collector_->GetStatsReport(internal_sender, callback);
Henrik Boström5023ffb2022-07-04 13:47:251318 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
Henrik Boström1df1bf82018-03-20 12:24:201319}
1320
1321void PeerConnection::GetStats(
1322 rtc::scoped_refptr<RtpReceiverInterface> selector,
1323 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1324 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011325 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 12:24:201326 RTC_DCHECK(callback);
1327 RTC_DCHECK(stats_collector_);
Henrik Boström5023ffb2022-07-04 13:47:251328 RTC_LOG_THREAD_BLOCK_COUNT();
Henrik Boström1df1bf82018-03-20 12:24:201329 rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
1330 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:051331 for (const auto& proxy_transceiver :
1332 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 12:24:201333 for (const auto& proxy_receiver :
1334 proxy_transceiver->internal()->receivers()) {
1335 if (proxy_receiver == selector) {
1336 internal_receiver = proxy_receiver->internal();
1337 break;
1338 }
1339 }
1340 if (internal_receiver)
1341 break;
1342 }
1343 }
Artem Titov880fa812021-07-30 20:30:231344 // If there is no `internal_receiver` then `selector` is either null or does
Henrik Boström1df1bf82018-03-20 12:24:201345 // not belong to the PeerConnection (in Plan B, receivers can be removed from
1346 // the PeerConnection). This means that "all the stats objects representing
1347 // the selector" is an empty set. Invoking GetStatsReport() with a null
1348 // selector produces an empty stats report.
1349 stats_collector_->GetStatsReport(internal_receiver, callback);
Henrik Boström5023ffb2022-07-04 13:47:251350 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
Henrik Boström1df1bf82018-03-20 12:24:201351}
1352
henrike@webrtc.org28e20752013-07-10 00:45:361353PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071354 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431355 return sdp_handler_->signaling_state();
henrike@webrtc.org28e20752013-07-10 00:45:361356}
1357
henrike@webrtc.org28e20752013-07-10 00:45:361358PeerConnectionInterface::IceConnectionState
1359PeerConnection::ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071360 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:361361 return ice_connection_state_;
1362}
1363
Alex Loiko9289eda2018-11-23 16:18:591364PeerConnectionInterface::IceConnectionState
1365PeerConnection::standardized_ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071366 RTC_DCHECK_RUN_ON(signaling_thread());
Alex Loiko9289eda2018-11-23 16:18:591367 return standardized_ice_connection_state_;
1368}
1369
Jonas Olsson635474e2018-10-18 13:58:171370PeerConnectionInterface::PeerConnectionState
1371PeerConnection::peer_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071372 RTC_DCHECK_RUN_ON(signaling_thread());
Jonas Olsson635474e2018-10-18 13:58:171373 return connection_state_;
1374}
1375
henrike@webrtc.org28e20752013-07-10 00:45:361376PeerConnectionInterface::IceGatheringState
1377PeerConnection::ice_gathering_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071378 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:361379 return ice_gathering_state_;
1380}
1381
Harald Alvestrand61f74d92020-03-02 10:20:001382absl::optional<bool> PeerConnection::can_trickle_ice_candidates() {
1383 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandcdcfab02020-09-28 13:02:071384 const SessionDescriptionInterface* description = current_remote_description();
Harald Alvestrand61f74d92020-03-02 10:20:001385 if (!description) {
Harald Alvestrandcdcfab02020-09-28 13:02:071386 description = pending_remote_description();
Harald Alvestrand61f74d92020-03-02 10:20:001387 }
1388 if (!description) {
1389 return absl::nullopt;
1390 }
1391 // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
1392 if (description->description()->transport_infos().size() < 1) {
1393 return absl::nullopt;
1394 }
1395 return description->description()->transport_infos()[0].description.HasOption(
1396 "trickle");
1397}
1398
Harald Alvestranda9af50f2021-05-21 13:33:511399RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>
1400PeerConnection::CreateDataChannelOrError(const std::string& label,
1401 const DataChannelInit* config) {
Karl Wiberg106d92d2019-02-14 09:17:471402 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171403 TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
zhihuang9763d562016-08-05 18:14:501404
Tommi4f7ade52023-03-29 18:46:591405 if (IsClosed()) {
1406 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1407 "CreateDataChannelOrError: PeerConnection is closed.");
1408 }
1409
Harald Alvestrand5da3eb02023-03-15 20:39:421410 bool first_datachannel = !data_channel_controller_.HasUsedDataChannels();
jiayl@webrtc.org001fd2d2014-05-29 15:31:111411
Tommi335d0842023-03-25 09:56:181412 InternalDataChannelInit internal_config;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:581413 if (config) {
Tommi335d0842023-03-25 09:56:181414 internal_config = InternalDataChannelInit(*config);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:581415 }
Tommi335d0842023-03-25 09:56:181416
1417 internal_config.fallback_ssl_role = sdp_handler_->GuessSslRole();
Tommi4f7ade52023-03-29 18:46:591418 RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>> ret =
Taylor Brandstetter3a034e12020-07-09 22:32:341419 data_channel_controller_.InternalCreateDataChannelWithProxy(
Tommi4f7ade52023-03-29 18:46:591420 label, internal_config);
1421 if (!ret.ok()) {
1422 return ret.MoveError();
deadbeefab9b2d12015-10-14 18:33:111423 }
henrike@webrtc.org28e20752013-07-10 00:45:361424
Tommi4f7ade52023-03-29 18:46:591425 rtc::scoped_refptr<DataChannelInterface> channel = ret.MoveValue();
1426
Philipp Hancke522380f2023-05-09 07:41:031427 // Check the onRenegotiationNeeded event (with plan-b backward compat)
1428 if (configuration_.sdp_semantics == SdpSemantics::kUnifiedPlan ||
1429 (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED &&
1430 first_datachannel)) {
Harald Alvestrand9cd199d2020-10-27 07:10:431431 sdp_handler_->UpdateNegotiationNeeded();
jiayl@webrtc.org001fd2d2014-05-29 15:31:111432 }
Harald Alvestrand8ebba742018-05-31 12:00:341433 NoteUsageEvent(UsageEvent::DATA_ADDED);
Taylor Brandstetter3a034e12020-07-09 22:32:341434 return channel;
henrike@webrtc.org28e20752013-07-10 00:45:361435}
1436
Henrik Boström79b69802019-07-18 09:16:561437void PeerConnection::RestartIce() {
1438 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431439 sdp_handler_->RestartIce();
Henrik Boström79b69802019-07-18 09:16:561440}
1441
henrike@webrtc.org28e20752013-07-10 00:45:361442void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:161443 const RTCOfferAnswerOptions& options) {
Karl Wiberg5966c502019-02-21 22:55:091444 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431445 sdp_handler_->CreateOffer(observer, options);
Henrik Boströma3728d32019-10-28 11:09:491446}
1447
Harald Alvestrandcdcfab02020-09-28 13:02:071448void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
1449 const RTCOfferAnswerOptions& options) {
Henrik Boströma3728d32019-10-28 11:09:491450 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431451 sdp_handler_->CreateAnswer(observer, options);
henrike@webrtc.org28e20752013-07-10 00:45:361452}
1453
henrike@webrtc.org28e20752013-07-10 00:45:361454void PeerConnection::SetLocalDescription(
1455 SetSessionDescriptionObserver* observer,
Steve Anton80dd7b52018-02-17 01:08:421456 SessionDescriptionInterface* desc_ptr) {
Karl Wiberg5966c502019-02-21 22:55:091457 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431458 sdp_handler_->SetLocalDescription(observer, desc_ptr);
Henrik Boström831ae4e2020-07-29 10:04:001459}
1460
1461void PeerConnection::SetLocalDescription(
1462 std::unique_ptr<SessionDescriptionInterface> desc,
1463 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1464 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431465 sdp_handler_->SetLocalDescription(std::move(desc), observer);
Henrik Boströma3728d32019-10-28 11:09:491466}
Steve Anton8a006912017-12-04 23:25:561467
Henrik Boström4e196702019-10-30 09:35:501468void PeerConnection::SetLocalDescription(
1469 SetSessionDescriptionObserver* observer) {
1470 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431471 sdp_handler_->SetLocalDescription(observer);
Henrik Boström831ae4e2020-07-29 10:04:001472}
1473
1474void PeerConnection::SetLocalDescription(
1475 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1476 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431477 sdp_handler_->SetLocalDescription(observer);
Henrik Boström4e196702019-10-30 09:35:501478}
1479
henrike@webrtc.org28e20752013-07-10 00:45:361480void PeerConnection::SetRemoteDescription(
Henrik Boströma4ecf552017-11-23 14:17:071481 SetSessionDescriptionObserver* observer,
Henrik Boströma3728d32019-10-28 11:09:491482 SessionDescriptionInterface* desc_ptr) {
1483 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431484 sdp_handler_->SetRemoteDescription(observer, desc_ptr);
Henrik Boström31638672017-11-23 16:48:321485}
1486
1487void PeerConnection::SetRemoteDescription(
1488 std::unique_ptr<SessionDescriptionInterface> desc,
1489 rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
Karl Wiberg5966c502019-02-21 22:55:091490 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431491 sdp_handler_->SetRemoteDescription(std::move(desc), observer);
Henrik Boströmafa07dd2018-12-20 10:06:021492}
1493
deadbeef46c73892016-11-17 03:42:041494PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
Karl Wiberg5966c502019-02-21 22:55:091495 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeef46c73892016-11-17 03:42:041496 return configuration_;
1497}
1498
Niels Möller2579f0c2019-08-19 07:58:171499RTCError PeerConnection::SetConfiguration(
1500 const RTCConfiguration& configuration) {
Karl Wiberg5966c502019-02-21 22:55:091501 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171502 TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
Steve Antonc79268f2018-04-24 16:54:101503 if (IsClosed()) {
Niels Möller2579f0c2019-08-19 07:58:171504 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1505 "SetConfiguration: PeerConnection is closed.");
Steve Antonc79268f2018-04-24 16:54:101506 }
1507
Qingsi Wanga2d60672018-04-11 23:57:451508 // According to JSEP, after setLocalDescription, changing the candidate pool
1509 // size is not allowed, and changing the set of ICE servers will not result
1510 // in new candidates being gathered.
Steve Anton75737c02017-11-06 18:37:171511 if (local_description() && configuration.ice_candidate_pool_size !=
1512 configuration_.ice_candidate_pool_size) {
Niels Möller2579f0c2019-08-19 07:58:171513 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1514 "Can't change candidate pool size after calling "
1515 "SetLocalDescription.");
buildbot@webrtc.org41451d42014-05-03 05:39:451516 }
Taylor Brandstettera1c30352016-05-13 15:15:111517
Piotr (Peter) Slatalaaa1e7c22018-10-16 17:04:451518 if (local_description() &&
Benjamin Wright8c27cca2018-10-25 17:16:441519 configuration.crypto_options != configuration_.crypto_options) {
Niels Möller2579f0c2019-08-19 07:58:171520 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1521 "Can't change crypto_options after calling "
1522 "SetLocalDescription.");
Benjamin Wright8c27cca2018-10-25 17:16:441523 }
1524
deadbeef293e9262017-01-11 20:28:301525 // The simplest (and most future-compatible) way to tell if the config was
1526 // modified in an invalid way is to copy each property we do support
1527 // modifying, then use operator==. There are far more properties we don't
1528 // support modifying than those we do, and more could be added.
1529 RTCConfiguration modified_config = configuration_;
1530 modified_config.servers = configuration.servers;
1531 modified_config.type = configuration.type;
1532 modified_config.ice_candidate_pool_size =
1533 configuration.ice_candidate_pool_size;
1534 modified_config.prune_turn_ports = configuration.prune_turn_ports;
Honghai Zhangf8998cf2019-10-14 18:27:501535 modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy;
Qingsi Wangbca14852019-06-26 21:56:021536 modified_config.surface_ice_candidates_on_ice_transport_type_changed =
1537 configuration.surface_ice_candidates_on_ice_transport_type_changed;
skvladd1f5fda2017-02-04 00:54:051538 modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
Qingsi Wange6826d22018-03-08 22:55:141539 modified_config.ice_check_interval_strong_connectivity =
1540 configuration.ice_check_interval_strong_connectivity;
1541 modified_config.ice_check_interval_weak_connectivity =
1542 configuration.ice_check_interval_weak_connectivity;
Qingsi Wang22e623a2018-03-13 17:53:571543 modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
1544 modified_config.ice_unwritable_min_checks =
1545 configuration.ice_unwritable_min_checks;
Jiawei Ou9d4fd5552018-12-07 07:30:171546 modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
Qingsi Wangdb53f8e2018-02-20 22:45:491547 modified_config.stun_candidate_keepalive_interval =
1548 configuration.stun_candidate_keepalive_interval;
Jonas Orelandbdcee282017-10-10 12:01:401549 modified_config.turn_customizer = configuration.turn_customizer;
Qingsi Wang9a5c6f82018-02-01 18:38:401550 modified_config.network_preference = configuration.network_preference;
Zhi Huangb57e1692018-06-12 18:41:111551 modified_config.active_reset_srtp_params =
1552 configuration.active_reset_srtp_params;
Jonas Oreland3c028422019-08-22 14:16:351553 modified_config.turn_logging_id = configuration.turn_logging_id;
philipel16cec3b2019-10-25 10:23:021554 modified_config.allow_codec_switching = configuration.allow_codec_switching;
Derek Bailey6c127a12021-04-15 19:42:411555 modified_config.stable_writable_connection_ping_interval_ms =
1556 configuration.stable_writable_connection_ping_interval_ms;
deadbeef293e9262017-01-11 20:28:301557 if (configuration != modified_config) {
Niels Möller2579f0c2019-08-19 07:58:171558 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1559 "Modifying the configuration in an unsupported way.");
deadbeef293e9262017-01-11 20:28:301560 }
1561
Steve Anton038834f2017-07-14 22:59:591562 // Validate the modified configuration.
1563 RTCError validate_error = ValidateConfiguration(modified_config);
1564 if (!validate_error.ok()) {
Niels Möller2579f0c2019-08-19 07:58:171565 return validate_error;
Steve Anton038834f2017-07-14 22:59:591566 }
1567
deadbeef293e9262017-01-11 20:28:301568 // Note that this isn't possible through chromium, since it's an unsigned
1569 // short in WebIDL.
1570 if (configuration.ice_candidate_pool_size < 0 ||
Wez939eb802018-05-03 10:34:171571 configuration.ice_candidate_pool_size > static_cast<int>(UINT16_MAX)) {
Niels Möller2579f0c2019-08-19 07:58:171572 return RTCError(RTCErrorType::INVALID_RANGE);
deadbeef293e9262017-01-11 20:28:301573 }
1574
1575 // Parse ICE servers before hopping to network thread.
1576 cricket::ServerAddresses stun_servers;
1577 std::vector<cricket::RelayServerConfig> turn_servers;
Philipp Hancke633dc2f2022-10-12 08:16:141578 RTCError parse_error = ParseIceServersOrError(configuration.servers,
1579 &stun_servers, &turn_servers);
1580 if (!parse_error.ok()) {
1581 return parse_error;
deadbeef293e9262017-01-11 20:28:301582 }
Philipp Hancke41a83572022-11-28 13:47:451583
1584 // Restrict number of TURN servers.
Philipp Hancke3e224c72023-03-20 07:22:491585 if (turn_servers.size() > cricket::kMaxTurnServers) {
Philipp Hancke41a83572022-11-28 13:47:451586 RTC_LOG(LS_WARNING) << "Number of configured TURN servers is "
1587 << turn_servers.size()
1588 << " which exceeds the maximum allowed number of "
1589 << cricket::kMaxTurnServers;
1590 turn_servers.resize(cricket::kMaxTurnServers);
1591 }
1592
Jonas Oreland3c028422019-08-22 14:16:351593 // Add the turn logging id to all turn servers
1594 for (cricket::RelayServerConfig& turn_server : turn_servers) {
1595 turn_server.turn_logging_id = configuration.turn_logging_id;
1596 }
1597
Harald Alvestrand8ebba742018-05-31 12:00:341598 // Note if STUN or TURN servers were supplied.
1599 if (!stun_servers.empty()) {
1600 NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
1601 }
1602 if (!turn_servers.empty()) {
1603 NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
1604 }
deadbeef293e9262017-01-11 20:28:301605
Niels Möller4bab23f2021-01-18 08:24:331606 const bool has_local_description = local_description() != nullptr;
1607
Tomas Gunnarsson20f74562021-02-04 09:22:501608 const bool needs_ice_restart =
1609 modified_config.servers != configuration_.servers ||
1610 NeedIceRestart(
1611 configuration_.surface_ice_candidates_on_ice_transport_type_changed,
1612 configuration_.type, modified_config.type) ||
1613 modified_config.GetTurnPortPrunePolicy() !=
1614 configuration_.GetTurnPortPrunePolicy();
1615 cricket::IceConfig ice_config = ParseIceConfig(modified_config);
1616
1617 // Apply part of the configuration on the network thread. In theory this
1618 // shouldn't fail.
Danil Chapovalov9e09a1f2022-09-08 16:38:101619 if (!network_thread()->BlockingCall(
Tomas Gunnarsson20f74562021-02-04 09:22:501620 [this, needs_ice_restart, &ice_config, &stun_servers, &turn_servers,
1621 &modified_config, has_local_description] {
Harald Alvestrandbc32c562022-02-09 12:08:471622 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson20f74562021-02-04 09:22:501623 // As described in JSEP, calling setConfiguration with new ICE
1624 // servers or candidate policy must set a "needs-ice-restart" bit so
1625 // that the next offer triggers an ICE restart which will pick up
1626 // the changes.
1627 if (needs_ice_restart)
1628 transport_controller_->SetNeedsIceRestartFlag();
1629
1630 transport_controller_->SetIceConfig(ice_config);
Niels Möller4bab23f2021-01-18 08:24:331631 return ReconfigurePortAllocator_n(
1632 stun_servers, turn_servers, modified_config.type,
1633 modified_config.ice_candidate_pool_size,
1634 modified_config.GetTurnPortPrunePolicy(),
1635 modified_config.turn_customizer,
1636 modified_config.stun_candidate_keepalive_interval,
1637 has_local_description);
1638 })) {
Niels Möller2579f0c2019-08-19 07:58:171639 LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
1640 "Failed to apply configuration to PortAllocator.");
deadbeef293e9262017-01-11 20:28:301641 }
Honghai Zhang4cedf2b2016-08-31 15:18:111642
Zhi Huangb57e1692018-06-12 18:41:111643 if (configuration_.active_reset_srtp_params !=
1644 modified_config.active_reset_srtp_params) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101645 // TODO(tommi): merge BlockingCalls
1646 network_thread()->BlockingCall([this, &modified_config] {
Harald Alvestrandbc32c562022-02-09 12:08:471647 RTC_DCHECK_RUN_ON(network_thread());
1648 transport_controller_->SetActiveResetSrtpParams(
1649 modified_config.active_reset_srtp_params);
1650 });
Zhi Huangb57e1692018-06-12 18:41:111651 }
1652
philipel16cec3b2019-10-25 10:23:021653 if (modified_config.allow_codec_switching.has_value()) {
Harald Alvestrandc0d44d92022-12-13 12:57:241654 std::vector<cricket::VideoMediaSendChannelInterface*> channels;
Harald Alvestrande15fb152020-10-19 13:28:051655 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
Tomas Gunnarssond41c2a62020-09-21 13:56:421656 if (transceiver->media_type() != cricket::MEDIA_TYPE_VIDEO)
Taylor Brandstetter6b381c72020-08-24 20:28:471657 continue;
Tomas Gunnarssond41c2a62020-09-21 13:56:421658
Harald Alvestrand2c761b22022-04-30 16:27:401659 auto* video_channel = transceiver->internal()->channel();
Tomas Gunnarssond41c2a62020-09-21 13:56:421660 if (video_channel)
Harald Alvestrandc0d44d92022-12-13 12:57:241661 channels.push_back(
1662 static_cast<cricket::VideoMediaSendChannelInterface*>(
1663 video_channel->media_send_channel()));
philipel01294f02019-11-14 12:03:251664 }
Tomas Gunnarssond41c2a62020-09-21 13:56:421665
Danil Chapovalov9e09a1f2022-09-08 16:38:101666 worker_thread()->BlockingCall(
Tomas Gunnarssond41c2a62020-09-21 13:56:421667 [channels = std::move(channels),
1668 allow_codec_switching = *modified_config.allow_codec_switching]() {
1669 for (auto* ch : channels)
1670 ch->SetVideoCodecSwitchingEnabled(allow_codec_switching);
1671 });
philipel16cec3b2019-10-25 10:23:021672 }
1673
deadbeef293e9262017-01-11 20:28:301674 configuration_ = modified_config;
Niels Möller2579f0c2019-08-19 07:58:171675 return RTCError::OK();
buildbot@webrtc.org41451d42014-05-03 05:39:451676}
1677
henrike@webrtc.org28e20752013-07-10 00:45:361678bool PeerConnection::AddIceCandidate(
1679 const IceCandidateInterface* ice_candidate) {
Karl Wiberg744310f2019-02-14 09:18:561680 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hanckea09b9212022-06-22 05:41:221681 ClearStatsCache();
Harald Alvestrand9cd199d2020-10-27 07:10:431682 return sdp_handler_->AddIceCandidate(ice_candidate);
henrike@webrtc.org28e20752013-07-10 00:45:361683}
1684
Henrik Boströmee6f4f62019-11-06 11:36:121685void PeerConnection::AddIceCandidate(
1686 std::unique_ptr<IceCandidateInterface> candidate,
1687 std::function<void(RTCError)> callback) {
1688 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hanckea09b9212022-06-22 05:41:221689 sdp_handler_->AddIceCandidate(std::move(candidate),
1690 [this, callback](webrtc::RTCError result) {
1691 ClearStatsCache();
1692 callback(result);
1693 });
Henrik Boströmee6f4f62019-11-06 11:36:121694}
1695
Honghai Zhang7fb69db2016-03-14 18:59:181696bool PeerConnection::RemoveIceCandidates(
1697 const std::vector<cricket::Candidate>& candidates) {
1698 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
Karl Wiberg2cc368f2019-04-02 09:31:561699 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431700 return sdp_handler_->RemoveIceCandidates(candidates);
Honghai Zhang7fb69db2016-03-14 18:59:181701}
1702
Niels Möller0c4f7be2018-05-07 12:01:371703RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
Steve Anton978b8762017-09-29 19:15:021704 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101705 return worker_thread()->BlockingCall([&]() { return SetBitrate(bitrate); });
zstein4b979802017-06-02 21:37:371706 }
Karl Wiberg6cab5c82019-03-26 08:57:011707 RTC_DCHECK_RUN_ON(worker_thread());
zstein4b979802017-06-02 21:37:371708
Niels Möller0c4f7be2018-05-07 12:01:371709 const bool has_min = bitrate.min_bitrate_bps.has_value();
1710 const bool has_start = bitrate.start_bitrate_bps.has_value();
1711 const bool has_max = bitrate.max_bitrate_bps.has_value();
zstein4b979802017-06-02 21:37:371712 if (has_min && *bitrate.min_bitrate_bps < 0) {
1713 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1714 "min_bitrate_bps <= 0");
1715 }
Niels Möller0c4f7be2018-05-07 12:01:371716 if (has_start) {
1717 if (has_min && *bitrate.start_bitrate_bps < *bitrate.min_bitrate_bps) {
zstein4b979802017-06-02 21:37:371718 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 12:01:371719 "start_bitrate_bps < min_bitrate_bps");
1720 } else if (*bitrate.start_bitrate_bps < 0) {
zstein4b979802017-06-02 21:37:371721 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1722 "curent_bitrate_bps < 0");
1723 }
1724 }
1725 if (has_max) {
Yves Gerey665174f2018-06-19 13:03:051726 if (has_start && *bitrate.max_bitrate_bps < *bitrate.start_bitrate_bps) {
zstein4b979802017-06-02 21:37:371727 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 12:01:371728 "max_bitrate_bps < start_bitrate_bps");
zstein4b979802017-06-02 21:37:371729 } else if (has_min && *bitrate.max_bitrate_bps < *bitrate.min_bitrate_bps) {
1730 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1731 "max_bitrate_bps < min_bitrate_bps");
1732 } else if (*bitrate.max_bitrate_bps < 0) {
1733 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1734 "max_bitrate_bps < 0");
1735 }
1736 }
1737
zstein4b979802017-06-02 21:37:371738 RTC_DCHECK(call_.get());
Piotr (Peter) Slatala7fbfaa42019-03-18 17:31:541739 call_->SetClientBitratePreferences(bitrate);
zstein4b979802017-06-02 21:37:371740
1741 return RTCError::OK();
1742}
1743
henrika5f6bf242017-11-01 10:06:561744void PeerConnection::SetAudioPlayout(bool playout) {
1745 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101746 worker_thread()->BlockingCall(
1747 [this, playout] { SetAudioPlayout(playout); });
henrika5f6bf242017-11-01 10:06:561748 return;
1749 }
Harald Alvestrandc3fa7c32022-05-22 10:57:011750 auto audio_state = context_->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 10:06:561751 audio_state->SetPlayout(playout);
1752}
1753
1754void PeerConnection::SetAudioRecording(bool recording) {
1755 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101756 worker_thread()->BlockingCall(
1757 [this, recording] { SetAudioRecording(recording); });
henrika5f6bf242017-11-01 10:06:561758 return;
1759 }
Harald Alvestrandc3fa7c32022-05-22 10:57:011760 auto audio_state = context_->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 10:06:561761 audio_state->SetRecording(recording);
1762}
1763
Henrik Boström4c1e7cc2020-06-11 10:26:531764void PeerConnection::AddAdaptationResource(
1765 rtc::scoped_refptr<Resource> resource) {
1766 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101767 return worker_thread()->BlockingCall(
1768 [this, resource]() { return AddAdaptationResource(resource); });
Henrik Boström4c1e7cc2020-06-11 10:26:531769 }
1770 RTC_DCHECK_RUN_ON(worker_thread());
1771 if (!call_) {
1772 // The PeerConnection has been closed.
1773 return;
1774 }
1775 call_->AddAdaptationResource(resource);
1776}
1777
Harald Alvestrand35ba0c52022-05-05 07:37:411778bool PeerConnection::ConfiguredForMedia() const {
Harald Alvestrandc3fa7c32022-05-22 10:57:011779 return context_->media_engine();
Harald Alvestrand35ba0c52022-05-05 07:37:411780}
1781
Bjorn Tereliusde939432017-11-20 16:38:141782bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
1783 int64_t output_period_ms) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101784 return worker_thread()->BlockingCall(
Danil Chapovalov116ffe72019-09-05 08:21:111785 [this, output = std::move(output), output_period_ms]() mutable {
1786 return StartRtcEventLog_w(std::move(output), output_period_ms);
1787 });
ivoc14d5dbe2016-07-04 14:06:551788}
1789
Niels Möllerf00ca1a2019-05-10 09:33:121790bool PeerConnection::StartRtcEventLog(
1791 std::unique_ptr<RtcEventLogOutput> output) {
Lionel Koenig0606eaf2023-06-27 08:46:191792 int64_t output_period_ms = 5000;
1793 if (trials().IsDisabled("WebRTC-RtcEventLogNewFormat")) {
1794 output_period_ms = webrtc::RtcEventLog::kImmediateOutput;
Niels Möller695cf6a2019-05-13 10:27:231795 }
1796 return StartRtcEventLog(std::move(output), output_period_ms);
Niels Möllerf00ca1a2019-05-10 09:33:121797}
1798
ivoc14d5dbe2016-07-04 14:06:551799void PeerConnection::StopRtcEventLog() {
Danil Chapovalov9e09a1f2022-09-08 16:38:101800 worker_thread()->BlockingCall([this] { StopRtcEventLog_w(); });
ivoc14d5dbe2016-07-04 14:06:551801}
1802
Harald Alvestrandad88c882018-11-28 15:47:461803rtc::scoped_refptr<DtlsTransportInterface>
1804PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
Tomas Gunnarsson2aeab5e2021-02-23 20:36:141805 RTC_DCHECK_RUN_ON(network_thread());
Harald Alvestrandad88c882018-11-28 15:47:461806 return transport_controller_->LookupDtlsTransportByMid(mid);
1807}
1808
Harald Alvestrand4a7b3ac2019-01-17 09:39:401809rtc::scoped_refptr<DtlsTransport>
1810PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
Karl Wiberg2cc368f2019-04-02 09:31:561811 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:471812 // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
1813 // This might be done by caching the value on the signaling thread.
Danil Chapovalov9e09a1f2022-09-08 16:38:101814 return network_thread()->BlockingCall([this, mid]() {
1815 RTC_DCHECK_RUN_ON(network_thread());
1816 return transport_controller_->LookupDtlsTransportByMid(mid);
1817 });
Harald Alvestrand4a7b3ac2019-01-17 09:39:401818}
1819
Harald Alvestrandc85328f2019-02-28 06:51:001820rtc::scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport()
1821 const {
Tomas Gunnarsson92eebef2021-02-10 12:05:441822 RTC_DCHECK_RUN_ON(network_thread());
1823 if (!sctp_mid_n_)
Bjorn A Mellembc3eebc2019-09-23 21:53:541824 return nullptr;
Tomas Gunnarsson92eebef2021-02-10 12:05:441825
1826 return transport_controller_->GetSctpTransport(*sctp_mid_n_);
Harald Alvestrandc85328f2019-02-28 06:51:001827}
1828
henrike@webrtc.org28e20752013-07-10 00:45:361829const SessionDescriptionInterface* PeerConnection::local_description() const {
Karl Wiberg739506e2019-04-03 09:37:281830 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431831 return sdp_handler_->local_description();
henrike@webrtc.org28e20752013-07-10 00:45:361832}
1833
1834const SessionDescriptionInterface* PeerConnection::remote_description() const {
Karl Wiberg739506e2019-04-03 09:37:281835 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431836 return sdp_handler_->remote_description();
henrike@webrtc.org28e20752013-07-10 00:45:361837}
1838
deadbeeffe4a8a42016-12-21 01:56:171839const SessionDescriptionInterface* PeerConnection::current_local_description()
1840 const {
Karl Wiberg739506e2019-04-03 09:37:281841 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431842 return sdp_handler_->current_local_description();
deadbeeffe4a8a42016-12-21 01:56:171843}
1844
1845const SessionDescriptionInterface* PeerConnection::current_remote_description()
1846 const {
Karl Wiberg739506e2019-04-03 09:37:281847 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431848 return sdp_handler_->current_remote_description();
deadbeeffe4a8a42016-12-21 01:56:171849}
1850
1851const SessionDescriptionInterface* PeerConnection::pending_local_description()
1852 const {
Karl Wiberg739506e2019-04-03 09:37:281853 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431854 return sdp_handler_->pending_local_description();
deadbeeffe4a8a42016-12-21 01:56:171855}
1856
1857const SessionDescriptionInterface* PeerConnection::pending_remote_description()
1858 const {
Karl Wiberg739506e2019-04-03 09:37:281859 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431860 return sdp_handler_->pending_remote_description();
deadbeeffe4a8a42016-12-21 01:56:171861}
1862
henrike@webrtc.org28e20752013-07-10 00:45:361863void PeerConnection::Close() {
Karl Wiberg744310f2019-02-14 09:18:561864 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171865 TRACE_EVENT0("webrtc", "PeerConnection::Close");
Harald Alvestrandcdcfab02020-09-28 13:02:071866
Tommife041642021-04-07 08:08:281867 RTC_LOG_THREAD_BLOCK_COUNT();
1868
Harald Alvestrandcdcfab02020-09-28 13:02:071869 if (IsClosed()) {
1870 return;
1871 }
henrike@webrtc.org28e20752013-07-10 00:45:361872 // Update stats here so that we have the most recent stats for tracks and
1873 // streams before the channels are closed.
Henrik Boströmf7859892022-07-04 12:36:371874 legacy_stats_->UpdateStats(kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:361875
Harald Alvestrandcdcfab02020-09-28 13:02:071876 ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed;
1877 Observer()->OnIceConnectionChange(ice_connection_state_);
1878 standardized_ice_connection_state_ =
1879 PeerConnectionInterface::IceConnectionState::kIceConnectionClosed;
1880 connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
1881 Observer()->OnConnectionChange(connection_state_);
1882
Harald Alvestrand9cd199d2020-10-27 07:10:431883 sdp_handler_->Close();
Harald Alvestrandcdcfab02020-09-28 13:02:071884
Harald Alvestrand8ebba742018-05-31 12:00:341885 NoteUsageEvent(UsageEvent::CLOSE_CALLED);
Steve Anton3fe1b152017-12-12 18:20:081886
Harald Alvestrand8101e7b2022-05-23 14:57:471887 if (ConfiguredForMedia()) {
1888 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1889 transceiver->internal()->SetPeerConnectionClosed();
1890 if (!transceiver->stopped())
1891 transceiver->StopInternal();
1892 }
Steve Anton8af21862017-12-15 19:20:131893 }
Steve Anton25cfeb92018-04-26 18:44:001894 // Ensure that all asynchronous stats requests are completed before destroying
1895 // the transport controller below.
1896 if (stats_collector_) {
1897 stats_collector_->WaitForPendingRequest();
1898 }
1899
1900 // Don't destroy BaseChannels until after stats has been cleaned up so that
1901 // the last stats request can still read from the channels.
Harald Alvestrand9cd199d2020-10-27 07:10:431902 sdp_handler_->DestroyAllChannels();
Steve Anton75737c02017-11-06 18:37:171903
Qingsi Wang93a84392018-01-31 01:13:091904 // The event log is used in the transport controller, which must be outlived
1905 // by the former. CreateOffer by the peer connection is implemented
1906 // asynchronously and if the peer connection is closed without resetting the
1907 // WebRTC session description factory, the session description factory would
1908 // call the transport controller.
Harald Alvestrand9cd199d2020-10-27 07:10:431909 sdp_handler_->ResetSessionDescFactory();
Harald Alvestrand8101e7b2022-05-23 14:57:471910 if (ConfiguredForMedia()) {
1911 rtp_manager_->Close();
1912 }
Qingsi Wang93a84392018-01-31 01:13:091913
Danil Chapovalov9e09a1f2022-09-08 16:38:101914 network_thread()->BlockingCall([this] {
Tomas Gunnarssond69e0702021-04-07 13:14:431915 // Data channels will already have been unset via the DestroyAllChannels()
1916 // call above, which triggers a call to TeardownDataChannelTransport_n().
1917 // TODO(tommi): ^^ That's not exactly optimal since this is yet another
1918 // blocking hop to the network thread during Close(). Further still, the
1919 // voice/video/data channels will be cleared on the worker thread.
Harald Alvestrandbc32c562022-02-09 12:08:471920 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson92eebef2021-02-10 12:05:441921 transport_controller_.reset();
1922 port_allocator_->DiscardCandidatePool();
1923 if (network_thread_safety_) {
1924 network_thread_safety_->SetNotAlive();
Tomas Gunnarsson92eebef2021-02-10 12:05:441925 }
1926 });
nisseeaabdf62017-05-05 09:23:021927
Danil Chapovalov9e09a1f2022-09-08 16:38:101928 worker_thread()->BlockingCall([this] {
Karl Wibergb03ab712019-02-14 10:59:571929 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:081930 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 12:18:151931 call_.reset();
1932 // The event log must outlive call (and any other object that uses it).
1933 event_log_.reset();
1934 });
Harald Alvestrand8ebba742018-05-31 12:00:341935 ReportUsagePattern();
Tomas Gunnarsson2efb8a52021-04-01 14:26:571936
1937 // Signal shutdown to the sdp handler. This invalidates weak pointers for
1938 // internal pending callbacks.
1939 sdp_handler_->PrepareForShutdown();
Tommi1f708ef2023-03-31 16:40:501940 data_channel_controller_.PrepareForShutdown();
1941
1942 // The .h file says that observer can be discarded after close() returns.
1943 // Make sure this is true.
1944 observer_ = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:361945}
1946
Steve Antonba818672017-11-06 18:21:571947void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
Harald Alvestrandcdcfab02020-09-28 13:02:071948 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonba818672017-11-06 18:21:571949 if (ice_connection_state_ == new_state) {
1950 return;
1951 }
1952
deadbeefcbecd352015-09-23 18:50:271953 // After transitioning to "closed", ignore any additional states from
Steve Antonba818672017-11-06 18:21:571954 // TransportController (such as "disconnected").
deadbeefab9b2d12015-10-14 18:33:111955 if (IsClosed()) {
deadbeefcbecd352015-09-23 18:50:271956 return;
1957 }
Steve Antonba818672017-11-06 18:21:571958
Mirko Bonadei675513b2017-11-09 10:09:251959 RTC_LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1960 << " => " << new_state;
Steve Antonba818672017-11-06 18:21:571961 RTC_DCHECK(ice_connection_state_ !=
1962 PeerConnectionInterface::kIceConnectionClosed);
1963
henrike@webrtc.org28e20752013-07-10 00:45:361964 ice_connection_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 08:50:161965 Observer()->OnIceConnectionChange(ice_connection_state_);
henrike@webrtc.org28e20752013-07-10 00:45:361966}
1967
Alex Loiko9289eda2018-11-23 16:18:591968void PeerConnection::SetStandardizedIceConnectionState(
1969 PeerConnectionInterface::IceConnectionState new_state) {
Qingsi Wang36e31472019-05-29 18:37:261970 if (standardized_ice_connection_state_ == new_state) {
Alex Loiko9289eda2018-11-23 16:18:591971 return;
Qingsi Wang36e31472019-05-29 18:37:261972 }
1973
1974 if (IsClosed()) {
Alex Loiko9289eda2018-11-23 16:18:591975 return;
Qingsi Wang36e31472019-05-29 18:37:261976 }
1977
1978 RTC_LOG(LS_INFO) << "Changing standardized IceConnectionState "
1979 << standardized_ice_connection_state_ << " => " << new_state;
1980
Alex Loiko9289eda2018-11-23 16:18:591981 standardized_ice_connection_state_ = new_state;
Jonas Olsson12046902018-12-06 10:25:141982 Observer()->OnStandardizedIceConnectionChange(new_state);
Alex Loiko9289eda2018-11-23 16:18:591983}
1984
Jonas Olsson635474e2018-10-18 13:58:171985void PeerConnection::SetConnectionState(
1986 PeerConnectionInterface::PeerConnectionState new_state) {
Jonas Olsson635474e2018-10-18 13:58:171987 if (connection_state_ == new_state)
1988 return;
1989 if (IsClosed())
1990 return;
1991 connection_state_ = new_state;
1992 Observer()->OnConnectionChange(new_state);
Philipp Hanckebb8f32f2021-02-04 20:50:501993
Philipp Hancke9799fe02022-07-06 07:26:411994 // The first connection state change to connected happens once per
1995 // connection which makes it a good point to report metrics.
Philipp Hanckecd0373f2021-02-24 10:04:301996 if (new_state == PeerConnectionState::kConnected && !was_ever_connected_) {
1997 was_ever_connected_ = true;
Philipp Hancke9799fe02022-07-06 07:26:411998 ReportFirstConnectUsageMetrics();
Philipp Hanckebb8f32f2021-02-04 20:50:501999 }
Jonas Olsson635474e2018-10-18 13:58:172000}
2001
Philipp Hancke9799fe02022-07-06 07:26:412002void PeerConnection::ReportFirstConnectUsageMetrics() {
2003 // Record bundle-policy from configuration. Done here from
2004 // connectionStateChange to limit to actually established connections.
2005 BundlePolicyUsage policy = kBundlePolicyUsageMax;
2006 switch (configuration_.bundle_policy) {
2007 case kBundlePolicyBalanced:
2008 policy = kBundlePolicyUsageBalanced;
2009 break;
2010 case kBundlePolicyMaxBundle:
2011 policy = kBundlePolicyUsageMaxBundle;
2012 break;
2013 case kBundlePolicyMaxCompat:
2014 policy = kBundlePolicyUsageMaxCompat;
2015 break;
2016 }
2017 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundlePolicy", policy,
2018 kBundlePolicyUsageMax);
2019
Philipp Hancke9799fe02022-07-06 07:26:412020 // Record whether there was a local or remote provisional answer.
2021 ProvisionalAnswerUsage pranswer = kProvisionalAnswerNotUsed;
2022 if (local_description()->GetType() == SdpType::kPrAnswer) {
2023 pranswer = kProvisionalAnswerLocal;
2024 } else if (remote_description()->GetType() == SdpType::kPrAnswer) {
2025 pranswer = kProvisionalAnswerRemote;
2026 }
2027 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ProvisionalAnswer", pranswer,
2028 kProvisionalAnswerMax);
2029
Philipp Hancke6f22eb52022-07-14 09:38:442030 // Record the number of valid / invalid ice-ufrag. We do allow certain
2031 // non-spec ice-char for backward-compat reasons. At this point we know
2032 // that the ufrag/pwd consists of a valid ice-char or one of the four
2033 // not allowed characters since we have passed the IsIceChar check done
2034 // by the p2p transport description on setRemoteDescription calls.
2035 auto transport_infos = remote_description()->description()->transport_infos();
2036 if (transport_infos.size() > 0) {
2037 auto ice_parameters = transport_infos[0].description.GetIceParameters();
2038 auto is_invalid_char = [](char c) {
2039 return c == '-' || c == '=' || c == '#' || c == '_';
2040 };
2041 bool isUsingInvalidIceCharInUfrag =
2042 absl::c_any_of(ice_parameters.ufrag, is_invalid_char);
2043 bool isUsingInvalidIceCharInPwd =
2044 absl::c_any_of(ice_parameters.pwd, is_invalid_char);
2045 RTC_HISTOGRAM_BOOLEAN(
2046 "WebRTC.PeerConnection.ValidIceChars",
2047 !(isUsingInvalidIceCharInUfrag || isUsingInvalidIceCharInPwd));
2048 }
Philipp Hancke66efab22023-01-25 10:37:452049
2050 // Record RtcpMuxPolicy setting.
2051 RtcpMuxPolicyUsage rtcp_mux_policy = kRtcpMuxPolicyUsageMax;
2052 switch (configuration_.rtcp_mux_policy) {
2053 case kRtcpMuxPolicyNegotiate:
2054 rtcp_mux_policy = kRtcpMuxPolicyUsageNegotiate;
2055 break;
2056 case kRtcpMuxPolicyRequire:
2057 rtcp_mux_policy = kRtcpMuxPolicyUsageRequire;
2058 break;
2059 }
2060 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.RtcpMuxPolicy",
2061 rtcp_mux_policy, kRtcpMuxPolicyUsageMax);
Philipp Hancke9799fe02022-07-06 07:26:412062}
2063
henrike@webrtc.org28e20752013-07-10 00:45:362064void PeerConnection::OnIceGatheringChange(
2065 PeerConnectionInterface::IceGatheringState new_state) {
2066 if (IsClosed()) {
2067 return;
2068 }
2069 ice_gathering_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 08:50:162070 Observer()->OnIceGatheringChange(ice_gathering_state_);
henrike@webrtc.org28e20752013-07-10 00:45:362071}
2072
jbauch81bf7b02017-03-25 15:31:122073void PeerConnection::OnIceCandidate(
2074 std::unique_ptr<IceCandidateInterface> candidate) {
zhihuang29ff8442016-07-27 18:07:252075 if (IsClosed()) {
2076 return;
2077 }
Qingsi Wang1ba5dec2019-08-19 18:57:172078 ReportIceCandidateCollected(candidate->candidate());
Philipp Hancke1fe14f22022-06-17 09:34:312079 ClearStatsCache();
Harald Alvestrand7a1c7f72018-08-01 08:50:162080 Observer()->OnIceCandidate(candidate.get());
henrike@webrtc.org28e20752013-07-10 00:45:362081}
2082
Eldar Rello0095d372019-12-02 20:22:072083void PeerConnection::OnIceCandidateError(const std::string& address,
2084 int port,
Eldar Relloda13ea22019-06-01 09:23:432085 const std::string& url,
2086 int error_code,
2087 const std::string& error_text) {
2088 if (IsClosed()) {
2089 return;
2090 }
Eldar Rello0095d372019-12-02 20:22:072091 Observer()->OnIceCandidateError(address, port, url, error_code, error_text);
Eldar Relloda13ea22019-06-01 09:23:432092}
2093
Honghai Zhang7fb69db2016-03-14 18:59:182094void PeerConnection::OnIceCandidatesRemoved(
2095 const std::vector<cricket::Candidate>& candidates) {
zhihuang29ff8442016-07-27 18:07:252096 if (IsClosed()) {
2097 return;
2098 }
Harald Alvestrand7a1c7f72018-08-01 08:50:162099 Observer()->OnIceCandidatesRemoved(candidates);
Honghai Zhang7fb69db2016-03-14 18:59:182100}
2101
Alex Drake00c7ecf2019-08-06 17:54:472102void PeerConnection::OnSelectedCandidatePairChanged(
2103 const cricket::CandidatePairChangeEvent& event) {
2104 if (IsClosed()) {
2105 return;
2106 }
Qingsi Wang1ba5dec2019-08-19 18:57:172107
Qingsi Wangcc46b10c2019-09-12 18:19:012108 if (event.selected_candidate_pair.local_candidate().type() ==
2109 LOCAL_PORT_TYPE &&
2110 event.selected_candidate_pair.remote_candidate().type() ==
2111 LOCAL_PORT_TYPE) {
2112 NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
2113 }
2114
Alex Drake00c7ecf2019-08-06 17:54:472115 Observer()->OnIceSelectedCandidatePairChanged(event);
2116}
2117
Danil Chapovalov66cadcc2018-06-19 14:47:432118absl::optional<std::string> PeerConnection::GetDataMid() const {
Harald Alvestrandcdcfab02020-09-28 13:02:072119 RTC_DCHECK_RUN_ON(signaling_thread());
Florent Castelli516e2842021-04-19 13:29:502120 return sctp_mid_s_;
Steve Antonfa2260d2017-12-29 00:38:232121}
2122
Tommiaa3c9f22023-04-18 10:19:192123void PeerConnection::SetSctpDataInfo(absl::string_view mid,
2124 absl::string_view transport_name) {
Tomas Gunnarsson92eebef2021-02-10 12:05:442125 RTC_DCHECK_RUN_ON(signaling_thread());
Tommiaa3c9f22023-04-18 10:19:192126 sctp_mid_s_ = std::string(mid);
2127 SetSctpTransportName(std::string(transport_name));
Tomas Gunnarsson92eebef2021-02-10 12:05:442128}
2129
Tommiaa3c9f22023-04-18 10:19:192130void PeerConnection::ResetSctpDataInfo() {
Tomas Gunnarsson92eebef2021-02-10 12:05:442131 RTC_DCHECK_RUN_ON(signaling_thread());
2132 sctp_mid_s_.reset();
Henrik Boström46053e42023-01-20 12:18:532133 SetSctpTransportName("");
Tomas Gunnarsson92eebef2021-02-10 12:05:442134}
2135
Tommid2afbaf2023-03-02 09:51:162136void PeerConnection::OnSctpDataChannelStateChanged(
Tommi56548982023-03-27 16:07:342137 int channel_id,
Tommid2afbaf2023-03-02 09:51:162138 DataChannelInterface::DataState state) {
2139 RTC_DCHECK_RUN_ON(signaling_thread());
2140 if (stats_collector_)
Tommi56548982023-03-27 16:07:342141 stats_collector_->OnSctpDataChannelStateChanged(channel_id, state);
deadbeefab9b2d12015-10-14 18:33:112142}
2143
Karl Wibergfb3be392019-03-22 13:13:222144PeerConnection::InitializePortAllocatorResult
2145PeerConnection::InitializePortAllocator_n(
Harald Alvestrandb2a74782018-06-28 11:54:072146 const cricket::ServerAddresses& stun_servers,
2147 const std::vector<cricket::RelayServerConfig>& turn_servers,
Taylor Brandstettera1c30352016-05-13 15:15:112148 const RTCConfiguration& configuration) {
Karl Wibergfb3be392019-03-22 13:13:222149 RTC_DCHECK_RUN_ON(network_thread());
2150
Taylor Brandstetterf8e65772016-06-28 00:20:152151 port_allocator_->Initialize();
Taylor Brandstettera1c30352016-05-13 15:15:112152 // To handle both internal and externally created port allocator, we will
2153 // enable BUNDLE here.
Karl Wibergfb3be392019-03-22 13:13:222154 int port_allocator_flags = port_allocator_->flags();
2155 port_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
2156 cricket::PORTALLOCATOR_ENABLE_IPV6 |
2157 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI;
Henrik Boströma445e6a2022-12-01 09:25:122158 if (trials().IsDisabled("WebRTC-IPv6Default")) {
Karl Wibergfb3be392019-03-22 13:13:222159 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
Taylor Brandstettera1c30352016-05-13 15:15:112160 }
zhihuangb09b3f92017-03-07 22:40:512161 if (configuration.disable_ipv6_on_wifi) {
Karl Wibergfb3be392019-03-22 13:13:222162 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
Mirko Bonadei675513b2017-11-09 10:09:252163 RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled.";
zhihuangb09b3f92017-03-07 22:40:512164 }
2165
Taylor Brandstettera1c30352016-05-13 15:15:112166 if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
Karl Wibergfb3be392019-03-22 13:13:222167 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
Mirko Bonadei675513b2017-11-09 10:09:252168 RTC_LOG(LS_INFO) << "TCP candidates are disabled.";
Taylor Brandstettera1c30352016-05-13 15:15:112169 }
2170
honghaiz60347052016-06-01 01:29:122171 if (configuration.candidate_network_policy ==
2172 kCandidateNetworkPolicyLowCost) {
Karl Wibergfb3be392019-03-22 13:13:222173 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
Mirko Bonadei675513b2017-11-09 10:09:252174 RTC_LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
honghaiz60347052016-06-01 01:29:122175 }
2176
Daniel Lazarenko2870b0a2018-01-25 09:30:222177 if (configuration.disable_link_local_networks) {
Karl Wibergfb3be392019-03-22 13:13:222178 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS;
Daniel Lazarenko2870b0a2018-01-25 09:30:222179 RTC_LOG(LS_INFO) << "Disable candidates on link-local network interfaces.";
2180 }
2181
Karl Wibergfb3be392019-03-22 13:13:222182 port_allocator_->set_flags(port_allocator_flags);
Taylor Brandstettera1c30352016-05-13 15:15:112183 // No step delay is used while allocating ports.
2184 port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
Qingsi Wangc129c352019-04-18 17:41:582185 port_allocator_->SetCandidateFilter(
Taylor Brandstettera1c30352016-05-13 15:15:112186 ConvertIceTransportTypeToCandidateFilter(configuration.type));
deadbeefd21eab3e2017-07-26 23:50:112187 port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);
Taylor Brandstettera1c30352016-05-13 15:15:112188
Harald Alvestrandb2a74782018-06-28 11:54:072189 auto turn_servers_copy = turn_servers;
Benjamin Wright6f80f092018-08-14 00:06:262190 for (auto& turn_server : turn_servers_copy) {
2191 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
Benjamin Wrightd6f86e82018-05-08 20:12:252192 }
Taylor Brandstettera1c30352016-05-13 15:15:112193 // Call this last since it may create pooled allocator sessions using the
2194 // properties set above.
Qingsi Wangdb53f8e2018-02-20 22:45:492195 port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-14 00:06:262196 stun_servers, std::move(turn_servers_copy),
Honghai Zhangf8998cf2019-10-14 18:27:502197 configuration.ice_candidate_pool_size,
2198 configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer,
Qingsi Wangdb53f8e2018-02-20 22:45:492199 configuration.stun_candidate_keepalive_interval);
Karl Wibergfb3be392019-03-22 13:13:222200
2201 InitializePortAllocatorResult res;
2202 res.enable_ipv6 = port_allocator_flags & cricket::PORTALLOCATOR_ENABLE_IPV6;
2203 return res;
Taylor Brandstettera1c30352016-05-13 15:15:112204}
2205
deadbeef91dd5672016-05-18 23:55:302206bool PeerConnection::ReconfigurePortAllocator_n(
deadbeef293e9262017-01-11 20:28:302207 const cricket::ServerAddresses& stun_servers,
2208 const std::vector<cricket::RelayServerConfig>& turn_servers,
2209 IceTransportsType type,
2210 int candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 18:27:502211 PortPrunePolicy turn_port_prune_policy,
Qingsi Wangdb53f8e2018-02-20 22:45:492212 webrtc::TurnCustomizer* turn_customizer,
Karl Wiberg739506e2019-04-03 09:37:282213 absl::optional<int> stun_candidate_keepalive_interval,
2214 bool have_local_description) {
Harald Alvestrandf598e492020-11-04 05:54:102215 RTC_DCHECK_RUN_ON(network_thread());
Qingsi Wangc129c352019-04-18 17:41:582216 port_allocator_->SetCandidateFilter(
deadbeef293e9262017-01-11 20:28:302217 ConvertIceTransportTypeToCandidateFilter(type));
Qingsi Wanga2d60672018-04-11 23:57:452218 // According to JSEP, after setLocalDescription, changing the candidate pool
2219 // size is not allowed, and changing the set of ICE servers will not result
2220 // in new candidates being gathered.
Karl Wiberg739506e2019-04-03 09:37:282221 if (have_local_description) {
Qingsi Wanga2d60672018-04-11 23:57:452222 port_allocator_->FreezeCandidatePool();
2223 }
Benjamin Wright6f80f092018-08-14 00:06:262224 // Add the custom tls turn servers if they exist.
2225 auto turn_servers_copy = turn_servers;
2226 for (auto& turn_server : turn_servers_copy) {
2227 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
2228 }
Taylor Brandstettera1c30352016-05-13 15:15:112229 // Call this last since it may create pooled allocator sessions using the
2230 // candidate filter set above.
deadbeef6de92f92016-12-13 02:49:322231 return port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-14 00:06:262232 stun_servers, std::move(turn_servers_copy), candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 18:27:502233 turn_port_prune_policy, turn_customizer,
2234 stun_candidate_keepalive_interval);
Taylor Brandstettera1c30352016-05-13 15:15:112235}
2236
Elad Alon99c3fe52017-10-13 14:29:402237bool PeerConnection::StartRtcEventLog_w(
Bjorn Tereliusde939432017-11-20 16:38:142238 std::unique_ptr<RtcEventLogOutput> output,
2239 int64_t output_period_ms) {
Karl Wibergb03ab712019-02-14 10:59:572240 RTC_DCHECK_RUN_ON(worker_thread());
zhihuang77985012017-02-07 23:45:162241 if (!event_log_) {
2242 return false;
2243 }
Bjorn Tereliusde939432017-11-20 16:38:142244 return event_log_->StartLogging(std::move(output), output_period_ms);
ivoc14d5dbe2016-07-04 14:06:552245}
2246
2247void PeerConnection::StopRtcEventLog_w() {
Karl Wibergb03ab712019-02-14 10:59:572248 RTC_DCHECK_RUN_ON(worker_thread());
zhihuang77985012017-02-07 23:45:162249 if (event_log_) {
2250 event_log_->StopLogging();
2251 }
ivoc14d5dbe2016-07-04 14:06:552252}
nisseeaabdf62017-05-05 09:23:022253
Tommi335d0842023-03-25 09:56:182254absl::optional<rtc::SSLRole> PeerConnection::GetSctpSslRole_n() {
Tommic61eee22023-03-22 07:25:382255 RTC_DCHECK_RUN_ON(network_thread());
Tommi335d0842023-03-25 09:56:182256 return sctp_mid_n_ ? transport_controller_->GetDtlsRole(*sctp_mid_n_)
2257 : absl::nullopt;
Steve Anton75737c02017-11-06 18:37:172258}
2259
2260bool PeerConnection::GetSslRole(const std::string& content_name,
2261 rtc::SSLRole* role) {
Karl Wiberg2cc368f2019-04-02 09:31:562262 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton75737c02017-11-06 18:37:172263 if (!local_description() || !remote_description()) {
Mirko Bonadei675513b2017-11-09 10:09:252264 RTC_LOG(LS_INFO)
2265 << "Local and Remote descriptions must be applied to get the "
Jonas Olsson45cc8902018-02-13 09:37:072266 "SSL Role of the session.";
Steve Anton75737c02017-11-06 18:37:172267 return false;
2268 }
2269
Danil Chapovalov9e09a1f2022-09-08 16:38:102270 auto dtls_role = network_thread()->BlockingCall([this, content_name]() {
2271 RTC_DCHECK_RUN_ON(network_thread());
2272 return transport_controller_->GetDtlsRole(content_name);
2273 });
Zhi Huange830e682018-03-30 17:48:352274 if (dtls_role) {
2275 *role = *dtls_role;
2276 return true;
2277 }
2278 return false;
Steve Anton75737c02017-11-06 18:37:172279}
2280
Steve Anton75737c02017-11-06 18:37:172281bool PeerConnection::GetTransportDescription(
2282 const SessionDescription* description,
2283 const std::string& content_name,
2284 cricket::TransportDescription* tdesc) {
2285 if (!description || !tdesc) {
2286 return false;
2287 }
2288 const TransportInfo* transport_info =
2289 description->GetTransportInfoByName(content_name);
2290 if (!transport_info) {
2291 return false;
2292 }
2293 *tdesc = transport_info->description;
2294 return true;
2295}
2296
Taylor Brandstetter3a034e12020-07-09 22:32:342297std::vector<DataChannelStats> PeerConnection::GetDataChannelStats() const {
Tommif9e13f82023-04-06 19:21:452298 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson2e94de52020-06-16 14:54:102299 return data_channel_controller_.GetDataChannelStats();
2300}
2301
Danil Chapovalov66cadcc2018-06-19 14:47:432302absl::optional<std::string> PeerConnection::sctp_transport_name() const {
Karl Wiberg2cc368f2019-04-02 09:31:562303 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:472304 if (sctp_mid_s_ && transport_controller_copy_)
Tomas Gunnarsson92eebef2021-02-10 12:05:442305 return sctp_transport_name_s_;
Danil Chapovalov66cadcc2018-06-19 14:47:432306 return absl::optional<std::string>();
Zhi Huange830e682018-03-30 17:48:352307}
2308
Henrik Boström46053e42023-01-20 12:18:532309void PeerConnection::SetSctpTransportName(std::string sctp_transport_name) {
2310 RTC_DCHECK_RUN_ON(signaling_thread());
2311 sctp_transport_name_s_ = std::move(sctp_transport_name);
2312 ClearStatsCache();
2313}
2314
Tomas Gunnarssonbfd9ba82021-04-18 09:55:572315absl::optional<std::string> PeerConnection::sctp_mid() const {
2316 RTC_DCHECK_RUN_ON(signaling_thread());
2317 return sctp_mid_s_;
2318}
2319
Qingsi Wang72a43a12018-02-21 00:03:182320cricket::CandidateStatsList PeerConnection::GetPooledCandidateStats() const {
Tomas Gunnarssone1c8a432021-04-08 13:15:282321 RTC_DCHECK_RUN_ON(network_thread());
2322 if (!network_thread_safety_->alive())
2323 return {};
Philipp Hancke6e57ca22022-06-09 13:58:182324 cricket::CandidateStatsList candidate_stats_list;
2325 port_allocator_->GetCandidateStatsFromPooledSessions(&candidate_stats_list);
2326 return candidate_stats_list;
Qingsi Wang72a43a12018-02-21 00:03:182327}
2328
Steve Anton5dfde182018-02-06 18:34:402329std::map<std::string, cricket::TransportStats>
2330PeerConnection::GetTransportStatsByNames(
2331 const std::set<std::string>& transport_names) {
Markus Handell518669d2021-06-07 11:30:462332 TRACE_EVENT0("webrtc", "PeerConnection::GetTransportStatsByNames");
Karl Wiberg2cc368f2019-04-02 09:31:562333 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarssone1c8a432021-04-08 13:15:282334 if (!network_thread_safety_->alive())
2335 return {};
2336
2337 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton5dfde182018-02-06 18:34:402338 std::map<std::string, cricket::TransportStats> transport_stats_by_name;
2339 for (const std::string& transport_name : transport_names) {
2340 cricket::TransportStats transport_stats;
2341 bool success =
2342 transport_controller_->GetStats(transport_name, &transport_stats);
2343 if (success) {
2344 transport_stats_by_name[transport_name] = std::move(transport_stats);
2345 } else {
2346 RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
2347 << transport_name;
2348 }
2349 }
2350 return transport_stats_by_name;
Steve Anton75737c02017-11-06 18:37:172351}
2352
2353bool PeerConnection::GetLocalCertificate(
2354 const std::string& transport_name,
2355 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282356 RTC_DCHECK_RUN_ON(network_thread());
2357 if (!network_thread_safety_->alive() || !certificate) {
Zhi Huange830e682018-03-30 17:48:352358 return false;
2359 }
2360 *certificate = transport_controller_->GetLocalCertificate(transport_name);
2361 return *certificate != nullptr;
Steve Anton75737c02017-11-06 18:37:172362}
2363
Taylor Brandstetterc3928662018-02-23 21:04:512364std::unique_ptr<rtc::SSLCertChain> PeerConnection::GetRemoteSSLCertChain(
Steve Anton75737c02017-11-06 18:37:172365 const std::string& transport_name) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282366 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstetterc3928662018-02-23 21:04:512367 return transport_controller_->GetRemoteSSLCertChain(transport_name);
Steve Anton75737c02017-11-06 18:37:172368}
2369
Steve Anton75737c02017-11-06 18:37:172370bool PeerConnection::IceRestartPending(const std::string& content_name) const {
Karl Wibergf73f7d62019-04-08 13:36:532371 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:432372 return sdp_handler_->IceRestartPending(content_name);
Steve Anton75737c02017-11-06 18:37:172373}
2374
Steve Anton75737c02017-11-06 18:37:172375bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
Danil Chapovalov9e09a1f2022-09-08 16:38:102376 return network_thread()->BlockingCall([this, &content_name] {
Tommic3257d02021-02-10 17:40:082377 RTC_DCHECK_RUN_ON(network_thread());
2378 return transport_controller_->NeedsIceRestart(content_name);
2379 });
Steve Anton75737c02017-11-06 18:37:172380}
2381
Alex Loiko9289eda2018-11-23 16:18:592382void PeerConnection::OnTransportControllerConnectionState(
2383 cricket::IceConnectionState state) {
2384 switch (state) {
2385 case cricket::kIceConnectionConnecting:
2386 // If the current state is Connected or Completed, then there were
2387 // writable channels but now there are not, so the next state must
2388 // be Disconnected.
2389 // kIceConnectionConnecting is currently used as the default,
2390 // un-connected state by the TransportController, so its only use is
2391 // detecting disconnections.
2392 if (ice_connection_state_ ==
2393 PeerConnectionInterface::kIceConnectionConnected ||
2394 ice_connection_state_ ==
2395 PeerConnectionInterface::kIceConnectionCompleted) {
2396 SetIceConnectionState(
2397 PeerConnectionInterface::kIceConnectionDisconnected);
2398 }
2399 break;
2400 case cricket::kIceConnectionFailed:
2401 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
2402 break;
2403 case cricket::kIceConnectionConnected:
2404 RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
2405 "all transports are writable.";
Tommidba22d32023-06-01 14:08:522406 {
2407 std::vector<RtpTransceiverProxyRefPtr> transceivers;
2408 if (ConfiguredForMedia()) {
2409 transceivers = rtp_manager()->transceivers()->List();
2410 }
2411
2412 network_thread()->PostTask(
2413 SafeTask(network_thread_safety_,
2414 [this, transceivers = std::move(transceivers)] {
2415 RTC_DCHECK_RUN_ON(network_thread());
2416 ReportTransportStats(std::move(transceivers));
2417 }));
2418 }
2419
Alex Loiko9289eda2018-11-23 16:18:592420 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2421 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2422 break;
2423 case cricket::kIceConnectionCompleted:
2424 RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
2425 "all transports are complete.";
2426 if (ice_connection_state_ !=
2427 PeerConnectionInterface::kIceConnectionConnected) {
2428 // If jumping directly from "checking" to "connected",
2429 // signal "connected" first.
2430 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2431 }
2432 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
Tomas Gunnarsson2001dc32021-04-06 09:36:002433
Alex Loiko9289eda2018-11-23 16:18:592434 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
Alex Loiko9289eda2018-11-23 16:18:592435 break;
2436 default:
Artem Titovd3251962021-11-15 15:57:072437 RTC_DCHECK_NOTREACHED();
Alex Loiko9289eda2018-11-23 16:18:592438 }
2439}
2440
Steve Anton75737c02017-11-06 18:37:172441void PeerConnection::OnTransportControllerCandidatesGathered(
2442 const std::string& transport_name,
2443 const cricket::Candidates& candidates) {
Tomas Gunnarsson20f74562021-02-04 09:22:502444 // TODO(bugs.webrtc.org/12427): Expect this to come in on the network thread
2445 // (not signaling as it currently does), handle appropriately.
Steve Anton75737c02017-11-06 18:37:172446 int sdp_mline_index;
2447 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
Mirko Bonadei675513b2017-11-09 10:09:252448 RTC_LOG(LS_ERROR)
2449 << "OnTransportControllerCandidatesGathered: content name "
2450 << transport_name << " not found";
Steve Anton75737c02017-11-06 18:37:172451 return;
2452 }
2453
2454 for (cricket::Candidates::const_iterator citer = candidates.begin();
2455 citer != candidates.end(); ++citer) {
2456 // Use transport_name as the candidate media id.
2457 std::unique_ptr<JsepIceCandidate> candidate(
2458 new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
Harald Alvestrand9cd199d2020-10-27 07:10:432459 sdp_handler_->AddLocalIceCandidate(candidate.get());
Steve Anton75737c02017-11-06 18:37:172460 OnIceCandidate(std::move(candidate));
2461 }
2462}
2463
Eldar Relloda13ea22019-06-01 09:23:432464void PeerConnection::OnTransportControllerCandidateError(
2465 const cricket::IceCandidateErrorEvent& event) {
Eldar Rello0095d372019-12-02 20:22:072466 OnIceCandidateError(event.address, event.port, event.url, event.error_code,
Eldar Relloda13ea22019-06-01 09:23:432467 event.error_text);
2468}
2469
Steve Anton75737c02017-11-06 18:37:172470void PeerConnection::OnTransportControllerCandidatesRemoved(
2471 const std::vector<cricket::Candidate>& candidates) {
Steve Anton75737c02017-11-06 18:37:172472 // Sanity check.
2473 for (const cricket::Candidate& candidate : candidates) {
2474 if (candidate.transport_name().empty()) {
Mirko Bonadei675513b2017-11-09 10:09:252475 RTC_LOG(LS_ERROR) << "OnTransportControllerCandidatesRemoved: "
Jonas Olsson45cc8902018-02-13 09:37:072476 "empty content name in candidate "
Mirko Bonadei675513b2017-11-09 10:09:252477 << candidate.ToString();
Steve Anton75737c02017-11-06 18:37:172478 return;
2479 }
2480 }
Harald Alvestrand9cd199d2020-10-27 07:10:432481 sdp_handler_->RemoveLocalIceCandidates(candidates);
Steve Anton75737c02017-11-06 18:37:172482 OnIceCandidatesRemoved(candidates);
2483}
2484
Alex Drake00c7ecf2019-08-06 17:54:472485void PeerConnection::OnTransportControllerCandidateChanged(
2486 const cricket::CandidatePairChangeEvent& event) {
2487 OnSelectedCandidatePairChanged(event);
2488}
2489
Steve Anton75737c02017-11-06 18:37:172490void PeerConnection::OnTransportControllerDtlsHandshakeError(
2491 rtc::SSLHandshakeError error) {
Qingsi Wang7fc821d2018-07-12 19:54:532492 RTC_HISTOGRAM_ENUMERATION(
2493 "WebRTC.PeerConnection.DtlsHandshakeError", static_cast<int>(error),
2494 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
Steve Anton75737c02017-11-06 18:37:172495}
2496
Steve Anton75737c02017-11-06 18:37:172497// Returns the media index for a local ice candidate given the content name.
2498bool PeerConnection::GetLocalCandidateMediaIndex(
2499 const std::string& content_name,
2500 int* sdp_mline_index) {
2501 if (!local_description() || !sdp_mline_index) {
2502 return false;
2503 }
2504
2505 bool content_found = false;
2506 const ContentInfos& contents = local_description()->description()->contents();
2507 for (size_t index = 0; index < contents.size(); ++index) {
2508 if (contents[index].name == content_name) {
2509 *sdp_mline_index = static_cast<int>(index);
2510 content_found = true;
2511 break;
2512 }
2513 }
2514 return content_found;
2515}
2516
Steve Anton75737c02017-11-06 18:37:172517Call::Stats PeerConnection::GetCallStats() {
2518 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:102519 return worker_thread()->BlockingCall([this] { return GetCallStats(); });
Steve Anton75737c02017-11-06 18:37:172520 }
Karl Wiberg6cab5c82019-03-26 08:57:012521 RTC_DCHECK_RUN_ON(worker_thread());
Henrik Boströme88c95e2020-07-08 09:18:502522 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton75737c02017-11-06 18:37:172523 if (call_) {
2524 return call_->GetStats();
2525 } else {
2526 return Call::Stats();
2527 }
2528}
2529
Fredrik Hernqvistefbe7532023-01-13 15:42:362530absl::optional<AudioDeviceModule::Stats> PeerConnection::GetAudioDeviceStats() {
2531 if (context_->media_engine()) {
2532 return context_->media_engine()->voice().GetAudioDeviceStats();
2533 }
2534 return absl::nullopt;
2535}
2536
Tommiaa3c9f22023-04-18 10:19:192537absl::optional<std::string> PeerConnection::SetupDataChannelTransport_n(
2538 absl::string_view mid) {
2539 sctp_mid_n_ = std::string(mid);
Bjorn A Mellembc3eebc2019-09-23 21:53:542540 DataChannelTransportInterface* transport =
Tommiaa3c9f22023-04-18 10:19:192541 transport_controller_->GetDataChannelTransport(*sctp_mid_n_);
Bjorn A Mellembc3eebc2019-09-23 21:53:542542 if (!transport) {
Piotr (Peter) Slatalab1ae10b2019-03-01 19:14:052543 RTC_LOG(LS_ERROR)
Bjorn A Mellemb689af42019-08-21 17:44:592544 << "Data channel transport is not available for data channels, mid="
2545 << mid;
Tommiaa3c9f22023-04-18 10:19:192546 sctp_mid_n_ = absl::nullopt;
2547 return absl::nullopt;
Bjorn Mellem175aa2e2018-11-08 19:23:222548 }
2549
Tommiaa3c9f22023-04-18 10:19:192550 absl::optional<std::string> transport_name;
Tomas Gunnarssone1c8a432021-04-08 13:15:282551 cricket::DtlsTransportInternal* dtls_transport =
Tommiaa3c9f22023-04-18 10:19:192552 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson92eebef2021-02-10 12:05:442553 if (dtls_transport) {
Tommiaa3c9f22023-04-18 10:19:192554 transport_name = dtls_transport->transport_name();
2555 } else {
2556 // Make sure we still set a valid string.
2557 transport_name = std::string("");
Tomas Gunnarsson92eebef2021-02-10 12:05:442558 }
Bjorn A Mellembc3eebc2019-09-23 21:53:542559
Tommiaa3c9f22023-04-18 10:19:192560 data_channel_controller_.SetupDataChannelTransport_n(transport);
2561
2562 return transport_name;
Bjorn Mellem175aa2e2018-11-08 19:23:222563}
2564
Tommib00d63c2023-04-12 17:49:532565void PeerConnection::TeardownDataChannelTransport_n(RTCError error) {
Tomas Gunnarssond69e0702021-04-07 13:14:432566 if (sctp_mid_n_) {
Artem Titov880fa812021-07-30 20:30:232567 // `sctp_mid_` may still be active through an SCTP transport. If not, unset
Tomas Gunnarssond69e0702021-04-07 13:14:432568 // it.
2569 RTC_LOG(LS_INFO) << "Tearing down data channel transport for mid="
2570 << *sctp_mid_n_;
2571 sctp_mid_n_.reset();
2572 }
2573
Tommib00d63c2023-04-12 17:49:532574 data_channel_controller_.TeardownDataChannelTransport_n(error);
Bjorn Mellem175aa2e2018-11-08 19:23:222575}
2576
Steve Anton75737c02017-11-06 18:37:172577// Returns false if bundle is enabled and rtcp_mux is disabled.
Henrik Boströmf8187e02021-04-26 19:04:262578bool PeerConnection::ValidateBundleSettings(
2579 const SessionDescription* desc,
2580 const std::map<std::string, const cricket::ContentGroup*>&
2581 bundle_groups_by_mid) {
2582 if (bundle_groups_by_mid.empty())
Steve Anton75737c02017-11-06 18:37:172583 return true;
2584
Steve Anton75737c02017-11-06 18:37:172585 const cricket::ContentInfos& contents = desc->contents();
2586 for (cricket::ContentInfos::const_iterator citer = contents.begin();
2587 citer != contents.end(); ++citer) {
2588 const cricket::ContentInfo* content = (&*citer);
2589 RTC_DCHECK(content != NULL);
Henrik Boströmf8187e02021-04-26 19:04:262590 auto it = bundle_groups_by_mid.find(content->name);
Philipp Hancke32dae4b2023-05-12 04:53:552591 if (it != bundle_groups_by_mid.end() &&
2592 !(content->rejected || content->bundle_only) &&
Steve Anton5adfafd2017-12-21 00:34:002593 content->type == MediaProtocolType::kRtp) {
Steve Anton75737c02017-11-06 18:37:172594 if (!HasRtcpMuxEnabled(content))
2595 return false;
2596 }
2597 }
2598 // RTCP-MUX is enabled in all the contents.
2599 return true;
2600}
2601
Philipp Hancke54b925c2021-01-28 08:56:392602void PeerConnection::ReportSdpBundleUsage(
2603 const SessionDescriptionInterface& remote_description) {
2604 RTC_DCHECK_RUN_ON(signaling_thread());
2605
2606 bool using_bundle =
2607 remote_description.description()->HasGroup(cricket::GROUP_TYPE_BUNDLE);
2608 int num_audio_mlines = 0;
2609 int num_video_mlines = 0;
2610 int num_data_mlines = 0;
2611 for (const ContentInfo& content :
2612 remote_description.description()->contents()) {
2613 cricket::MediaType media_type = content.media_description()->type();
2614 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2615 num_audio_mlines += 1;
2616 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2617 num_video_mlines += 1;
2618 } else if (media_type == cricket::MEDIA_TYPE_DATA) {
2619 num_data_mlines += 1;
2620 }
2621 }
2622 bool simple = num_audio_mlines <= 1 && num_video_mlines <= 1;
2623 BundleUsage usage = kBundleUsageMax;
2624 if (num_audio_mlines == 0 && num_video_mlines == 0) {
2625 if (num_data_mlines > 0) {
2626 usage = using_bundle ? kBundleUsageBundleDatachannelOnly
2627 : kBundleUsageNoBundleDatachannelOnly;
2628 } else {
2629 usage = kBundleUsageEmpty;
2630 }
Harald Alvestrandfa67aef2021-12-08 14:30:552631 } else if (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
Philipp Hancke54b925c2021-01-28 08:56:392632 // In plan-b, simple/complex usage will not show up in the number of
2633 // m-lines or BUNDLE.
2634 usage = using_bundle ? kBundleUsageBundlePlanB : kBundleUsageNoBundlePlanB;
2635 } else {
2636 if (simple) {
2637 usage =
2638 using_bundle ? kBundleUsageBundleSimple : kBundleUsageNoBundleSimple;
2639 } else {
2640 usage = using_bundle ? kBundleUsageBundleComplex
2641 : kBundleUsageNoBundleComplex;
2642 }
2643 }
2644 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundleUsage", usage,
2645 kBundleUsageMax);
2646}
2647
Qingsi Wang1ba5dec2019-08-19 18:57:172648void PeerConnection::ReportIceCandidateCollected(
2649 const cricket::Candidate& candidate) {
2650 NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
2651 if (candidate.address().IsPrivateIP()) {
2652 NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
2653 }
2654 if (candidate.address().IsUnresolvedIP()) {
2655 NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
2656 }
2657 if (candidate.address().family() == AF_INET6) {
2658 NoteUsageEvent(UsageEvent::IPV6_CANDIDATE_COLLECTED);
2659 }
2660}
2661
Harald Alvestrand8ebba742018-05-31 12:00:342662void PeerConnection::NoteUsageEvent(UsageEvent event) {
2663 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand44d0dff2020-10-09 05:43:532664 usage_pattern_.NoteUsageEvent(event);
Harald Alvestrand8ebba742018-05-31 12:00:342665}
2666
Tomas Gunnarsson8cb97062021-02-08 17:57:042667// Asynchronously adds remote candidates on the network thread.
2668void PeerConnection::AddRemoteCandidate(const std::string& mid,
2669 const cricket::Candidate& candidate) {
2670 RTC_DCHECK_RUN_ON(signaling_thread());
2671
Byoungchan Lee5a925772022-10-18 17:43:182672 if (candidate.network_type() != rtc::ADAPTER_TYPE_UNKNOWN) {
2673 RTC_DLOG(LS_WARNING) << "Using candidate with adapter type set - this "
2674 "should only happen in test";
2675 }
2676
2677 // Clear fields that do not make sense as remote candidates.
2678 cricket::Candidate new_candidate(candidate);
2679 new_candidate.set_network_type(rtc::ADAPTER_TYPE_UNKNOWN);
2680 new_candidate.set_relay_protocol("");
2681 new_candidate.set_underlying_type_for_vpn(rtc::ADAPTER_TYPE_UNKNOWN);
2682
Danil Chapovalova30439b2022-07-07 08:08:492683 network_thread()->PostTask(SafeTask(
Byoungchan Lee5a925772022-10-18 17:43:182684 network_thread_safety_, [this, mid = mid, candidate = new_candidate] {
Tomas Gunnarsson8cb97062021-02-08 17:57:042685 RTC_DCHECK_RUN_ON(network_thread());
2686 std::vector<cricket::Candidate> candidates = {candidate};
2687 RTCError error =
2688 transport_controller_->AddRemoteCandidates(mid, candidates);
2689 if (error.ok()) {
Danil Chapovalova30439b2022-07-07 08:08:492690 signaling_thread()->PostTask(SafeTask(
Tomas Gunnarsson8cb97062021-02-08 17:57:042691 signaling_thread_safety_.flag(),
2692 [this, candidate = std::move(candidate)] {
2693 ReportRemoteIceCandidateAdded(candidate);
2694 // Candidates successfully submitted for checking.
2695 if (ice_connection_state() ==
2696 PeerConnectionInterface::kIceConnectionNew ||
2697 ice_connection_state() ==
2698 PeerConnectionInterface::kIceConnectionDisconnected) {
2699 // If state is New, then the session has just gotten its first
2700 // remote ICE candidates, so go to Checking. If state is
2701 // Disconnected, the session is re-using old candidates or
2702 // receiving additional ones, so go to Checking. If state is
2703 // Connected, stay Connected.
2704 // TODO(bemasc): If state is Connected, and the new candidates
2705 // are for a newly added transport, then the state actually
2706 // _should_ move to checking. Add a way to distinguish that
2707 // case.
2708 SetIceConnectionState(
2709 PeerConnectionInterface::kIceConnectionChecking);
2710 }
2711 // TODO(bemasc): If state is Completed, go back to Connected.
2712 }));
2713 } else {
2714 RTC_LOG(LS_WARNING) << error.message();
2715 }
2716 }));
2717}
2718
Harald Alvestrand8ebba742018-05-31 12:00:342719void PeerConnection::ReportUsagePattern() const {
Harald Alvestrand44d0dff2020-10-09 05:43:532720 usage_pattern_.ReportUsagePattern(observer_);
Harald Alvestrand8ebba742018-05-31 12:00:342721}
2722
Tomas Gunnarsson8cb97062021-02-08 17:57:042723void PeerConnection::ReportRemoteIceCandidateAdded(
2724 const cricket::Candidate& candidate) {
2725 RTC_DCHECK_RUN_ON(signaling_thread());
2726
2727 NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED);
2728
2729 if (candidate.address().IsPrivateIP()) {
2730 NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED);
2731 }
2732 if (candidate.address().IsUnresolvedIP()) {
2733 NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED);
2734 }
2735 if (candidate.address().family() == AF_INET6) {
2736 NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED);
2737 }
2738}
2739
Steve Anton75737c02017-11-06 18:37:172740bool PeerConnection::SrtpRequired() const {
Tomas Gunnarsson3278a712021-03-30 15:23:422741 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand0d018412021-11-04 13:52:312742 return (dtls_enabled_ ||
2743 sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() ==
2744 cricket::SEC_REQUIRED);
Steve Anton75737c02017-11-06 18:37:172745}
2746
2747void PeerConnection::OnTransportControllerGatheringState(
2748 cricket::IceGatheringState state) {
2749 RTC_DCHECK(signaling_thread()->IsCurrent());
2750 if (state == cricket::kIceGatheringGathering) {
2751 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
2752 } else if (state == cricket::kIceGatheringComplete) {
2753 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
Harald Alvestrandbedb6052020-08-20 12:50:102754 } else if (state == cricket::kIceGatheringNew) {
2755 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew);
2756 } else {
2757 RTC_LOG(LS_ERROR) << "Unknown state received: " << state;
Artem Titovd3251962021-11-15 15:57:072758 RTC_DCHECK_NOTREACHED();
Steve Anton75737c02017-11-06 18:37:172759 }
2760}
2761
Tomas Gunnarsson2001dc32021-04-06 09:36:002762// Runs on network_thread().
Tommidba22d32023-06-01 14:08:522763void PeerConnection::ReportTransportStats(
2764 std::vector<RtpTransceiverProxyRefPtr> transceivers) {
Markus Handell518669d2021-06-07 11:30:462765 TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
Tommic3257d02021-02-10 17:40:082766 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Antonc7b964c2018-02-01 22:39:452767 std::map<std::string, std::set<cricket::MediaType>>
2768 media_types_by_transport_name;
Tommidba22d32023-06-01 14:08:522769 for (const auto& transceiver : transceivers) {
2770 if (transceiver->internal()->channel()) {
2771 std::string transport_name(
2772 transceiver->internal()->channel()->transport_name());
2773 media_types_by_transport_name[transport_name].insert(
2774 transceiver->media_type());
Steve Antonc7b964c2018-02-01 22:39:452775 }
Steve Anton75737c02017-11-06 18:37:172776 }
Tomas Gunnarsson2001dc32021-04-06 09:36:002777
Tomas Gunnarsson2001dc32021-04-06 09:36:002778 if (sctp_mid_n_) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282779 cricket::DtlsTransportInternal* dtls_transport =
2780 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson2001dc32021-04-06 09:36:002781 if (dtls_transport) {
2782 media_types_by_transport_name[dtls_transport->transport_name()].insert(
2783 cricket::MEDIA_TYPE_DATA);
2784 }
Steve Anton75737c02017-11-06 18:37:172785 }
Zhi Huange830e682018-03-30 17:48:352786
Tomas Gunnarsson2001dc32021-04-06 09:36:002787 for (const auto& entry : media_types_by_transport_name) {
2788 const std::string& transport_name = entry.first;
2789 const std::set<cricket::MediaType> media_types = entry.second;
2790 cricket::TransportStats stats;
2791 if (transport_controller_->GetStats(transport_name, &stats)) {
2792 ReportBestConnectionState(stats);
2793 ReportNegotiatedCiphers(dtls_enabled_, stats, media_types);
2794 }
2795 }
Steve Anton75737c02017-11-06 18:37:172796}
Tomas Gunnarsson2001dc32021-04-06 09:36:002797
Steve Anton75737c02017-11-06 18:37:172798// Walk through the ConnectionInfos to gather best connection usage
2799// for IPv4 and IPv6.
Tommic3257d02021-02-10 17:40:082800// static (no member state required)
Steve Anton75737c02017-11-06 18:37:172801void PeerConnection::ReportBestConnectionState(
2802 const cricket::TransportStats& stats) {
Steve Antonc7b964c2018-02-01 22:39:452803 for (const cricket::TransportChannelStats& channel_stats :
2804 stats.channel_stats) {
2805 for (const cricket::ConnectionInfo& connection_info :
Jonas Oreland149dc722019-08-28 06:10:272806 channel_stats.ice_transport_stats.connection_infos) {
Steve Antonc7b964c2018-02-01 22:39:452807 if (!connection_info.best_connection) {
Steve Anton75737c02017-11-06 18:37:172808 continue;
2809 }
2810
Steve Antonc7b964c2018-02-01 22:39:452811 const cricket::Candidate& local = connection_info.local_candidate;
2812 const cricket::Candidate& remote = connection_info.remote_candidate;
Steve Anton75737c02017-11-06 18:37:172813
2814 // Increment the counter for IceCandidatePairType.
2815 if (local.protocol() == cricket::TCP_PROTOCOL_NAME ||
2816 (local.type() == RELAY_PORT_TYPE &&
2817 local.relay_protocol() == cricket::TCP_PROTOCOL_NAME)) {
Qingsi Wang7fc821d2018-07-12 19:54:532818 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_TCP",
2819 GetIceCandidatePairCounter(local, remote),
2820 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 18:37:172821 } else if (local.protocol() == cricket::UDP_PROTOCOL_NAME) {
Qingsi Wang7fc821d2018-07-12 19:54:532822 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_UDP",
2823 GetIceCandidatePairCounter(local, remote),
2824 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 18:37:172825 } else {
Karl Wibergc95b9392020-11-07 23:49:372826 RTC_CHECK_NOTREACHED();
Steve Anton75737c02017-11-06 18:37:172827 }
Steve Anton75737c02017-11-06 18:37:172828
2829 // Increment the counter for IP type.
2830 if (local.address().family() == AF_INET) {
Qingsi Wang7fc821d2018-07-12 19:54:532831 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2832 kBestConnections_IPv4,
2833 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 18:37:172834 } else if (local.address().family() == AF_INET6) {
Qingsi Wang7fc821d2018-07-12 19:54:532835 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2836 kBestConnections_IPv6,
2837 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 18:37:172838 } else {
Qingsi Wang1dac6d82018-12-12 23:28:472839 RTC_CHECK(!local.address().hostname().empty() &&
2840 local.address().IsUnresolvedIP());
Steve Anton75737c02017-11-06 18:37:172841 }
2842
2843 return;
2844 }
2845 }
2846}
2847
Tommic3257d02021-02-10 17:40:082848// static
Steve Anton75737c02017-11-06 18:37:172849void PeerConnection::ReportNegotiatedCiphers(
Tommic3257d02021-02-10 17:40:082850 bool dtls_enabled,
Steve Antonc7b964c2018-02-01 22:39:452851 const cricket::TransportStats& stats,
2852 const std::set<cricket::MediaType>& media_types) {
Tommic3257d02021-02-10 17:40:082853 if (!dtls_enabled || stats.channel_stats.empty()) {
Steve Anton75737c02017-11-06 18:37:172854 return;
2855 }
2856
2857 int srtp_crypto_suite = stats.channel_stats[0].srtp_crypto_suite;
2858 int ssl_cipher_suite = stats.channel_stats[0].ssl_cipher_suite;
Mirko Bonadei7750d802021-07-26 15:27:422859 if (srtp_crypto_suite == rtc::kSrtpInvalidCryptoSuite &&
2860 ssl_cipher_suite == rtc::kTlsNullWithNullNull) {
Steve Anton75737c02017-11-06 18:37:172861 return;
2862 }
2863
Mirko Bonadei7750d802021-07-26 15:27:422864 if (ssl_cipher_suite != rtc::kTlsNullWithNullNull) {
Qingsi Wang7fc821d2018-07-12 19:54:532865 for (cricket::MediaType media_type : media_types) {
2866 switch (media_type) {
2867 case cricket::MEDIA_TYPE_AUDIO:
2868 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2869 "WebRTC.PeerConnection.SslCipherSuite.Audio", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422870 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532871 break;
2872 case cricket::MEDIA_TYPE_VIDEO:
2873 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2874 "WebRTC.PeerConnection.SslCipherSuite.Video", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422875 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532876 break;
2877 case cricket::MEDIA_TYPE_DATA:
2878 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2879 "WebRTC.PeerConnection.SslCipherSuite.Data", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422880 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532881 break;
2882 default:
Artem Titovd3251962021-11-15 15:57:072883 RTC_DCHECK_NOTREACHED();
Qingsi Wang7fc821d2018-07-12 19:54:532884 continue;
2885 }
Steve Antonc7b964c2018-02-01 22:39:452886 }
Steve Anton75737c02017-11-06 18:37:172887 }
2888}
2889
Taylor Brandstettercbaa2542018-04-16 23:42:142890bool PeerConnection::OnTransportChanged(
Zhi Huange830e682018-03-30 17:48:352891 const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 23:42:142892 RtpTransportInternal* rtp_transport,
Harald Alvestrandc85328f2019-02-28 06:51:002893 rtc::scoped_refptr<DtlsTransport> dtls_transport,
Bjorn A Mellembc3eebc2019-09-23 21:53:542894 DataChannelTransportInterface* data_channel_transport) {
Karl Wibergac025892019-03-26 12:08:372895 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstettercbaa2542018-04-16 23:42:142896 bool ret = true;
Harald Alvestrand8101e7b2022-05-23 14:57:472897 if (ConfiguredForMedia()) {
2898 for (const auto& transceiver :
2899 rtp_manager()->transceivers()->UnsafeList()) {
2900 cricket::ChannelInterface* channel = transceiver->internal()->channel();
2901 if (channel && channel->mid() == mid) {
2902 ret = channel->SetRtpTransport(rtp_transport);
2903 }
Harald Alvestrand19ebabc2022-04-28 13:31:172904 }
Zhi Huange830e682018-03-30 17:48:352905 }
Tomas Gunnarsson92eebef2021-02-10 12:05:442906
Harald Alvestrand7a829a82020-02-12 06:38:212907 if (mid == sctp_mid_n_) {
Harald Alvestrand00cf34c2019-12-02 08:56:022908 data_channel_controller_.OnTransportChanged(data_channel_transport);
Tomas Gunnarsson92eebef2021-02-10 12:05:442909 if (dtls_transport) {
Danil Chapovalova30439b2022-07-07 08:08:492910 signaling_thread()->PostTask(SafeTask(
Tomas Gunnarsson92eebef2021-02-10 12:05:442911 signaling_thread_safety_.flag(),
Tomas Gunnarsson94f01942022-01-03 14:59:122912 [this,
2913 name = std::string(dtls_transport->internal()->transport_name())] {
Tomas Gunnarsson92eebef2021-02-10 12:05:442914 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström46053e42023-01-20 12:18:532915 SetSctpTransportName(std::move(name));
Tomas Gunnarsson92eebef2021-02-10 12:05:442916 }));
2917 }
Bjorn A Mellemb689af42019-08-21 17:44:592918 }
Tomas Gunnarsson92eebef2021-02-10 12:05:442919
Taylor Brandstettercbaa2542018-04-16 23:42:142920 return ret;
Steve Anton75737c02017-11-06 18:37:172921}
2922
Harald Alvestrand7a1c7f72018-08-01 08:50:162923PeerConnectionObserver* PeerConnection::Observer() const {
Harald Alvestrand05e4d082019-12-03 13:04:212924 RTC_DCHECK_RUN_ON(signaling_thread());
2925 RTC_DCHECK(observer_);
Harald Alvestrand7a1c7f72018-08-01 08:50:162926 return observer_;
2927}
2928
Tomas Gunnarsson92eebef2021-02-10 12:05:442929void PeerConnection::StartSctpTransport(int local_port,
2930 int remote_port,
2931 int max_message_size) {
2932 RTC_DCHECK_RUN_ON(signaling_thread());
2933 if (!sctp_mid_s_)
2934 return;
2935
Danil Chapovalova30439b2022-07-07 08:08:492936 network_thread()->PostTask(SafeTask(
Tomas Gunnarsson92eebef2021-02-10 12:05:442937 network_thread_safety_,
2938 [this, mid = *sctp_mid_s_, local_port, remote_port, max_message_size] {
2939 rtc::scoped_refptr<SctpTransport> sctp_transport =
Harald Alvestrandbc32c562022-02-09 12:08:472940 transport_controller_n()->GetSctpTransport(mid);
Tomas Gunnarsson92eebef2021-02-10 12:05:442941 if (sctp_transport)
2942 sctp_transport->Start(local_port, remote_port, max_message_size);
2943 }));
2944}
2945
Benjamin Wright8c27cca2018-10-25 17:16:442946CryptoOptions PeerConnection::GetCryptoOptions() {
Harald Alvestrandc06e3742020-10-01 10:23:332947 RTC_DCHECK_RUN_ON(signaling_thread());
Benjamin Wright8c27cca2018-10-25 17:16:442948 // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions
2949 // after it has been removed.
2950 return configuration_.crypto_options.has_value()
2951 ? *configuration_.crypto_options
Harald Alvestrand4da4a872020-11-04 10:34:212952 : options_.crypto_options;
Benjamin Wright8c27cca2018-10-25 17:16:442953}
2954
Harald Alvestrand89061872018-01-02 13:08:342955void PeerConnection::ClearStatsCache() {
Karl Wiberg6cab5c82019-03-26 08:57:012956 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hancke7baa63f2022-09-01 13:39:502957 if (legacy_stats_) {
2958 legacy_stats_->InvalidateCache();
2959 }
Harald Alvestrand89061872018-01-02 13:08:342960 if (stats_collector_) {
2961 stats_collector_->ClearCachedStatsReport();
2962 }
2963}
2964
Henrik Boströme574a312020-08-25 08:20:112965bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
2966 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:432967 return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
Eldar Rello5ab79e62019-10-09 15:29:442968}
2969
Harald Alvestrand1090e442020-10-05 07:01:092970void PeerConnection::RequestUsagePatternReportForTesting() {
Harald Alvestrand00c62ed2021-10-20 08:52:122971 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand1090e442020-10-05 07:01:092972 message_handler_.RequestUsagePatternReport(
2973 [this]() {
2974 RTC_DCHECK_RUN_ON(signaling_thread());
2975 ReportUsagePattern();
2976 },
2977 /* delay_ms= */ 0);
2978}
2979
Tomas Gunnarsson1e40a0c2020-09-28 08:39:312980std::function<void(const rtc::CopyOnWriteBuffer& packet,
2981 int64_t packet_time_us)>
2982PeerConnection::InitializeRtcpCallback() {
Tommic3257d02021-02-10 17:40:082983 RTC_DCHECK_RUN_ON(network_thread());
Per Kcf439a02023-01-05 13:01:392984 return [this](const rtc::CopyOnWriteBuffer& packet,
2985 int64_t /*packet_time_us*/) {
2986 worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, packet]() {
2987 call_ptr_->Receiver()->DeliverRtcpPacket(packet);
2988 }));
Tomas Gunnarsson1e40a0c2020-09-28 08:39:312989 };
2990}
Harald Alvestrandcdcfab02020-09-28 13:02:072991
Per Ke1e94ad2023-03-30 14:53:592992std::function<void(const RtpPacketReceived& parsed_packet)>
2993PeerConnection::InitializeUnDemuxablePacketHandler() {
2994 RTC_DCHECK_RUN_ON(network_thread());
2995 return [this](const RtpPacketReceived& parsed_packet) {
2996 worker_thread()->PostTask(
2997 SafeTask(worker_thread_safety_, [this, parsed_packet]() {
2998 // Deliver the packet anyway to Call to allow Call to do BWE.
2999 // Even if there is no media receiver, the packet has still
3000 // been received on the network and has been correcly parsed.
3001 call_ptr_->Receiver()->DeliverRtpPacket(
3002 MediaType::ANY, parsed_packet,
3003 /*undemuxable_packet_handler=*/
3004 [](const RtpPacketReceived& packet) { return false; });
3005 }));
3006 };
3007}
3008
henrike@webrtc.org28e20752013-07-10 00:45:363009} // namespace webrtc