blob: 444a0bf618ff1709f34097171f01e3b550f2f7b1 [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"
Danil Chapovalov3bdb49b2023-11-30 07:59:3926#include "api/environment/environment.h"
Steve Anton10542f22019-01-11 17:11:0027#include "api/jsep_ice_candidate.h"
Per Ke1e94ad2023-03-30 14:53:5928#include "api/media_types.h"
Harald Alvestrand763f5a92020-10-22 10:39:4029#include "api/rtp_parameters.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4730#include "api/rtp_transceiver_direction.h"
Steve Anton10542f22019-01-11 17:11:0031#include "api/uma_metrics.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4732#include "api/video/video_codec_constants.h"
33#include "call/audio_state.h"
34#include "call/packet_receiver.h"
Harald Alvestrand763f5a92020-10-22 10:39:4035#include "media/base/media_channel.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4736#include "media/base/media_config.h"
Harald Alvestrand0d4af122022-01-31 09:36:0537#include "media/base/media_engine.h"
Amit Hilbuchf4770402019-04-08 21:11:5738#include "media/base/rid_description.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4739#include "media/base/stream_params.h"
40#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Harald Alvestrand0ccfbd22021-04-08 07:25:0441#include "p2p/base/basic_async_resolver_factory.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4742#include "p2p/base/connection.h"
43#include "p2p/base/connection_info.h"
44#include "p2p/base/dtls_transport_internal.h"
45#include "p2p/base/p2p_constants.h"
46#include "p2p/base/p2p_transport_channel.h"
47#include "p2p/base/transport_info.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4748#include "pc/ice_server_parsing.h"
Harald Alvestrand763f5a92020-10-22 10:39:4049#include "pc/rtp_receiver.h"
Harald Alvestrand0d4af122022-01-31 09:36:0550#include "pc/rtp_receiver_proxy.h"
Harald Alvestrand763f5a92020-10-22 10:39:4051#include "pc/rtp_sender.h"
Harald Alvestrand0d4af122022-01-31 09:36:0552#include "pc/rtp_sender_proxy.h"
Harald Alvestrandc85328f2019-02-28 06:51:0053#include "pc/sctp_transport.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4754#include "pc/simulcast_description.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4755#include "pc/webrtc_session_description_factory.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4756#include "rtc_base/helpers.h"
57#include "rtc_base/ip_address.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3158#include "rtc_base/logging.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4759#include "rtc_base/net_helper.h"
Harald Alvestrand0d4af122022-01-31 09:36:0560#include "rtc_base/network.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4761#include "rtc_base/network_constants.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4762#include "rtc_base/socket_address.h"
Steve Anton10542f22019-01-11 17:11:0063#include "rtc_base/string_encode.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3164#include "rtc_base/trace_event.h"
Harald Alvestrand763f5a92020-10-22 10:39:4065#include "rtc_base/unique_id_generator.h"
Qingsi Wang7fc821d2018-07-12 19:54:5366#include "system_wrappers/include/metrics.h"
henrike@webrtc.org28e20752013-07-10 00:45:3667
Steve Anton75737c02017-11-06 18:37:1768using cricket::ContentInfo;
69using cricket::ContentInfos;
70using cricket::MediaContentDescription;
Steve Anton5adfafd2017-12-21 00:34:0071using cricket::MediaProtocolType;
Amit Hilbuchbcd39d42019-01-26 01:13:5672using cricket::RidDescription;
73using cricket::RidDirection;
Amit Hilbuchc63ddb22019-01-02 18:13:5874using cricket::SessionDescription;
Amit Hilbuchbcd39d42019-01-26 01:13:5675using cricket::SimulcastDescription;
76using cricket::SimulcastLayer;
Amit Hilbuchc63ddb22019-01-02 18:13:5877using cricket::SimulcastLayerList;
Amit Hilbuchbcd39d42019-01-26 01:13:5678using cricket::StreamParams;
Steve Anton75737c02017-11-06 18:37:1779using cricket::TransportInfo;
80
Steve Antonba818672017-11-06 18:21:5781namespace webrtc {
82
Steve Anton75737c02017-11-06 18:37:1783namespace {
henrike@webrtc.org28e20752013-07-10 00:45:3684
Harald Alvestrand19793842018-06-25 10:03:5085static const int REPORT_USAGE_PATTERN_DELAY_MS = 60000;
86
Taylor Brandstettera1c30352016-05-13 15:15:1187uint32_t ConvertIceTransportTypeToCandidateFilter(
88 PeerConnectionInterface::IceTransportsType type) {
89 switch (type) {
90 case PeerConnectionInterface::kNone:
91 return cricket::CF_NONE;
92 case PeerConnectionInterface::kRelay:
93 return cricket::CF_RELAY;
94 case PeerConnectionInterface::kNoHost:
95 return (cricket::CF_ALL & ~cricket::CF_HOST);
96 case PeerConnectionInterface::kAll:
97 return cricket::CF_ALL;
98 default:
Artem Titovd3251962021-11-15 15:57:0799 RTC_DCHECK_NOTREACHED();
Taylor Brandstettera1c30352016-05-13 15:15:11100 }
101 return cricket::CF_NONE;
102}
103
Steve Anton75737c02017-11-06 18:37:17104IceCandidatePairType GetIceCandidatePairCounter(
105 const cricket::Candidate& local,
106 const cricket::Candidate& remote) {
Tommi698b4e72024-01-24 07:36:45107 if (local.is_local() && remote.is_local()) {
Jeroen de Borst833979f2018-12-13 16:25:54108 bool local_hostname =
109 !local.address().hostname().empty() && local.address().IsUnresolvedIP();
110 bool remote_hostname = !remote.address().hostname().empty() &&
111 remote.address().IsUnresolvedIP();
Steve Anton75737c02017-11-06 18:37:17112 bool local_private = IPIsPrivate(local.address().ipaddr());
113 bool remote_private = IPIsPrivate(remote.address().ipaddr());
Jeroen de Borst833979f2018-12-13 16:25:54114 if (local_hostname) {
115 if (remote_hostname) {
116 return kIceCandidatePairHostNameHostName;
117 } else if (remote_private) {
118 return kIceCandidatePairHostNameHostPrivate;
119 } else {
120 return kIceCandidatePairHostNameHostPublic;
121 }
122 } else if (local_private) {
123 if (remote_hostname) {
124 return kIceCandidatePairHostPrivateHostName;
125 } else if (remote_private) {
Steve Anton75737c02017-11-06 18:37:17126 return kIceCandidatePairHostPrivateHostPrivate;
127 } else {
128 return kIceCandidatePairHostPrivateHostPublic;
129 }
130 } else {
Jeroen de Borst833979f2018-12-13 16:25:54131 if (remote_hostname) {
132 return kIceCandidatePairHostPublicHostName;
133 } else if (remote_private) {
Steve Anton75737c02017-11-06 18:37:17134 return kIceCandidatePairHostPublicHostPrivate;
135 } else {
136 return kIceCandidatePairHostPublicHostPublic;
137 }
138 }
139 }
Tommi698b4e72024-01-24 07:36:45140
141 if (local.is_local()) {
142 if (remote.is_stun())
143 return kIceCandidatePairHostSrflx;
144 if (remote.is_relay())
145 return kIceCandidatePairHostRelay;
146 if (remote.is_prflx())
147 return kIceCandidatePairHostPrflx;
148 } else if (local.is_stun()) {
149 if (remote.is_local())
150 return kIceCandidatePairSrflxHost;
151 if (remote.is_stun())
152 return kIceCandidatePairSrflxSrflx;
153 if (remote.is_relay())
154 return kIceCandidatePairSrflxRelay;
155 if (remote.is_prflx())
156 return kIceCandidatePairSrflxPrflx;
157 } else if (local.is_relay()) {
158 if (remote.is_local())
159 return kIceCandidatePairRelayHost;
160 if (remote.is_stun())
161 return kIceCandidatePairRelaySrflx;
162 if (remote.is_relay())
163 return kIceCandidatePairRelayRelay;
164 if (remote.is_prflx())
165 return kIceCandidatePairRelayPrflx;
166 } else if (local.is_prflx()) {
167 if (remote.is_local())
168 return kIceCandidatePairPrflxHost;
169 if (remote.is_stun())
170 return kIceCandidatePairPrflxSrflx;
171 if (remote.is_relay())
172 return kIceCandidatePairPrflxRelay;
173 }
174
Steve Anton75737c02017-11-06 18:37:17175 return kIceCandidatePairMax;
176}
177
Danil Chapovalov66cadcc2018-06-19 14:47:43178absl::optional<int> RTCConfigurationToIceConfigOptionalInt(
Qingsi Wang866e08d2018-03-23 00:54:23179 int rtc_configuration_parameter) {
180 if (rtc_configuration_parameter ==
Harald Alvestranda6544372023-11-13 09:33:56181 PeerConnectionInterface::RTCConfiguration::kUndefined) {
Danil Chapovalov66cadcc2018-06-19 14:47:43182 return absl::nullopt;
Qingsi Wang866e08d2018-03-23 00:54:23183 }
184 return rtc_configuration_parameter;
185}
186
Jonas Orelande3096512020-05-27 07:01:05187// Check if the changes of IceTransportsType motives an ice restart.
188bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,
189 PeerConnectionInterface::IceTransportsType current,
190 PeerConnectionInterface::IceTransportsType modified) {
191 if (current == modified) {
192 return false;
193 }
194
195 if (!surface_ice_candidates_on_ice_transport_type_changed) {
196 return true;
197 }
198
199 auto current_filter = ConvertIceTransportTypeToCandidateFilter(current);
200 auto modified_filter = ConvertIceTransportTypeToCandidateFilter(modified);
201
202 // If surface_ice_candidates_on_ice_transport_type_changed is true and we
203 // extend the filter, then no ice restart is needed.
204 return (current_filter & modified_filter) != current_filter;
205}
206
Harald Alvestrand62166932020-10-26 08:30:41207cricket::IceConfig ParseIceConfig(
208 const PeerConnectionInterface::RTCConfiguration& config) {
209 cricket::ContinualGatheringPolicy gathering_policy;
210 switch (config.continual_gathering_policy) {
211 case PeerConnectionInterface::GATHER_ONCE:
212 gathering_policy = cricket::GATHER_ONCE;
213 break;
214 case PeerConnectionInterface::GATHER_CONTINUALLY:
215 gathering_policy = cricket::GATHER_CONTINUALLY;
216 break;
217 default:
Artem Titovd3251962021-11-15 15:57:07218 RTC_DCHECK_NOTREACHED();
Harald Alvestrand62166932020-10-26 08:30:41219 gathering_policy = cricket::GATHER_ONCE;
220 }
221
222 cricket::IceConfig ice_config;
223 ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt(
224 config.ice_connection_receiving_timeout);
225 ice_config.prioritize_most_likely_candidate_pairs =
226 config.prioritize_most_likely_ice_candidate_pairs;
227 ice_config.backup_connection_ping_interval =
228 RTCConfigurationToIceConfigOptionalInt(
229 config.ice_backup_candidate_pair_ping_interval);
230 ice_config.continual_gathering_policy = gathering_policy;
231 ice_config.presume_writable_when_fully_relayed =
232 config.presume_writable_when_fully_relayed;
233 ice_config.surface_ice_candidates_on_ice_transport_type_changed =
234 config.surface_ice_candidates_on_ice_transport_type_changed;
235 ice_config.ice_check_interval_strong_connectivity =
236 config.ice_check_interval_strong_connectivity;
237 ice_config.ice_check_interval_weak_connectivity =
238 config.ice_check_interval_weak_connectivity;
239 ice_config.ice_check_min_interval = config.ice_check_min_interval;
240 ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout;
241 ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks;
242 ice_config.ice_inactive_timeout = config.ice_inactive_timeout;
243 ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
244 ice_config.network_preference = config.network_preference;
Derek Bailey6c127a12021-04-15 19:42:41245 ice_config.stable_writable_connection_ping_interval =
246 config.stable_writable_connection_ping_interval_ms;
Harald Alvestrand62166932020-10-26 08:30:41247 return ice_config;
248}
249
250// Ensures the configuration doesn't have any parameters with invalid values,
251// or values that conflict with other parameters.
252//
253// Returns RTCError::OK() if there are no issues.
254RTCError ValidateConfiguration(
255 const PeerConnectionInterface::RTCConfiguration& config) {
256 return cricket::P2PTransportChannel::ValidateIceConfig(
257 ParseIceConfig(config));
258}
259
Tommiaea49c92023-10-22 11:00:14260// Checks for valid pool size range and if a previous value has already been
261// set, which is done via SetLocalDescription.
262RTCError ValidateIceCandidatePoolSize(
263 int ice_candidate_pool_size,
264 absl::optional<int> previous_ice_candidate_pool_size) {
265 // Note that this isn't possible through chromium, since it's an unsigned
266 // short in WebIDL.
267 if (ice_candidate_pool_size < 0 ||
268 ice_candidate_pool_size > static_cast<int>(UINT16_MAX)) {
269 return RTCError(RTCErrorType::INVALID_RANGE);
270 }
271
272 // According to JSEP, after setLocalDescription, changing the candidate pool
273 // size is not allowed, and changing the set of ICE servers will not result
274 // in new candidates being gathered.
275 if (previous_ice_candidate_pool_size.has_value() &&
276 ice_candidate_pool_size != previous_ice_candidate_pool_size.value()) {
277 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
278 "Can't change candidate pool size after calling "
279 "SetLocalDescription.");
280 }
281
282 return RTCError::OK();
283}
284
285// The simplest (and most future-compatible) way to tell if a config was
286// modified in an invalid way is to copy each property we do support modifying,
287// then use operator==. There are far more properties we don't support modifying
288// than those we do, and more could be added.
289// This helper function accepts a proposed new `configuration` object, an
290// existing configuration and returns a valid, modified, configuration that's
291// based on the existing configuration, with modified properties copied from
292// `configuration`.
293// If the result of creating a modified configuration doesn't pass the above
294// `operator==` test or a call to `ValidateConfiguration()`, then the function
295// will return an error. Otherwise, the return value will be the new config.
296RTCErrorOr<PeerConnectionInterface::RTCConfiguration> ApplyConfiguration(
297 const PeerConnectionInterface::RTCConfiguration& configuration,
298 const PeerConnectionInterface::RTCConfiguration& existing_configuration) {
299 PeerConnectionInterface::RTCConfiguration modified_config =
300 existing_configuration;
301 modified_config.servers = configuration.servers;
302 modified_config.type = configuration.type;
303 modified_config.ice_candidate_pool_size =
304 configuration.ice_candidate_pool_size;
305 modified_config.prune_turn_ports = configuration.prune_turn_ports;
306 modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy;
307 modified_config.surface_ice_candidates_on_ice_transport_type_changed =
308 configuration.surface_ice_candidates_on_ice_transport_type_changed;
309 modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
310 modified_config.ice_check_interval_strong_connectivity =
311 configuration.ice_check_interval_strong_connectivity;
312 modified_config.ice_check_interval_weak_connectivity =
313 configuration.ice_check_interval_weak_connectivity;
314 modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
315 modified_config.ice_unwritable_min_checks =
316 configuration.ice_unwritable_min_checks;
317 modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
318 modified_config.stun_candidate_keepalive_interval =
319 configuration.stun_candidate_keepalive_interval;
320 modified_config.turn_customizer = configuration.turn_customizer;
321 modified_config.network_preference = configuration.network_preference;
322 modified_config.active_reset_srtp_params =
323 configuration.active_reset_srtp_params;
324 modified_config.turn_logging_id = configuration.turn_logging_id;
Tommiaea49c92023-10-22 11:00:14325 modified_config.stable_writable_connection_ping_interval_ms =
326 configuration.stable_writable_connection_ping_interval_ms;
327 if (configuration != modified_config) {
328 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
329 "Modifying the configuration in an unsupported way.");
330 }
331
332 RTCError err = ValidateConfiguration(modified_config);
333 if (!err.ok()) {
334 return err;
335 }
336
337 return modified_config;
338}
339
Harald Alvestrand62166932020-10-26 08:30:41340bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) {
341 return content->media_description()->rtcp_mux();
342}
343
Tommic3257d02021-02-10 17:40:08344bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration,
345 const PeerConnectionFactoryInterface::Options& options,
346 const PeerConnectionDependencies& dependencies) {
347 if (options.disable_encryption)
348 return false;
349
350 // Enable DTLS by default if we have an identity store or a certificate.
Harald Alvestrand8c371f22024-01-30 07:39:42351 return (dependencies.cert_generator || !configuration.certificates.empty());
Tommic3257d02021-02-10 17:40:08352}
353
Tommiaea49c92023-10-22 11:00:14354// Calls `ParseIceServersOrError` to extract ice server information from the
355// `configuration` and then validates the extracted configuration. For a
356// non-empty list of servers, usage gets recorded via `usage_pattern`.
357RTCError ParseAndValidateIceServersFromConfiguration(
358 const PeerConnectionInterface::RTCConfiguration& configuration,
359 cricket::ServerAddresses& stun_servers,
360 std::vector<cricket::RelayServerConfig>& turn_servers,
361 UsagePattern& usage_pattern) {
362 RTC_DCHECK(stun_servers.empty());
363 RTC_DCHECK(turn_servers.empty());
364 RTCError err = ParseIceServersOrError(configuration.servers, &stun_servers,
365 &turn_servers);
366 if (!err.ok()) {
367 return err;
368 }
369
370 // Restrict number of TURN servers.
371 if (turn_servers.size() > cricket::kMaxTurnServers) {
372 RTC_LOG(LS_WARNING) << "Number of configured TURN servers is "
373 << turn_servers.size()
374 << " which exceeds the maximum allowed number of "
375 << cricket::kMaxTurnServers;
376 turn_servers.resize(cricket::kMaxTurnServers);
377 }
378
379 // Add the turn logging id to all turn servers
380 for (cricket::RelayServerConfig& turn_server : turn_servers) {
381 turn_server.turn_logging_id = configuration.turn_logging_id;
382 }
383
384 // Note if STUN or TURN servers were supplied.
385 if (!stun_servers.empty()) {
386 usage_pattern.NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
387 }
388 if (!turn_servers.empty()) {
389 usage_pattern.NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
390 }
391 return RTCError::OK();
392}
393
Steve Anton75737c02017-11-06 18:37:17394} // namespace
395
deadbeef293e9262017-01-11 20:28:30396bool PeerConnectionInterface::RTCConfiguration::operator==(
397 const PeerConnectionInterface::RTCConfiguration& o) const {
398 // This static_assert prevents us from accidentally breaking operator==.
Steve Anton300bf8e2017-07-14 17:13:10399 // Note: Order matters! Fields must be ordered the same as RTCConfiguration.
deadbeef293e9262017-01-11 20:28:30400 struct stuff_being_tested_for_equality {
Magnus Jedvert3beb2072017-07-14 14:23:56401 IceServers servers;
Steve Anton300bf8e2017-07-14 17:13:10402 IceTransportsType type;
deadbeef293e9262017-01-11 20:28:30403 BundlePolicy bundle_policy;
404 RtcpMuxPolicy rtcp_mux_policy;
Steve Anton300bf8e2017-07-14 17:13:10405 std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
406 int ice_candidate_pool_size;
Steve Anton300bf8e2017-07-14 17:13:10407 bool disable_ipv6_on_wifi;
deadbeefd21eab3e2017-07-26 23:50:11408 int max_ipv6_networks;
Daniel Lazarenko2870b0a2018-01-25 09:30:22409 bool disable_link_local_networks;
Danil Chapovalov66cadcc2018-06-19 14:47:43410 absl::optional<int> screencast_min_bitrate;
deadbeef293e9262017-01-11 20:28:30411 TcpCandidatePolicy tcp_candidate_policy;
412 CandidateNetworkPolicy candidate_network_policy;
413 int audio_jitter_buffer_max_packets;
414 bool audio_jitter_buffer_fast_accelerate;
Jakob Ivarsson10403ae2018-11-27 14:45:20415 int audio_jitter_buffer_min_delay_ms;
deadbeef293e9262017-01-11 20:28:30416 int ice_connection_receiving_timeout;
417 int ice_backup_candidate_pair_ping_interval;
418 ContinualGatheringPolicy continual_gathering_policy;
deadbeef293e9262017-01-11 20:28:30419 bool prioritize_most_likely_ice_candidate_pairs;
420 struct cricket::MediaConfig media_config;
deadbeef293e9262017-01-11 20:28:30421 bool prune_turn_ports;
Honghai Zhangf8998cf2019-10-14 18:27:50422 PortPrunePolicy turn_port_prune_policy;
deadbeef293e9262017-01-11 20:28:30423 bool presume_writable_when_fully_relayed;
424 bool enable_ice_renomination;
425 bool redetermine_role_on_ice_restart;
Qingsi Wang1fe119f2019-05-31 23:55:33426 bool surface_ice_candidates_on_ice_transport_type_changed;
Danil Chapovalov66cadcc2018-06-19 14:47:43427 absl::optional<int> ice_check_interval_strong_connectivity;
428 absl::optional<int> ice_check_interval_weak_connectivity;
429 absl::optional<int> ice_check_min_interval;
430 absl::optional<int> ice_unwritable_timeout;
431 absl::optional<int> ice_unwritable_min_checks;
Jiawei Ou9d4fd5552018-12-07 07:30:17432 absl::optional<int> ice_inactive_timeout;
Danil Chapovalov66cadcc2018-06-19 14:47:43433 absl::optional<int> stun_candidate_keepalive_interval;
Harald Alvestranda6544372023-11-13 09:33:56434 TurnCustomizer* turn_customizer;
Steve Anton79e79602017-11-20 18:25:56435 SdpSemantics sdp_semantics;
Danil Chapovalov66cadcc2018-06-19 14:47:43436 absl::optional<rtc::AdapterType> network_preference;
Zhi Huangb57e1692018-06-12 18:41:11437 bool active_reset_srtp_params;
Benjamin Wright8c27cca2018-10-25 17:16:44438 absl::optional<CryptoOptions> crypto_options;
Johannes Kron89f874e2018-11-12 09:25:48439 bool offer_extmap_allow_mixed;
Jonas Oreland3c028422019-08-22 14:16:35440 std::string turn_logging_id;
Eldar Rello5ab79e62019-10-09 15:29:44441 bool enable_implicit_rollback;
Harald Alvestrand62166932020-10-26 08:30:41442 absl::optional<int> report_usage_pattern_delay_ms;
Derek Bailey6c127a12021-04-15 19:42:41443 absl::optional<int> stable_writable_connection_ping_interval_ms;
Harald Alvestranda6544372023-11-13 09:33:56444 VpnPreference vpn_preference;
Jonas Oreland2ee0e642021-08-25 13:43:02445 std::vector<rtc::NetworkMask> vpn_list;
Niels Möller73d07742021-12-02 12:58:01446 PortAllocatorConfig port_allocator_config;
Henrik Boströmcf2856b2022-11-15 08:23:19447 absl::optional<TimeDelta> pacer_burst_interval;
deadbeef293e9262017-01-11 20:28:30448 };
449 static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
450 "Did you add something to RTCConfiguration and forget to "
451 "update operator==?");
452 return type == o.type && servers == o.servers &&
453 bundle_policy == o.bundle_policy &&
454 rtcp_mux_policy == o.rtcp_mux_policy &&
455 tcp_candidate_policy == o.tcp_candidate_policy &&
456 candidate_network_policy == o.candidate_network_policy &&
457 audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
458 audio_jitter_buffer_fast_accelerate ==
459 o.audio_jitter_buffer_fast_accelerate &&
Jakob Ivarsson10403ae2018-11-27 14:45:20460 audio_jitter_buffer_min_delay_ms ==
461 o.audio_jitter_buffer_min_delay_ms &&
deadbeef293e9262017-01-11 20:28:30462 ice_connection_receiving_timeout ==
463 o.ice_connection_receiving_timeout &&
464 ice_backup_candidate_pair_ping_interval ==
465 o.ice_backup_candidate_pair_ping_interval &&
466 continual_gathering_policy == o.continual_gathering_policy &&
467 certificates == o.certificates &&
468 prioritize_most_likely_ice_candidate_pairs ==
469 o.prioritize_most_likely_ice_candidate_pairs &&
Henrik Boström24e03372022-10-27 11:49:10470 media_config == o.media_config &&
zhihuangb09b3f92017-03-07 22:40:51471 disable_ipv6_on_wifi == o.disable_ipv6_on_wifi &&
deadbeefd21eab3e2017-07-26 23:50:11472 max_ipv6_networks == o.max_ipv6_networks &&
Daniel Lazarenko2870b0a2018-01-25 09:30:22473 disable_link_local_networks == o.disable_link_local_networks &&
deadbeef293e9262017-01-11 20:28:30474 screencast_min_bitrate == o.screencast_min_bitrate &&
deadbeef293e9262017-01-11 20:28:30475 ice_candidate_pool_size == o.ice_candidate_pool_size &&
476 prune_turn_ports == o.prune_turn_ports &&
Honghai Zhangf8998cf2019-10-14 18:27:50477 turn_port_prune_policy == o.turn_port_prune_policy &&
deadbeef293e9262017-01-11 20:28:30478 presume_writable_when_fully_relayed ==
479 o.presume_writable_when_fully_relayed &&
480 enable_ice_renomination == o.enable_ice_renomination &&
skvlad51072462017-02-02 19:50:14481 redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
Qingsi Wang1fe119f2019-05-31 23:55:33482 surface_ice_candidates_on_ice_transport_type_changed ==
483 o.surface_ice_candidates_on_ice_transport_type_changed &&
Qingsi Wange6826d22018-03-08 22:55:14484 ice_check_interval_strong_connectivity ==
485 o.ice_check_interval_strong_connectivity &&
486 ice_check_interval_weak_connectivity ==
487 o.ice_check_interval_weak_connectivity &&
Steve Anton300bf8e2017-07-14 17:13:10488 ice_check_min_interval == o.ice_check_min_interval &&
Qingsi Wang22e623a2018-03-13 17:53:57489 ice_unwritable_timeout == o.ice_unwritable_timeout &&
490 ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
Jiawei Ou9d4fd5552018-12-07 07:30:17491 ice_inactive_timeout == o.ice_inactive_timeout &&
Qingsi Wangdb53f8e2018-02-20 22:45:49492 stun_candidate_keepalive_interval ==
493 o.stun_candidate_keepalive_interval &&
Steve Anton79e79602017-11-20 18:25:56494 turn_customizer == o.turn_customizer &&
Qingsi Wang9a5c6f82018-02-01 18:38:40495 sdp_semantics == o.sdp_semantics &&
Zhi Huangb57e1692018-06-12 18:41:11496 network_preference == o.network_preference &&
Piotr (Peter) Slatalae0c2e972018-10-08 16:43:21497 active_reset_srtp_params == o.active_reset_srtp_params &&
Johannes Kron89f874e2018-11-12 09:25:48498 crypto_options == o.crypto_options &&
Jonas Oreland3c028422019-08-22 14:16:35499 offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
Eldar Rello5ab79e62019-10-09 15:29:44500 turn_logging_id == o.turn_logging_id &&
philipel16cec3b2019-10-25 10:23:02501 enable_implicit_rollback == o.enable_implicit_rollback &&
Derek Bailey6c127a12021-04-15 19:42:41502 report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms &&
503 stable_writable_connection_ping_interval_ms ==
Jonas Orelandc8fa1ee2021-08-25 06:58:04504 o.stable_writable_connection_ping_interval_ms &&
Niels Möller73d07742021-12-02 12:58:01505 vpn_preference == o.vpn_preference && vpn_list == o.vpn_list &&
506 port_allocator_config.min_port == o.port_allocator_config.min_port &&
507 port_allocator_config.max_port == o.port_allocator_config.max_port &&
Henrik Boströmcf2856b2022-11-15 08:23:19508 port_allocator_config.flags == o.port_allocator_config.flags &&
509 pacer_burst_interval == o.pacer_burst_interval;
deadbeef293e9262017-01-11 20:28:30510}
511
512bool PeerConnectionInterface::RTCConfiguration::operator!=(
513 const PeerConnectionInterface::RTCConfiguration& o) const {
514 return !(*this == o);
deadbeef3edec7c2016-12-10 19:44:26515}
516
Harald Alvestranda3dd7722020-11-27 08:05:42517RTCErrorOr<rtc::scoped_refptr<PeerConnection>> PeerConnection::Create(
Danil Chapovalov3bdb49b2023-11-30 07:59:39518 const Environment& env,
Harald Alvestrand62166932020-10-26 08:30:41519 rtc::scoped_refptr<ConnectionContext> context,
Harald Alvestrand4da4a872020-11-04 10:34:21520 const PeerConnectionFactoryInterface::Options& options,
Harald Alvestrand62166932020-10-26 08:30:41521 std::unique_ptr<Call> call,
522 const PeerConnectionInterface::RTCConfiguration& configuration,
523 PeerConnectionDependencies dependencies) {
Henrik Boström62995db2022-01-03 08:58:10524 // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
Henrik Boström6d2fe892022-01-21 08:51:07525 if (configuration.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
526 RTC_LOG(LS_WARNING)
527 << "PeerConnection constructed with legacy SDP semantics!";
528 }
Henrik Boström62995db2022-01-03 08:58:10529
Harald Alvestrand62166932020-10-26 08:30:41530 RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
531 ParseIceConfig(configuration));
532 if (!config_error.ok()) {
Harald Alvestranda3dd7722020-11-27 08:05:42533 RTC_LOG(LS_ERROR) << "Invalid ICE configuration: "
534 << config_error.message();
535 return config_error;
Harald Alvestrand62166932020-10-26 08:30:41536 }
537
538 if (!dependencies.allocator) {
539 RTC_LOG(LS_ERROR)
540 << "PeerConnection initialized without a PortAllocator? "
541 "This shouldn't happen if using PeerConnectionFactory.";
Harald Alvestranda3dd7722020-11-27 08:05:42542 return RTCError(
543 RTCErrorType::INVALID_PARAMETER,
544 "Attempt to create a PeerConnection without a PortAllocatorFactory");
Harald Alvestrand62166932020-10-26 08:30:41545 }
546
547 if (!dependencies.observer) {
548 // TODO(deadbeef): Why do we do this?
549 RTC_LOG(LS_ERROR) << "PeerConnection initialized without a "
550 "PeerConnectionObserver";
Harald Alvestranda3dd7722020-11-27 08:05:42551 return RTCError(RTCErrorType::INVALID_PARAMETER,
552 "Attempt to create a PeerConnection without an observer");
Harald Alvestrand62166932020-10-26 08:30:41553 }
554
555 bool is_unified_plan =
556 configuration.sdp_semantics == SdpSemantics::kUnifiedPlan;
Tommic3257d02021-02-10 17:40:08557 bool dtls_enabled = DtlsEnabled(configuration, options, dependencies);
Harald Alvestrand0ccfbd22021-04-08 07:25:04558
Harald Alvestrand4d25a772023-08-25 11:07:28559 if (!dependencies.async_dns_resolver_factory) {
Harald Alvestrand4d25a772023-08-25 11:07:28560 dependencies.async_dns_resolver_factory =
561 std::make_unique<BasicAsyncDnsResolverFactory>();
Harald Alvestrand0ccfbd22021-04-08 07:25:04562 }
563
Harald Alvestrandfd9a8f82020-10-26 14:17:02564 // The PeerConnection constructor consumes some, but not all, dependencies.
Tommi87f70902021-04-27 12:43:08565 auto pc = rtc::make_ref_counted<PeerConnection>(
Danil Chapovalov3bdb49b2023-11-30 07:59:39566 env, context, options, is_unified_plan, std::move(call), dependencies,
567 dtls_enabled);
Harald Alvestranda3dd7722020-11-27 08:05:42568 RTCError init_error = pc->Initialize(configuration, std::move(dependencies));
569 if (!init_error.ok()) {
570 RTC_LOG(LS_ERROR) << "PeerConnection initialization failed";
571 return init_error;
Harald Alvestrand62166932020-10-26 08:30:41572 }
573 return pc;
574}
575
Harald Alvestrand4da4a872020-11-04 10:34:21576PeerConnection::PeerConnection(
Danil Chapovalov3bdb49b2023-11-30 07:59:39577 const Environment& env,
Harald Alvestrand4da4a872020-11-04 10:34:21578 rtc::scoped_refptr<ConnectionContext> context,
579 const PeerConnectionFactoryInterface::Options& options,
580 bool is_unified_plan,
Harald Alvestrand4da4a872020-11-04 10:34:21581 std::unique_ptr<Call> call,
Tommic3257d02021-02-10 17:40:08582 PeerConnectionDependencies& dependencies,
583 bool dtls_enabled)
Danil Chapovalov3bdb49b2023-11-30 07:59:39584 : env_(env),
585 context_(context),
Harald Alvestrand4da4a872020-11-04 10:34:21586 options_(options),
Harald Alvestrandfd9a8f82020-10-26 14:17:02587 observer_(dependencies.observer),
Harald Alvestrand62166932020-10-26 08:30:41588 is_unified_plan_(is_unified_plan),
Harald Alvestrand0ccfbd22021-04-08 07:25:04589 async_dns_resolver_factory_(
590 std::move(dependencies.async_dns_resolver_factory)),
Harald Alvestrandfd9a8f82020-10-26 14:17:02591 port_allocator_(std::move(dependencies.allocator)),
592 ice_transport_factory_(std::move(dependencies.ice_transport_factory)),
593 tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
Karl Wiberg6cab5c82019-03-26 08:57:01594 call_(std::move(call)),
Tommiaf27d4e2023-10-24 21:49:31595 worker_thread_safety_(PendingTaskSafetyFlag::CreateAttachedToTaskQueue(
596 /*alive=*/call_ != nullptr,
597 worker_thread())),
Henrik Boström79b69802019-07-18 09:16:56598 call_ptr_(call_.get()),
Tomas Gunnarsson97a387d2021-03-29 19:04:29599 // RFC 3264: The numeric value of the session id and version in the
600 // o line MUST be representable with a "64 bit signed integer".
Artem Titov880fa812021-07-30 20:30:23601 // Due to this constraint session id `session_id_` is max limited to
Tomas Gunnarsson97a387d2021-03-29 19:04:29602 // LLONG_MAX.
603 session_id_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
Tommic3257d02021-02-10 17:40:08604 dtls_enabled_(dtls_enabled),
Harald Alvestrand1090e442020-10-05 07:01:09605 data_channel_controller_(this),
Lahiru Ginnaliya Gamathige70f9e242021-01-28 07:32:46606 message_handler_(signaling_thread()),
Danil Chapovalov49c35d32023-11-27 11:55:39607 weak_factory_(this) {
Danil Chapovalov3bdb49b2023-11-30 07:59:39608 // Field trials specific to the peerconnection should be owned by the `env`,
609 RTC_DCHECK(dependencies.trials == nullptr);
Danil Chapovalov49c35d32023-11-27 11:55:39610}
henrike@webrtc.org28e20752013-07-10 00:45:36611
612PeerConnection::~PeerConnection() {
Peter Boström1a9d6152015-12-08 21:15:17613 TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
Steve Anton4171afb2017-11-20 18:20:22614 RTC_DCHECK_RUN_ON(signaling_thread());
615
Harald Alvestrand9cd199d2020-10-27 07:10:43616 if (sdp_handler_) {
617 sdp_handler_->PrepareForShutdown();
618 }
Henrik Boströma3728d32019-10-28 11:09:49619
Tommi94774d42023-04-24 09:31:45620 // In case `Close()` wasn't called, always make sure the controller cancels
621 // potentially pending operations.
622 data_channel_controller_.PrepareForShutdown();
623
Steve Anton8af21862017-12-15 19:20:13624 // Need to stop transceivers before destroying the stats collector because
Henrik Boströmf7859892022-07-04 12:36:37625 // AudioRtpSender has a reference to the LegacyStatsCollector it will update
626 // when stopping.
Harald Alvestrande15fb152020-10-19 13:28:05627 if (rtp_manager()) {
628 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
629 transceiver->StopInternal();
630 }
Steve Anton8af21862017-12-15 19:20:13631 }
Steve Anton4171afb2017-11-20 18:20:22632
Henrik Boströmf7859892022-07-04 12:36:37633 legacy_stats_.reset(nullptr);
hbosb78306a2016-12-19 13:06:57634 if (stats_collector_) {
635 stats_collector_->WaitForPendingRequest();
636 stats_collector_ = nullptr;
637 }
Steve Anton75737c02017-11-06 18:37:17638
Harald Alvestrand9cd199d2020-10-27 07:10:43639 if (sdp_handler_) {
640 // Don't destroy BaseChannels until after stats has been cleaned up so that
641 // the last stats request can still read from the channels.
Tommi29190752023-10-21 14:50:09642 sdp_handler_->DestroyMediaChannels();
Harald Alvestrand9cd199d2020-10-27 07:10:43643 RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
Harald Alvestrand9cd199d2020-10-27 07:10:43644 sdp_handler_->ResetSessionDescFactory();
645 }
Steve Anton75737c02017-11-06 18:37:17646
Tomas Gunnarsson92eebef2021-02-10 12:05:44647 // port_allocator_ and transport_controller_ live on the network thread and
648 // should be destroyed there.
Harald Alvestrandbc32c562022-02-09 12:08:47649 transport_controller_copy_ = nullptr;
Danil Chapovalov9e09a1f2022-09-08 16:38:10650 network_thread()->BlockingCall([this] {
Karl Wibergfb3be392019-03-22 13:13:22651 RTC_DCHECK_RUN_ON(network_thread());
Tommib00d63c2023-04-12 17:49:53652 TeardownDataChannelTransport_n(RTCError::OK());
Tomas Gunnarsson92eebef2021-02-10 12:05:44653 transport_controller_.reset();
Karl Wibergfb3be392019-03-22 13:13:22654 port_allocator_.reset();
Tommic3257d02021-02-10 17:40:08655 if (network_thread_safety_)
Tomas Gunnarsson92eebef2021-02-10 12:05:44656 network_thread_safety_->SetNotAlive();
Karl Wibergfb3be392019-03-22 13:13:22657 });
Tommi29190752023-10-21 14:50:09658 sctp_mid_s_.reset();
659 SetSctpTransportName("");
Tomas Gunnarssond69e0702021-04-07 13:14:43660
Danil Chapovalov49c35d32023-11-27 11:55:39661 // call_ must be destroyed on the worker thread.
Danil Chapovalov9e09a1f2022-09-08 16:38:10662 worker_thread()->BlockingCall([this] {
Karl Wibergb03ab712019-02-14 10:59:57663 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:08664 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 12:18:15665 call_.reset();
eladalon248fd4f2017-09-06 12:18:15666 });
Tommi52719652023-04-04 09:59:55667
668 data_channel_controller_.PrepareForShutdown();
henrike@webrtc.org28e20752013-07-10 00:45:36669}
670
Harald Alvestranda3dd7722020-11-27 08:05:42671RTCError PeerConnection::Initialize(
buildbot@webrtc.org41451d42014-05-03 05:39:45672 const PeerConnectionInterface::RTCConfiguration& configuration,
Benjamin Wrightcab588882018-05-02 22:12:47673 PeerConnectionDependencies dependencies) {
Karl Wiberg744310f2019-02-14 09:18:56674 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:17675 TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
Steve Anton038834f2017-07-14 22:59:59676
Harald Alvestrandb2a74782018-06-28 11:54:07677 cricket::ServerAddresses stun_servers;
678 std::vector<cricket::RelayServerConfig> turn_servers;
Tommiaea49c92023-10-22 11:00:14679 RTCError parse_error = ParseAndValidateIceServersFromConfiguration(
680 configuration, stun_servers, turn_servers, usage_pattern_);
Philipp Hancke633dc2f2022-10-12 08:16:14681 if (!parse_error.ok()) {
682 return parse_error;
Harald Alvestrandb2a74782018-06-28 11:54:07683 }
684
Tommic3257d02021-02-10 17:40:08685 // Network thread initialization.
Jared Siskinbceec842023-04-20 21:10:51686 transport_controller_copy_ = network_thread()->BlockingCall([&] {
687 RTC_DCHECK_RUN_ON(network_thread());
688 network_thread_safety_ = PendingTaskSafetyFlag::Create();
689 InitializePortAllocatorResult pa_result =
690 InitializePortAllocator_n(stun_servers, turn_servers, configuration);
691 // Send information about IPv4/IPv6 status.
692 PeerConnectionAddressFamilyCounter address_family =
693 pa_result.enable_ipv6 ? kPeerConnection_IPv6 : kPeerConnection_IPv4;
694 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", address_family,
695 kPeerConnectionAddressFamilyCounter_Max);
696 return InitializeTransportController_n(configuration, dependencies);
697 });
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:45698
Steve Antonba818672017-11-06 18:21:57699 configuration_ = configuration;
700
Henrik Boströmf7859892022-07-04 12:36:37701 legacy_stats_ = std::make_unique<LegacyStatsCollector>(this);
Harald Alvestrande15fb152020-10-19 13:28:05702 stats_collector_ = RTCStatsCollector::Create(this);
703
Harald Alvestrand66c40362022-01-28 17:41:30704 sdp_handler_ = SdpOfferAnswerHandler::Create(this, configuration,
Niels Möllerafb246b2022-04-20 12:26:50705 dependencies, context_.get());
Harald Alvestrand9cd199d2020-10-27 07:10:43706
Artem Titovc6c02ef2022-05-09 08:30:09707 rtp_manager_ = std::make_unique<RtpTransmissionManager>(
Henrik Boströmf7859892022-07-04 12:36:37708 IsUnifiedPlan(), context_.get(), &usage_pattern_, observer_,
709 legacy_stats_.get(), [this]() {
Artem Titovc6c02ef2022-05-09 08:30:09710 RTC_DCHECK_RUN_ON(signaling_thread());
711 sdp_handler_->UpdateNegotiationNeeded();
712 });
Harald Alvestrande15fb152020-10-19 13:28:05713
Artem Titovc6c02ef2022-05-09 08:30:09714 // Add default audio/video transceivers for Plan B SDP.
715 if (!IsUnifiedPlan()) {
716 rtp_manager()->transceivers()->Add(
717 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Harald Alvestrandc3fa7c32022-05-22 10:57:01718 signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
719 cricket::MEDIA_TYPE_AUDIO, context())));
Artem Titovc6c02ef2022-05-09 08:30:09720 rtp_manager()->transceivers()->Add(
721 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Harald Alvestrandc3fa7c32022-05-22 10:57:01722 signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
723 cricket::MEDIA_TYPE_VIDEO, context())));
Steve Anton4171afb2017-11-20 18:20:22724 }
Harald Alvestrand763f5a92020-10-22 10:39:40725
Harald Alvestrand62166932020-10-26 08:30:41726 int delay_ms = configuration.report_usage_pattern_delay_ms
727 ? *configuration.report_usage_pattern_delay_ms
728 : REPORT_USAGE_PATTERN_DELAY_MS;
Harald Alvestrand1090e442020-10-05 07:01:09729 message_handler_.RequestUsagePatternReport(
730 [this]() {
731 RTC_DCHECK_RUN_ON(signaling_thread());
732 ReportUsagePattern();
733 },
734 delay_ms);
Jonas Orelanda3aa9bd2019-04-17 05:38:40735
Harald Alvestranda3dd7722020-11-27 08:05:42736 return RTCError::OK();
henrike@webrtc.org28e20752013-07-10 00:45:36737}
738
Harald Alvestrandbc32c562022-02-09 12:08:47739JsepTransportController* PeerConnection::InitializeTransportController_n(
Tommic3257d02021-02-10 17:40:08740 const RTCConfiguration& configuration,
741 const PeerConnectionDependencies& dependencies) {
742 JsepTransportController::Config config;
743 config.redetermine_role_on_ice_restart =
744 configuration.redetermine_role_on_ice_restart;
745 config.ssl_max_version = options_.ssl_max_version;
746 config.disable_encryption = options_.disable_encryption;
747 config.bundle_policy = configuration.bundle_policy;
748 config.rtcp_mux_policy = configuration.rtcp_mux_policy;
749 // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove
750 // this stub.
751 config.crypto_options = configuration.crypto_options.has_value()
752 ? *configuration.crypto_options
753 : options_.crypto_options;
754 config.transport_observer = this;
755 config.rtcp_handler = InitializeRtcpCallback();
Per Ke1e94ad2023-03-30 14:53:59756 config.un_demuxable_packet_handler = InitializeUnDemuxablePacketHandler();
Danil Chapovalov3bdb49b2023-11-30 07:59:39757 config.event_log = &env_.event_log();
Tommic3257d02021-02-10 17:40:08758#if defined(ENABLE_EXTERNAL_AUTH)
759 config.enable_external_auth = true;
760#endif
761 config.active_reset_srtp_params = configuration.active_reset_srtp_params;
762
763 // DTLS has to be enabled to use SCTP.
Florent Castelli516e2842021-04-19 13:29:50764 if (dtls_enabled_) {
Tommic3257d02021-02-10 17:40:08765 config.sctp_factory = context_->sctp_transport_factory();
766 }
767
768 config.ice_transport_factory = ice_transport_factory_.get();
769 config.on_dtls_handshake_error_ =
770 [weak_ptr = weak_factory_.GetWeakPtr()](rtc::SSLHandshakeError s) {
771 if (weak_ptr) {
772 weak_ptr->OnTransportControllerDtlsHandshakeError(s);
773 }
774 };
775
Per Ke1e94ad2023-03-30 14:53:59776 transport_controller_.reset(new JsepTransportController(
Victor Boiviecd54fd82024-02-28 11:16:15777 env_, network_thread(), port_allocator_.get(),
Per Ke1e94ad2023-03-30 14:53:59778 async_dns_resolver_factory_.get(), std::move(config)));
Tommic3257d02021-02-10 17:40:08779
780 transport_controller_->SubscribeIceConnectionState(
781 [this](cricket::IceConnectionState s) {
782 RTC_DCHECK_RUN_ON(network_thread());
783 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49784 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08785 RTC_DCHECK_RUN_ON(signaling_thread());
786 OnTransportControllerConnectionState(s);
787 }));
788 });
789 transport_controller_->SubscribeConnectionState(
790 [this](PeerConnectionInterface::PeerConnectionState s) {
791 RTC_DCHECK_RUN_ON(network_thread());
792 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49793 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08794 RTC_DCHECK_RUN_ON(signaling_thread());
795 SetConnectionState(s);
796 }));
797 });
798 transport_controller_->SubscribeStandardizedIceConnectionState(
799 [this](PeerConnectionInterface::IceConnectionState s) {
800 RTC_DCHECK_RUN_ON(network_thread());
801 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49802 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08803 RTC_DCHECK_RUN_ON(signaling_thread());
804 SetStandardizedIceConnectionState(s);
805 }));
806 });
807 transport_controller_->SubscribeIceGatheringState(
808 [this](cricket::IceGatheringState s) {
809 RTC_DCHECK_RUN_ON(network_thread());
810 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49811 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08812 RTC_DCHECK_RUN_ON(signaling_thread());
813 OnTransportControllerGatheringState(s);
814 }));
815 });
816 transport_controller_->SubscribeIceCandidateGathered(
817 [this](const std::string& transport,
818 const std::vector<cricket::Candidate>& candidates) {
819 RTC_DCHECK_RUN_ON(network_thread());
820 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49821 SafeTask(signaling_thread_safety_.flag(),
822 [this, t = transport, c = candidates]() {
823 RTC_DCHECK_RUN_ON(signaling_thread());
824 OnTransportControllerCandidatesGathered(t, c);
825 }));
Tommic3257d02021-02-10 17:40:08826 });
827 transport_controller_->SubscribeIceCandidateError(
828 [this](const cricket::IceCandidateErrorEvent& event) {
829 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalova30439b2022-07-07 08:08:49830 signaling_thread()->PostTask(
831 SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
Tommic3257d02021-02-10 17:40:08832 RTC_DCHECK_RUN_ON(signaling_thread());
833 OnTransportControllerCandidateError(event);
834 }));
835 });
836 transport_controller_->SubscribeIceCandidatesRemoved(
837 [this](const std::vector<cricket::Candidate>& c) {
838 RTC_DCHECK_RUN_ON(network_thread());
839 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49840 SafeTask(signaling_thread_safety_.flag(), [this, c = c]() {
Tommic3257d02021-02-10 17:40:08841 RTC_DCHECK_RUN_ON(signaling_thread());
842 OnTransportControllerCandidatesRemoved(c);
843 }));
844 });
845 transport_controller_->SubscribeIceCandidatePairChanged(
846 [this](const cricket::CandidatePairChangeEvent& event) {
847 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalova30439b2022-07-07 08:08:49848 signaling_thread()->PostTask(
849 SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
Tommic3257d02021-02-10 17:40:08850 RTC_DCHECK_RUN_ON(signaling_thread());
851 OnTransportControllerCandidateChanged(event);
852 }));
853 });
854
855 transport_controller_->SetIceConfig(ParseIceConfig(configuration));
Harald Alvestrandbc32c562022-02-09 12:08:47856 return transport_controller_.get();
Tommic3257d02021-02-10 17:40:08857}
858
Yves Gerey665174f2018-06-19 13:03:05859rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::local_streams() {
Karl Wiberg5966c502019-02-21 22:55:09860 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58861 RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
862 "Plan SdpSemantics. Please use GetSenders "
863 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43864 return sdp_handler_->local_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36865}
866
Yves Gerey665174f2018-06-19 13:03:05867rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
Karl Wiberg5966c502019-02-21 22:55:09868 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58869 RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
870 "Plan SdpSemantics. Please use GetReceivers "
871 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43872 return sdp_handler_->remote_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36873}
874
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29875bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 09:18:56876 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58877 RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
878 "SdpSemantics. Please use AddTrack instead.";
Peter Boström1a9d6152015-12-08 21:15:17879 TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
Harald Alvestrand35ba0c52022-05-05 07:37:41880 if (!ConfiguredForMedia()) {
881 RTC_LOG(LS_ERROR) << "AddStream: Not configured for media";
882 return false;
883 }
Harald Alvestrand9cd199d2020-10-27 07:10:43884 return sdp_handler_->AddStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36885}
886
887void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 09:18:56888 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41889 RTC_DCHECK(ConfiguredForMedia());
Steve Antonfc853712018-03-01 21:48:58890 RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified "
891 "Plan SdpSemantics. Please use RemoveTrack "
892 "instead.";
Peter Boström1a9d6152015-12-08 21:15:17893 TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
Harald Alvestrand9cd199d2020-10-27 07:10:43894 sdp_handler_->RemoveStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36895}
896
Steve Anton2d6c76a2018-01-06 01:10:52897RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
Steve Antonf9381f02017-12-14 18:23:57898 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 19:34:10899 const std::vector<std::string>& stream_ids) {
Jonas Oreland4b2a1062022-10-19 07:24:42900 return AddTrack(std::move(track), stream_ids, nullptr);
901}
902
903RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
904 rtc::scoped_refptr<MediaStreamTrackInterface> track,
905 const std::vector<std::string>& stream_ids,
906 const std::vector<RtpEncodingParameters>& init_send_encodings) {
907 return AddTrack(std::move(track), stream_ids, &init_send_encodings);
908}
909
910RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
911 rtc::scoped_refptr<MediaStreamTrackInterface> track,
912 const std::vector<std::string>& stream_ids,
913 const std::vector<RtpEncodingParameters>* init_send_encodings) {
Karl Wiberg744310f2019-02-14 09:18:56914 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton2d6c76a2018-01-06 01:10:52915 TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
Harald Alvestrand35ba0c52022-05-05 07:37:41916 if (!ConfiguredForMedia()) {
917 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
918 "Not configured for media");
919 }
Steve Antonf9381f02017-12-14 18:23:57920 if (!track) {
921 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Track is null.");
922 }
923 if (!(track->kind() == MediaStreamTrackInterface::kAudioKind ||
924 track->kind() == MediaStreamTrackInterface::kVideoKind)) {
925 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
926 "Track has invalid kind: " + track->kind());
927 }
Steve Antonf9381f02017-12-14 18:23:57928 if (IsClosed()) {
929 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
930 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 23:35:42931 }
Niels Möllerafb246b2022-04-20 12:26:50932 if (rtp_manager()->FindSenderForTrack(track.get())) {
Steve Antonf9381f02017-12-14 18:23:57933 LOG_AND_RETURN_ERROR(
934 RTCErrorType::INVALID_PARAMETER,
935 "Sender already exists for track " + track->id() + ".");
deadbeefe1f9d832016-01-14 23:35:42936 }
Jonas Oreland4b2a1062022-10-19 07:24:42937 auto sender_or_error =
938 rtp_manager()->AddTrack(track, stream_ids, init_send_encodings);
Steve Antonf9381f02017-12-14 18:23:57939 if (sender_or_error.ok()) {
Harald Alvestrand9cd199d2020-10-27 07:10:43940 sdp_handler_->UpdateNegotiationNeeded();
Henrik Boströmf7859892022-07-04 12:36:37941 legacy_stats_->AddTrack(track.get());
Steve Antonf9381f02017-12-14 18:23:57942 }
943 return sender_or_error;
944}
deadbeefe1f9d832016-01-14 23:35:42945
Harald Alvestrand09a0d012022-01-04 19:42:07946RTCError PeerConnection::RemoveTrackOrError(
Steve Antonf9381f02017-12-14 18:23:57947 rtc::scoped_refptr<RtpSenderInterface> sender) {
Karl Wiberg744310f2019-02-14 09:18:56948 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41949 if (!ConfiguredForMedia()) {
950 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
951 "Not configured for media");
952 }
Steve Antonf9381f02017-12-14 18:23:57953 if (!sender) {
954 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Sender is null.");
955 }
deadbeefe1f9d832016-01-14 23:35:42956 if (IsClosed()) {
Steve Antonf9381f02017-12-14 18:23:57957 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
958 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 23:35:42959 }
Steve Antonf9381f02017-12-14 18:23:57960 if (IsUnifiedPlan()) {
961 auto transceiver = FindTransceiverBySender(sender);
962 if (!transceiver || !sender->track()) {
963 return RTCError::OK();
964 }
965 sender->SetTrack(nullptr);
966 if (transceiver->direction() == RtpTransceiverDirection::kSendRecv) {
Steve Anton52d86772018-02-20 23:48:12967 transceiver->internal()->set_direction(
968 RtpTransceiverDirection::kRecvOnly);
Steve Antonf9381f02017-12-14 18:23:57969 } else if (transceiver->direction() == RtpTransceiverDirection::kSendOnly) {
Steve Anton52d86772018-02-20 23:48:12970 transceiver->internal()->set_direction(
971 RtpTransceiverDirection::kInactive);
Steve Antonf9381f02017-12-14 18:23:57972 }
Steve Anton4171afb2017-11-20 18:20:22973 } else {
Steve Antonf9381f02017-12-14 18:23:57974 bool removed;
975 if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
Harald Alvestrande15fb152020-10-19 13:28:05976 removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 12:26:50977 sender.get());
Steve Antonf9381f02017-12-14 18:23:57978 } else {
979 RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
Harald Alvestrande15fb152020-10-19 13:28:05980 removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 12:26:50981 sender.get());
Steve Antonf9381f02017-12-14 18:23:57982 }
983 if (!removed) {
984 LOG_AND_RETURN_ERROR(
985 RTCErrorType::INVALID_PARAMETER,
986 "Couldn't find sender " + sender->id() + " to remove.");
987 }
Steve Anton4171afb2017-11-20 18:20:22988 }
Harald Alvestrand9cd199d2020-10-27 07:10:43989 sdp_handler_->UpdateNegotiationNeeded();
Steve Antonf9381f02017-12-14 18:23:57990 return RTCError::OK();
991}
992
993rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
994PeerConnection::FindTransceiverBySender(
995 rtc::scoped_refptr<RtpSenderInterface> sender) {
Harald Alvestrande15fb152020-10-19 13:28:05996 return rtp_manager()->transceivers()->FindBySender(sender);
deadbeefe1f9d832016-01-14 23:35:42997}
998
Steve Anton9158ef62017-11-27 21:01:52999RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1000PeerConnection::AddTransceiver(
1001 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
Harald Alvestrand35ba0c52022-05-05 07:37:411002 if (!ConfiguredForMedia()) {
1003 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1004 "Not configured for media");
1005 }
1006
Steve Anton9158ef62017-11-27 21:01:521007 return AddTransceiver(track, RtpTransceiverInit());
1008}
1009
1010RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1011PeerConnection::AddTransceiver(
1012 rtc::scoped_refptr<MediaStreamTrackInterface> track,
1013 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 09:18:561014 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411015 if (!ConfiguredForMedia()) {
1016 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1017 "Not configured for media");
1018 }
Steve Antonfc853712018-03-01 21:48:581019 RTC_CHECK(IsUnifiedPlan())
1020 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 21:01:521021 if (!track) {
1022 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "track is null");
1023 }
1024 cricket::MediaType media_type;
1025 if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
1026 media_type = cricket::MEDIA_TYPE_AUDIO;
1027 } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
1028 media_type = cricket::MEDIA_TYPE_VIDEO;
1029 } else {
1030 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1031 "Track kind is not audio or video");
1032 }
1033 return AddTransceiver(media_type, track, init);
1034}
1035
1036RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1037PeerConnection::AddTransceiver(cricket::MediaType media_type) {
1038 return AddTransceiver(media_type, RtpTransceiverInit());
1039}
1040
1041RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1042PeerConnection::AddTransceiver(cricket::MediaType media_type,
1043 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 09:18:561044 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411045 if (!ConfiguredForMedia()) {
1046 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1047 "Not configured for media");
1048 }
Steve Antonfc853712018-03-01 21:48:581049 RTC_CHECK(IsUnifiedPlan())
1050 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 21:01:521051 if (!(media_type == cricket::MEDIA_TYPE_AUDIO ||
1052 media_type == cricket::MEDIA_TYPE_VIDEO)) {
1053 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1054 "media type is not audio or video");
1055 }
1056 return AddTransceiver(media_type, nullptr, init);
1057}
1058
1059RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1060PeerConnection::AddTransceiver(
1061 cricket::MediaType media_type,
1062 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Steve Anton22da89f2018-01-25 21:58:071063 const RtpTransceiverInit& init,
Guido Urdaneta70c2db12019-04-16 10:24:141064 bool update_negotiation_needed) {
Harald Alvestranda474fbf2020-10-01 16:47:231065 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411066 if (!ConfiguredForMedia()) {
1067 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1068 "Not configured for media");
1069 }
Steve Anton9158ef62017-11-27 21:01:521070 RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
1071 media_type == cricket::MEDIA_TYPE_VIDEO));
1072 if (track) {
1073 RTC_DCHECK_EQ(media_type,
1074 (track->kind() == MediaStreamTrackInterface::kAudioKind
1075 ? cricket::MEDIA_TYPE_AUDIO
1076 : cricket::MEDIA_TYPE_VIDEO));
1077 }
1078
Amit Hilbuchaa584152019-02-07 01:09:521079 size_t num_rids = absl::c_count_if(init.send_encodings,
1080 [](const RtpEncodingParameters& encoding) {
1081 return !encoding.rid.empty();
1082 });
1083 if (num_rids > 0 && num_rids != init.send_encodings.size()) {
Amit Hilbuchce470aa2019-02-07 01:09:521084 LOG_AND_RETURN_ERROR(
Amit Hilbuchaa584152019-02-07 01:09:521085 RTCErrorType::INVALID_PARAMETER,
1086 "RIDs must be provided for either all or none of the send encodings.");
Emircan Uysaler78323432019-02-08 20:41:391087 }
1088
Amit Hilbuchf4770402019-04-08 21:11:571089 if (num_rids > 0 && absl::c_any_of(init.send_encodings,
1090 [](const RtpEncodingParameters& encoding) {
1091 return !IsLegalRsidName(encoding.rid);
1092 })) {
1093 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1094 "Invalid RID value provided.");
1095 }
1096
Amit Hilbuchaa584152019-02-07 01:09:521097 if (absl::c_any_of(init.send_encodings,
1098 [](const RtpEncodingParameters& encoding) {
1099 return encoding.ssrc.has_value();
1100 })) {
1101 LOG_AND_RETURN_ERROR(
1102 RTCErrorType::UNSUPPORTED_PARAMETER,
1103 "Attempted to set an unimplemented parameter of RtpParameters.");
Florent Castelli892acf02018-10-01 20:47:201104 }
1105
1106 RtpParameters parameters;
1107 parameters.encodings = init.send_encodings;
Amit Hilbuchaa584152019-02-07 01:09:521108
1109 // Encodings are dropped from the tail if too many are provided.
Florent Castellie1b685a2021-04-30 17:11:371110 size_t max_simulcast_streams =
1111 media_type == cricket::MEDIA_TYPE_VIDEO ? kMaxSimulcastStreams : 1u;
1112 if (parameters.encodings.size() > max_simulcast_streams) {
Amit Hilbuchaa584152019-02-07 01:09:521113 parameters.encodings.erase(
Florent Castellie1b685a2021-04-30 17:11:371114 parameters.encodings.begin() + max_simulcast_streams,
Amit Hilbuchaa584152019-02-07 01:09:521115 parameters.encodings.end());
1116 }
1117
1118 // Single RID should be removed.
1119 if (parameters.encodings.size() == 1 &&
1120 !parameters.encodings[0].rid.empty()) {
1121 RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
1122 parameters.encodings[0].rid.clear();
1123 }
1124
1125 // If RIDs were not provided, they are generated for simulcast scenario.
1126 if (parameters.encodings.size() > 1 && num_rids == 0) {
1127 rtc::UniqueStringGenerator rid_generator;
1128 for (RtpEncodingParameters& encoding : parameters.encodings) {
Harald Alvestrand5ad491e2023-02-10 11:28:041129 encoding.rid = rid_generator.GenerateString();
Amit Hilbuchaa584152019-02-07 01:09:521130 }
1131 }
1132
Florent Castellibd1e5d52023-01-17 17:08:261133 // If no encoding parameters were provided, a default entry is created.
1134 if (parameters.encodings.empty()) {
1135 parameters.encodings.push_back({});
1136 }
1137
Florent Castelli892acf02018-10-01 20:47:201138 if (UnimplementedRtpParameterHasValue(parameters)) {
1139 LOG_AND_RETURN_ERROR(
1140 RTCErrorType::UNSUPPORTED_PARAMETER,
1141 "Attempted to set an unimplemented parameter of RtpParameters.");
1142 }
Steve Anton9158ef62017-11-27 21:01:521143
Florent Castelli725ee242022-10-18 15:05:581144 std::vector<cricket::VideoCodec> codecs;
Florent Castelli43a5dd82023-04-12 10:45:071145 // Gather the current codec capabilities to allow checking scalabilityMode and
1146 // codec selection against supported values.
Florent Castelli725ee242022-10-18 15:05:581147 if (media_type == cricket::MEDIA_TYPE_VIDEO) {
Florent Castelli725ee242022-10-18 15:05:581148 codecs = context_->media_engine()->video().send_codecs(false);
Florent Castelli43a5dd82023-04-12 10:45:071149 } else {
1150 codecs = context_->media_engine()->voice().send_codecs();
Florent Castelli725ee242022-10-18 15:05:581151 }
1152
Florent Castelli43a5dd82023-04-12 10:45:071153 auto result =
1154 cricket::CheckRtpParametersValues(parameters, codecs, absl::nullopt);
Florent Castellic1a0bcb2019-01-29 13:26:481155 if (!result.ok()) {
Florent Castelli43a5dd82023-04-12 10:45:071156 if (result.type() == RTCErrorType::INVALID_MODIFICATION) {
1157 result.set_type(RTCErrorType::UNSUPPORTED_OPERATION);
1158 }
Florent Castellic1a0bcb2019-01-29 13:26:481159 LOG_AND_RETURN_ERROR(result.type(), result.message());
1160 }
1161
Steve Anton3d954a62018-04-02 18:27:231162 RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
1163 << " transceiver in response to a call to AddTransceiver.";
Steve Anton07563732018-06-26 18:13:501164 // Set the sender ID equal to the track ID if the track is specified unless
1165 // that sender ID is already in use.
Harald Alvestrande15fb152020-10-19 13:28:051166 std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
1167 ? track->id()
1168 : rtc::CreateRandomUuid());
1169 auto sender = rtp_manager()->CreateSender(
1170 media_type, sender_id, track, init.stream_ids, parameters.encodings);
1171 auto receiver =
1172 rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
1173 auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
Steve Anton02ee47c2018-01-11 00:26:061174 transceiver->internal()->set_direction(init.direction);
1175
Guido Urdaneta70c2db12019-04-16 10:24:141176 if (update_negotiation_needed) {
Harald Alvestrand9cd199d2020-10-27 07:10:431177 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton22da89f2018-01-25 21:58:071178 }
Steve Antonf9381f02017-12-14 18:23:571179
1180 return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
1181}
1182
Steve Anton52d86772018-02-20 23:48:121183void PeerConnection::OnNegotiationNeeded() {
1184 RTC_DCHECK_RUN_ON(signaling_thread());
1185 RTC_DCHECK(!IsClosed());
Harald Alvestrand9cd199d2020-10-27 07:10:431186 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton52d86772018-02-20 23:48:121187}
1188
deadbeeffac06552015-11-25 19:26:011189rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
deadbeefbd7d8f72015-12-19 00:58:441190 const std::string& kind,
1191 const std::string& stream_id) {
Karl Wiberg5966c502019-02-21 22:55:091192 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411193 if (!ConfiguredForMedia()) {
1194 RTC_LOG(LS_ERROR) << "Not configured for media";
1195 return nullptr;
1196 }
Steve Antonfc853712018-03-01 21:48:581197 RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified "
1198 "Plan SdpSemantics. Please use AddTransceiver "
1199 "instead.";
Peter Boström1a9d6152015-12-08 21:15:171200 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
zhihuang29ff8442016-07-27 18:07:251201 if (IsClosed()) {
1202 return nullptr;
1203 }
Steve Anton4171afb2017-11-20 18:20:221204
Seth Hampson5b4f0752018-04-02 23:31:361205 // Internally we need to have one stream with Plan B semantics, so we
1206 // generate a random stream ID if not specified.
Seth Hampson845e8782018-03-02 19:34:101207 std::vector<std::string> stream_ids;
Seth Hampson5b4f0752018-04-02 23:31:361208 if (stream_id.empty()) {
1209 stream_ids.push_back(rtc::CreateRandomUuid());
1210 RTC_LOG(LS_INFO)
1211 << "No stream_id specified for sender. Generated stream ID: "
1212 << stream_ids[0];
1213 } else {
Seth Hampson845e8782018-03-02 19:34:101214 stream_ids.push_back(stream_id);
Steve Anton02ee47c2018-01-11 00:26:061215 }
1216
Steve Anton4171afb2017-11-20 18:20:221217 // TODO(steveanton): Move construction of the RtpSenders to RtpTransceiver.
deadbeefa601f5c2016-06-06 21:27:391218 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
deadbeeffac06552015-11-25 19:26:011219 if (kind == MediaStreamTrackInterface::kAudioKind) {
Henrik Boströmf7859892022-07-04 12:36:371220 auto audio_sender =
1221 AudioRtpSender::Create(worker_thread(), rtc::CreateRandomUuid(),
1222 legacy_stats_.get(), rtp_manager());
Harald Alvestrandc0d44d92022-12-13 12:57:241223 audio_sender->SetMediaChannel(rtp_manager()->voice_media_send_channel());
deadbeefa601f5c2016-06-06 21:27:391224 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-11 00:26:061225 signaling_thread(), audio_sender);
Harald Alvestrande15fb152020-10-19 13:28:051226 rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 19:26:011227 } else if (kind == MediaStreamTrackInterface::kVideoKind) {
Harald Alvestrande15fb152020-10-19 13:28:051228 auto video_sender = VideoRtpSender::Create(
1229 worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
Harald Alvestrandc0d44d92022-12-13 12:57:241230 video_sender->SetMediaChannel(rtp_manager()->video_media_send_channel());
deadbeefa601f5c2016-06-06 21:27:391231 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-11 00:26:061232 signaling_thread(), video_sender);
Harald Alvestrande15fb152020-10-19 13:28:051233 rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 19:26:011234 } else {
Mirko Bonadei675513b2017-11-09 10:09:251235 RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
Steve Anton4171afb2017-11-20 18:20:221236 return nullptr;
deadbeeffac06552015-11-25 19:26:011237 }
Henrik Andreasssoncc189172019-05-20 09:01:381238 new_sender->internal()->set_stream_ids(stream_ids);
Steve Anton4171afb2017-11-20 18:20:221239
deadbeefe1f9d832016-01-14 23:35:421240 return new_sender;
deadbeeffac06552015-11-25 19:26:011241}
1242
deadbeef70ab1a12015-09-28 23:53:551243std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
1244 const {
Karl Wiberga58e1692019-03-26 12:33:431245 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 21:27:391246 std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
Harald Alvestrand8101e7b2022-05-23 14:57:471247 if (ConfiguredForMedia()) {
1248 for (const auto& sender : rtp_manager()->GetSendersInternal()) {
1249 ret.push_back(sender);
1250 }
deadbeefa601f5c2016-06-06 21:27:391251 }
1252 return ret;
deadbeef70ab1a12015-09-28 23:53:551253}
1254
1255std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
1256PeerConnection::GetReceivers() const {
Karl Wiberga58e1692019-03-26 12:33:431257 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 21:27:391258 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
Harald Alvestrand8101e7b2022-05-23 14:57:471259 if (ConfiguredForMedia()) {
1260 for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
1261 ret.push_back(receiver);
1262 }
deadbeefa601f5c2016-06-06 21:27:391263 }
1264 return ret;
deadbeef70ab1a12015-09-28 23:53:551265}
1266
Steve Anton9158ef62017-11-27 21:01:521267std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
1268PeerConnection::GetTransceivers() const {
Karl Wiberg5966c502019-02-21 22:55:091269 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:581270 RTC_CHECK(IsUnifiedPlan())
1271 << "GetTransceivers is only supported with Unified Plan SdpSemantics.";
Steve Anton9158ef62017-11-27 21:01:521272 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
Harald Alvestrand8101e7b2022-05-23 14:57:471273 if (ConfiguredForMedia()) {
1274 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1275 all_transceivers.push_back(transceiver);
1276 }
Steve Anton9158ef62017-11-27 21:01:521277 }
1278 return all_transceivers;
1279}
1280
henrike@webrtc.org28e20752013-07-10 00:45:361281bool PeerConnection::GetStats(StatsObserver* observer,
wu@webrtc.orgb9a088b2014-02-13 23:18:491282 MediaStreamTrackInterface* track,
1283 StatsOutputLevel level) {
Henrik Boströmf7859892022-07-04 12:36:371284 TRACE_EVENT0("webrtc", "PeerConnection::GetStats (legacy)");
Karl Wiberg6cab5c82019-03-26 08:57:011285 RTC_DCHECK_RUN_ON(signaling_thread());
nisse7ce109a2017-01-31 08:57:561286 if (!observer) {
Henrik Boströmf7859892022-07-04 12:36:371287 RTC_LOG(LS_ERROR) << "Legacy GetStats - observer is NULL.";
henrike@webrtc.org28e20752013-07-10 00:45:361288 return false;
1289 }
1290
Tommife041642021-04-07 08:08:281291 RTC_LOG_THREAD_BLOCK_COUNT();
1292
Henrik Boströmf7859892022-07-04 12:36:371293 legacy_stats_->UpdateStats(level);
Tommi19015512022-02-02 10:49:351294
1295 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(4);
1296
Henrik Boströmf7859892022-07-04 12:36:371297 // The LegacyStatsCollector is used to tell if a track is valid because it may
zhihuange9e94c32016-11-04 18:38:151298 // remember tracks that the PeerConnection previously removed.
Henrik Boströmf7859892022-07-04 12:36:371299 if (track && !legacy_stats_->IsValidTrack(track->id())) {
1300 RTC_LOG(LS_WARNING) << "Legacy GetStats is called with an invalid track: "
Mirko Bonadei675513b2017-11-09 10:09:251301 << track->id();
zhihuange9e94c32016-11-04 18:38:151302 return false;
1303 }
Henrik Boströmf7859892022-07-04 12:36:371304 message_handler_.PostGetStats(observer, legacy_stats_.get(), track);
Tommife041642021-04-07 08:08:281305
henrike@webrtc.org28e20752013-07-10 00:45:361306 return true;
1307}
1308
hbos74e1a4f2016-09-16 06:33:011309void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
Henrik Boström1df1bf82018-03-20 12:24:201310 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011311 RTC_DCHECK_RUN_ON(signaling_thread());
hbos74e1a4f2016-09-16 06:33:011312 RTC_DCHECK(stats_collector_);
Henrik Boström1df1bf82018-03-20 12:24:201313 RTC_DCHECK(callback);
Tommife041642021-04-07 08:08:281314 RTC_LOG_THREAD_BLOCK_COUNT();
Niels Möllere7cc8832022-01-04 14:20:031315 stats_collector_->GetStatsReport(
1316 rtc::scoped_refptr<RTCStatsCollectorCallback>(callback));
Henrik Boström5023ffb2022-07-04 13:47:251317 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
hbos74e1a4f2016-09-16 06:33:011318}
1319
Henrik Boström1df1bf82018-03-20 12:24:201320void PeerConnection::GetStats(
1321 rtc::scoped_refptr<RtpSenderInterface> selector,
1322 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1323 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011324 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 12:24:201325 RTC_DCHECK(callback);
1326 RTC_DCHECK(stats_collector_);
Henrik Boström5023ffb2022-07-04 13:47:251327 RTC_LOG_THREAD_BLOCK_COUNT();
Henrik Boström1df1bf82018-03-20 12:24:201328 rtc::scoped_refptr<RtpSenderInternal> internal_sender;
1329 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:051330 for (const auto& proxy_transceiver :
1331 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 12:24:201332 for (const auto& proxy_sender :
1333 proxy_transceiver->internal()->senders()) {
1334 if (proxy_sender == selector) {
1335 internal_sender = proxy_sender->internal();
1336 break;
1337 }
1338 }
1339 if (internal_sender)
1340 break;
1341 }
1342 }
Artem Titov880fa812021-07-30 20:30:231343 // If there is no `internal_sender` then `selector` is either null or does not
Henrik Boström1df1bf82018-03-20 12:24:201344 // belong to the PeerConnection (in Plan B, senders can be removed from the
1345 // PeerConnection). This means that "all the stats objects representing the
1346 // selector" is an empty set. Invoking GetStatsReport() with a null selector
1347 // produces an empty stats report.
1348 stats_collector_->GetStatsReport(internal_sender, callback);
Henrik Boström5023ffb2022-07-04 13:47:251349 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
Henrik Boström1df1bf82018-03-20 12:24:201350}
1351
1352void PeerConnection::GetStats(
1353 rtc::scoped_refptr<RtpReceiverInterface> selector,
1354 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1355 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011356 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 12:24:201357 RTC_DCHECK(callback);
1358 RTC_DCHECK(stats_collector_);
Henrik Boström5023ffb2022-07-04 13:47:251359 RTC_LOG_THREAD_BLOCK_COUNT();
Henrik Boström1df1bf82018-03-20 12:24:201360 rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
1361 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:051362 for (const auto& proxy_transceiver :
1363 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 12:24:201364 for (const auto& proxy_receiver :
1365 proxy_transceiver->internal()->receivers()) {
1366 if (proxy_receiver == selector) {
1367 internal_receiver = proxy_receiver->internal();
1368 break;
1369 }
1370 }
1371 if (internal_receiver)
1372 break;
1373 }
1374 }
Artem Titov880fa812021-07-30 20:30:231375 // If there is no `internal_receiver` then `selector` is either null or does
Henrik Boström1df1bf82018-03-20 12:24:201376 // not belong to the PeerConnection (in Plan B, receivers can be removed from
1377 // the PeerConnection). This means that "all the stats objects representing
1378 // the selector" is an empty set. Invoking GetStatsReport() with a null
1379 // selector produces an empty stats report.
1380 stats_collector_->GetStatsReport(internal_receiver, callback);
Henrik Boström5023ffb2022-07-04 13:47:251381 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
Henrik Boström1df1bf82018-03-20 12:24:201382}
1383
henrike@webrtc.org28e20752013-07-10 00:45:361384PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071385 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431386 return sdp_handler_->signaling_state();
henrike@webrtc.org28e20752013-07-10 00:45:361387}
1388
henrike@webrtc.org28e20752013-07-10 00:45:361389PeerConnectionInterface::IceConnectionState
1390PeerConnection::ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071391 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:361392 return ice_connection_state_;
1393}
1394
Alex Loiko9289eda2018-11-23 16:18:591395PeerConnectionInterface::IceConnectionState
1396PeerConnection::standardized_ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071397 RTC_DCHECK_RUN_ON(signaling_thread());
Alex Loiko9289eda2018-11-23 16:18:591398 return standardized_ice_connection_state_;
1399}
1400
Jonas Olsson635474e2018-10-18 13:58:171401PeerConnectionInterface::PeerConnectionState
1402PeerConnection::peer_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071403 RTC_DCHECK_RUN_ON(signaling_thread());
Jonas Olsson635474e2018-10-18 13:58:171404 return connection_state_;
1405}
1406
henrike@webrtc.org28e20752013-07-10 00:45:361407PeerConnectionInterface::IceGatheringState
1408PeerConnection::ice_gathering_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071409 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:361410 return ice_gathering_state_;
1411}
1412
Harald Alvestrand61f74d92020-03-02 10:20:001413absl::optional<bool> PeerConnection::can_trickle_ice_candidates() {
1414 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandcdcfab02020-09-28 13:02:071415 const SessionDescriptionInterface* description = current_remote_description();
Harald Alvestrand61f74d92020-03-02 10:20:001416 if (!description) {
Harald Alvestrandcdcfab02020-09-28 13:02:071417 description = pending_remote_description();
Harald Alvestrand61f74d92020-03-02 10:20:001418 }
1419 if (!description) {
1420 return absl::nullopt;
1421 }
1422 // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
1423 if (description->description()->transport_infos().size() < 1) {
1424 return absl::nullopt;
1425 }
1426 return description->description()->transport_infos()[0].description.HasOption(
1427 "trickle");
1428}
1429
Harald Alvestranda9af50f2021-05-21 13:33:511430RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>
1431PeerConnection::CreateDataChannelOrError(const std::string& label,
1432 const DataChannelInit* config) {
Karl Wiberg106d92d2019-02-14 09:17:471433 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171434 TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
zhihuang9763d562016-08-05 18:14:501435
Tommi4f7ade52023-03-29 18:46:591436 if (IsClosed()) {
1437 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1438 "CreateDataChannelOrError: PeerConnection is closed.");
1439 }
1440
Harald Alvestrand5da3eb02023-03-15 20:39:421441 bool first_datachannel = !data_channel_controller_.HasUsedDataChannels();
jiayl@webrtc.org001fd2d2014-05-29 15:31:111442
Tommi335d0842023-03-25 09:56:181443 InternalDataChannelInit internal_config;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:581444 if (config) {
Tommi335d0842023-03-25 09:56:181445 internal_config = InternalDataChannelInit(*config);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:581446 }
Tommi335d0842023-03-25 09:56:181447
1448 internal_config.fallback_ssl_role = sdp_handler_->GuessSslRole();
Tommi4f7ade52023-03-29 18:46:591449 RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>> ret =
Taylor Brandstetter3a034e12020-07-09 22:32:341450 data_channel_controller_.InternalCreateDataChannelWithProxy(
Tommi4f7ade52023-03-29 18:46:591451 label, internal_config);
1452 if (!ret.ok()) {
1453 return ret.MoveError();
deadbeefab9b2d12015-10-14 18:33:111454 }
henrike@webrtc.org28e20752013-07-10 00:45:361455
Tommi4f7ade52023-03-29 18:46:591456 rtc::scoped_refptr<DataChannelInterface> channel = ret.MoveValue();
1457
Philipp Hancke522380f2023-05-09 07:41:031458 // Check the onRenegotiationNeeded event (with plan-b backward compat)
1459 if (configuration_.sdp_semantics == SdpSemantics::kUnifiedPlan ||
1460 (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED &&
1461 first_datachannel)) {
Harald Alvestrand9cd199d2020-10-27 07:10:431462 sdp_handler_->UpdateNegotiationNeeded();
jiayl@webrtc.org001fd2d2014-05-29 15:31:111463 }
Harald Alvestrand8ebba742018-05-31 12:00:341464 NoteUsageEvent(UsageEvent::DATA_ADDED);
Taylor Brandstetter3a034e12020-07-09 22:32:341465 return channel;
henrike@webrtc.org28e20752013-07-10 00:45:361466}
1467
Henrik Boström79b69802019-07-18 09:16:561468void PeerConnection::RestartIce() {
1469 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431470 sdp_handler_->RestartIce();
Henrik Boström79b69802019-07-18 09:16:561471}
1472
henrike@webrtc.org28e20752013-07-10 00:45:361473void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:161474 const RTCOfferAnswerOptions& options) {
Karl Wiberg5966c502019-02-21 22:55:091475 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431476 sdp_handler_->CreateOffer(observer, options);
Henrik Boströma3728d32019-10-28 11:09:491477}
1478
Harald Alvestrandcdcfab02020-09-28 13:02:071479void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
1480 const RTCOfferAnswerOptions& options) {
Henrik Boströma3728d32019-10-28 11:09:491481 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431482 sdp_handler_->CreateAnswer(observer, options);
henrike@webrtc.org28e20752013-07-10 00:45:361483}
1484
henrike@webrtc.org28e20752013-07-10 00:45:361485void PeerConnection::SetLocalDescription(
1486 SetSessionDescriptionObserver* observer,
Steve Anton80dd7b52018-02-17 01:08:421487 SessionDescriptionInterface* desc_ptr) {
Karl Wiberg5966c502019-02-21 22:55:091488 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431489 sdp_handler_->SetLocalDescription(observer, desc_ptr);
Henrik Boström831ae4e2020-07-29 10:04:001490}
1491
1492void PeerConnection::SetLocalDescription(
1493 std::unique_ptr<SessionDescriptionInterface> desc,
1494 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1495 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431496 sdp_handler_->SetLocalDescription(std::move(desc), observer);
Henrik Boströma3728d32019-10-28 11:09:491497}
Steve Anton8a006912017-12-04 23:25:561498
Henrik Boström4e196702019-10-30 09:35:501499void PeerConnection::SetLocalDescription(
1500 SetSessionDescriptionObserver* observer) {
1501 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431502 sdp_handler_->SetLocalDescription(observer);
Henrik Boström831ae4e2020-07-29 10:04:001503}
1504
1505void PeerConnection::SetLocalDescription(
1506 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1507 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431508 sdp_handler_->SetLocalDescription(observer);
Henrik Boström4e196702019-10-30 09:35:501509}
1510
henrike@webrtc.org28e20752013-07-10 00:45:361511void PeerConnection::SetRemoteDescription(
Henrik Boströma4ecf552017-11-23 14:17:071512 SetSessionDescriptionObserver* observer,
Henrik Boströma3728d32019-10-28 11:09:491513 SessionDescriptionInterface* desc_ptr) {
1514 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431515 sdp_handler_->SetRemoteDescription(observer, desc_ptr);
Henrik Boström31638672017-11-23 16:48:321516}
1517
1518void PeerConnection::SetRemoteDescription(
1519 std::unique_ptr<SessionDescriptionInterface> desc,
1520 rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
Karl Wiberg5966c502019-02-21 22:55:091521 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431522 sdp_handler_->SetRemoteDescription(std::move(desc), observer);
Henrik Boströmafa07dd2018-12-20 10:06:021523}
1524
deadbeef46c73892016-11-17 03:42:041525PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
Karl Wiberg5966c502019-02-21 22:55:091526 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeef46c73892016-11-17 03:42:041527 return configuration_;
1528}
1529
Niels Möller2579f0c2019-08-19 07:58:171530RTCError PeerConnection::SetConfiguration(
1531 const RTCConfiguration& configuration) {
Karl Wiberg5966c502019-02-21 22:55:091532 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171533 TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
Steve Antonc79268f2018-04-24 16:54:101534 if (IsClosed()) {
Niels Möller2579f0c2019-08-19 07:58:171535 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1536 "SetConfiguration: PeerConnection is closed.");
Steve Antonc79268f2018-04-24 16:54:101537 }
1538
Tommiaea49c92023-10-22 11:00:141539 const bool has_local_description = local_description() != nullptr;
1540
1541 RTCError validate_error = ValidateIceCandidatePoolSize(
1542 configuration.ice_candidate_pool_size,
1543 has_local_description
1544 ? absl::optional<int>(configuration_.ice_candidate_pool_size)
1545 : absl::nullopt);
1546 if (!validate_error.ok()) {
1547 return validate_error;
buildbot@webrtc.org41451d42014-05-03 05:39:451548 }
Taylor Brandstettera1c30352016-05-13 15:15:111549
Tommiaea49c92023-10-22 11:00:141550 if (has_local_description &&
Benjamin Wright8c27cca2018-10-25 17:16:441551 configuration.crypto_options != configuration_.crypto_options) {
Niels Möller2579f0c2019-08-19 07:58:171552 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1553 "Can't change crypto_options after calling "
1554 "SetLocalDescription.");
Benjamin Wright8c27cca2018-10-25 17:16:441555 }
1556
Tommiaea49c92023-10-22 11:00:141557 // Create a new, configuration object whose Ice config will have been
1558 // validated..
1559 RTCErrorOr<RTCConfiguration> validated_config =
1560 ApplyConfiguration(configuration, configuration_);
1561 if (!validated_config.ok()) {
1562 return validated_config.error();
deadbeef293e9262017-01-11 20:28:301563 }
1564
1565 // Parse ICE servers before hopping to network thread.
1566 cricket::ServerAddresses stun_servers;
1567 std::vector<cricket::RelayServerConfig> turn_servers;
Tommiaea49c92023-10-22 11:00:141568 validate_error = ParseAndValidateIceServersFromConfiguration(
1569 configuration, stun_servers, turn_servers, usage_pattern_);
1570 if (!validate_error.ok()) {
1571 return validate_error;
deadbeef293e9262017-01-11 20:28:301572 }
Philipp Hancke41a83572022-11-28 13:47:451573
Tommiaea49c92023-10-22 11:00:141574 const RTCConfiguration& modified_config = validated_config.value();
Tomas Gunnarsson20f74562021-02-04 09:22:501575 const bool needs_ice_restart =
1576 modified_config.servers != configuration_.servers ||
1577 NeedIceRestart(
1578 configuration_.surface_ice_candidates_on_ice_transport_type_changed,
1579 configuration_.type, modified_config.type) ||
1580 modified_config.GetTurnPortPrunePolicy() !=
1581 configuration_.GetTurnPortPrunePolicy();
1582 cricket::IceConfig ice_config = ParseIceConfig(modified_config);
1583
1584 // Apply part of the configuration on the network thread. In theory this
1585 // shouldn't fail.
Danil Chapovalov9e09a1f2022-09-08 16:38:101586 if (!network_thread()->BlockingCall(
Tomas Gunnarsson20f74562021-02-04 09:22:501587 [this, needs_ice_restart, &ice_config, &stun_servers, &turn_servers,
1588 &modified_config, has_local_description] {
Harald Alvestrandbc32c562022-02-09 12:08:471589 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson20f74562021-02-04 09:22:501590 // As described in JSEP, calling setConfiguration with new ICE
1591 // servers or candidate policy must set a "needs-ice-restart" bit so
1592 // that the next offer triggers an ICE restart which will pick up
1593 // the changes.
1594 if (needs_ice_restart)
1595 transport_controller_->SetNeedsIceRestartFlag();
1596
1597 transport_controller_->SetIceConfig(ice_config);
Tommiaea49c92023-10-22 11:00:141598 transport_controller_->SetActiveResetSrtpParams(
1599 modified_config.active_reset_srtp_params);
Niels Möller4bab23f2021-01-18 08:24:331600 return ReconfigurePortAllocator_n(
1601 stun_servers, turn_servers, modified_config.type,
1602 modified_config.ice_candidate_pool_size,
1603 modified_config.GetTurnPortPrunePolicy(),
1604 modified_config.turn_customizer,
1605 modified_config.stun_candidate_keepalive_interval,
1606 has_local_description);
1607 })) {
Niels Möller2579f0c2019-08-19 07:58:171608 LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
1609 "Failed to apply configuration to PortAllocator.");
deadbeef293e9262017-01-11 20:28:301610 }
Honghai Zhang4cedf2b2016-08-31 15:18:111611
deadbeef293e9262017-01-11 20:28:301612 configuration_ = modified_config;
Niels Möller2579f0c2019-08-19 07:58:171613 return RTCError::OK();
buildbot@webrtc.org41451d42014-05-03 05:39:451614}
1615
henrike@webrtc.org28e20752013-07-10 00:45:361616bool PeerConnection::AddIceCandidate(
1617 const IceCandidateInterface* ice_candidate) {
Karl Wiberg744310f2019-02-14 09:18:561618 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hanckea09b9212022-06-22 05:41:221619 ClearStatsCache();
Harald Alvestrand9cd199d2020-10-27 07:10:431620 return sdp_handler_->AddIceCandidate(ice_candidate);
henrike@webrtc.org28e20752013-07-10 00:45:361621}
1622
Henrik Boströmee6f4f62019-11-06 11:36:121623void PeerConnection::AddIceCandidate(
1624 std::unique_ptr<IceCandidateInterface> candidate,
1625 std::function<void(RTCError)> callback) {
1626 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hanckea09b9212022-06-22 05:41:221627 sdp_handler_->AddIceCandidate(std::move(candidate),
Harald Alvestranda6544372023-11-13 09:33:561628 [this, callback](RTCError result) {
Philipp Hanckea09b9212022-06-22 05:41:221629 ClearStatsCache();
1630 callback(result);
1631 });
Henrik Boströmee6f4f62019-11-06 11:36:121632}
1633
Honghai Zhang7fb69db2016-03-14 18:59:181634bool PeerConnection::RemoveIceCandidates(
1635 const std::vector<cricket::Candidate>& candidates) {
1636 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
Karl Wiberg2cc368f2019-04-02 09:31:561637 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431638 return sdp_handler_->RemoveIceCandidates(candidates);
Honghai Zhang7fb69db2016-03-14 18:59:181639}
1640
Niels Möller0c4f7be2018-05-07 12:01:371641RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
Steve Anton978b8762017-09-29 19:15:021642 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101643 return worker_thread()->BlockingCall([&]() { return SetBitrate(bitrate); });
zstein4b979802017-06-02 21:37:371644 }
Karl Wiberg6cab5c82019-03-26 08:57:011645 RTC_DCHECK_RUN_ON(worker_thread());
zstein4b979802017-06-02 21:37:371646
Niels Möller0c4f7be2018-05-07 12:01:371647 const bool has_min = bitrate.min_bitrate_bps.has_value();
1648 const bool has_start = bitrate.start_bitrate_bps.has_value();
1649 const bool has_max = bitrate.max_bitrate_bps.has_value();
zstein4b979802017-06-02 21:37:371650 if (has_min && *bitrate.min_bitrate_bps < 0) {
1651 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1652 "min_bitrate_bps <= 0");
1653 }
Niels Möller0c4f7be2018-05-07 12:01:371654 if (has_start) {
1655 if (has_min && *bitrate.start_bitrate_bps < *bitrate.min_bitrate_bps) {
zstein4b979802017-06-02 21:37:371656 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 12:01:371657 "start_bitrate_bps < min_bitrate_bps");
1658 } else if (*bitrate.start_bitrate_bps < 0) {
zstein4b979802017-06-02 21:37:371659 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1660 "curent_bitrate_bps < 0");
1661 }
1662 }
1663 if (has_max) {
Yves Gerey665174f2018-06-19 13:03:051664 if (has_start && *bitrate.max_bitrate_bps < *bitrate.start_bitrate_bps) {
zstein4b979802017-06-02 21:37:371665 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 12:01:371666 "max_bitrate_bps < start_bitrate_bps");
zstein4b979802017-06-02 21:37:371667 } else if (has_min && *bitrate.max_bitrate_bps < *bitrate.min_bitrate_bps) {
1668 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1669 "max_bitrate_bps < min_bitrate_bps");
1670 } else if (*bitrate.max_bitrate_bps < 0) {
1671 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1672 "max_bitrate_bps < 0");
1673 }
1674 }
1675
zstein4b979802017-06-02 21:37:371676 RTC_DCHECK(call_.get());
Piotr (Peter) Slatala7fbfaa42019-03-18 17:31:541677 call_->SetClientBitratePreferences(bitrate);
zstein4b979802017-06-02 21:37:371678
1679 return RTCError::OK();
1680}
1681
Per K39ac25d2024-02-07 13:16:201682void PeerConnection::ReconfigureBandwidthEstimation(
1683 const BandwidthEstimationSettings& settings) {
1684 worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, settings]() {
1685 RTC_DCHECK_RUN_ON(worker_thread());
1686 call_->GetTransportControllerSend()->ReconfigureBandwidthEstimation(
1687 settings);
1688 }));
1689}
1690
henrika5f6bf242017-11-01 10:06:561691void PeerConnection::SetAudioPlayout(bool playout) {
1692 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101693 worker_thread()->BlockingCall(
1694 [this, playout] { SetAudioPlayout(playout); });
henrika5f6bf242017-11-01 10:06:561695 return;
1696 }
Harald Alvestrandc3fa7c32022-05-22 10:57:011697 auto audio_state = context_->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 10:06:561698 audio_state->SetPlayout(playout);
1699}
1700
1701void PeerConnection::SetAudioRecording(bool recording) {
1702 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101703 worker_thread()->BlockingCall(
1704 [this, recording] { SetAudioRecording(recording); });
henrika5f6bf242017-11-01 10:06:561705 return;
1706 }
Harald Alvestrandc3fa7c32022-05-22 10:57:011707 auto audio_state = context_->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 10:06:561708 audio_state->SetRecording(recording);
1709}
1710
Henrik Boström4c1e7cc2020-06-11 10:26:531711void PeerConnection::AddAdaptationResource(
1712 rtc::scoped_refptr<Resource> resource) {
1713 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101714 return worker_thread()->BlockingCall(
1715 [this, resource]() { return AddAdaptationResource(resource); });
Henrik Boström4c1e7cc2020-06-11 10:26:531716 }
1717 RTC_DCHECK_RUN_ON(worker_thread());
1718 if (!call_) {
1719 // The PeerConnection has been closed.
1720 return;
1721 }
1722 call_->AddAdaptationResource(resource);
1723}
1724
Harald Alvestrand35ba0c52022-05-05 07:37:411725bool PeerConnection::ConfiguredForMedia() const {
Harald Alvestrandc3fa7c32022-05-22 10:57:011726 return context_->media_engine();
Harald Alvestrand35ba0c52022-05-05 07:37:411727}
1728
Bjorn Tereliusde939432017-11-20 16:38:141729bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
1730 int64_t output_period_ms) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101731 return worker_thread()->BlockingCall(
Danil Chapovalov116ffe72019-09-05 08:21:111732 [this, output = std::move(output), output_period_ms]() mutable {
1733 return StartRtcEventLog_w(std::move(output), output_period_ms);
1734 });
ivoc14d5dbe2016-07-04 14:06:551735}
1736
Niels Möllerf00ca1a2019-05-10 09:33:121737bool PeerConnection::StartRtcEventLog(
1738 std::unique_ptr<RtcEventLogOutput> output) {
Lionel Koenig0606eaf2023-06-27 08:46:191739 int64_t output_period_ms = 5000;
1740 if (trials().IsDisabled("WebRTC-RtcEventLogNewFormat")) {
Harald Alvestranda6544372023-11-13 09:33:561741 output_period_ms = RtcEventLog::kImmediateOutput;
Niels Möller695cf6a2019-05-13 10:27:231742 }
1743 return StartRtcEventLog(std::move(output), output_period_ms);
Niels Möllerf00ca1a2019-05-10 09:33:121744}
1745
ivoc14d5dbe2016-07-04 14:06:551746void PeerConnection::StopRtcEventLog() {
Danil Chapovalov9e09a1f2022-09-08 16:38:101747 worker_thread()->BlockingCall([this] { StopRtcEventLog_w(); });
ivoc14d5dbe2016-07-04 14:06:551748}
1749
Harald Alvestrandad88c882018-11-28 15:47:461750rtc::scoped_refptr<DtlsTransportInterface>
1751PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
Tomas Gunnarsson2aeab5e2021-02-23 20:36:141752 RTC_DCHECK_RUN_ON(network_thread());
Harald Alvestrandad88c882018-11-28 15:47:461753 return transport_controller_->LookupDtlsTransportByMid(mid);
1754}
1755
Harald Alvestrand4a7b3ac2019-01-17 09:39:401756rtc::scoped_refptr<DtlsTransport>
1757PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
Karl Wiberg2cc368f2019-04-02 09:31:561758 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:471759 // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
1760 // This might be done by caching the value on the signaling thread.
Danil Chapovalov9e09a1f2022-09-08 16:38:101761 return network_thread()->BlockingCall([this, mid]() {
1762 RTC_DCHECK_RUN_ON(network_thread());
1763 return transport_controller_->LookupDtlsTransportByMid(mid);
1764 });
Harald Alvestrand4a7b3ac2019-01-17 09:39:401765}
1766
Harald Alvestrandc85328f2019-02-28 06:51:001767rtc::scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport()
1768 const {
Tomas Gunnarsson92eebef2021-02-10 12:05:441769 RTC_DCHECK_RUN_ON(network_thread());
1770 if (!sctp_mid_n_)
Bjorn A Mellembc3eebc2019-09-23 21:53:541771 return nullptr;
Tomas Gunnarsson92eebef2021-02-10 12:05:441772
1773 return transport_controller_->GetSctpTransport(*sctp_mid_n_);
Harald Alvestrandc85328f2019-02-28 06:51:001774}
1775
henrike@webrtc.org28e20752013-07-10 00:45:361776const SessionDescriptionInterface* PeerConnection::local_description() const {
Karl Wiberg739506e2019-04-03 09:37:281777 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431778 return sdp_handler_->local_description();
henrike@webrtc.org28e20752013-07-10 00:45:361779}
1780
1781const SessionDescriptionInterface* PeerConnection::remote_description() const {
Karl Wiberg739506e2019-04-03 09:37:281782 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431783 return sdp_handler_->remote_description();
henrike@webrtc.org28e20752013-07-10 00:45:361784}
1785
deadbeeffe4a8a42016-12-21 01:56:171786const SessionDescriptionInterface* PeerConnection::current_local_description()
1787 const {
Karl Wiberg739506e2019-04-03 09:37:281788 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431789 return sdp_handler_->current_local_description();
deadbeeffe4a8a42016-12-21 01:56:171790}
1791
1792const SessionDescriptionInterface* PeerConnection::current_remote_description()
1793 const {
Karl Wiberg739506e2019-04-03 09:37:281794 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431795 return sdp_handler_->current_remote_description();
deadbeeffe4a8a42016-12-21 01:56:171796}
1797
1798const SessionDescriptionInterface* PeerConnection::pending_local_description()
1799 const {
Karl Wiberg739506e2019-04-03 09:37:281800 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431801 return sdp_handler_->pending_local_description();
deadbeeffe4a8a42016-12-21 01:56:171802}
1803
1804const SessionDescriptionInterface* PeerConnection::pending_remote_description()
1805 const {
Karl Wiberg739506e2019-04-03 09:37:281806 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431807 return sdp_handler_->pending_remote_description();
deadbeeffe4a8a42016-12-21 01:56:171808}
1809
henrike@webrtc.org28e20752013-07-10 00:45:361810void PeerConnection::Close() {
Karl Wiberg744310f2019-02-14 09:18:561811 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171812 TRACE_EVENT0("webrtc", "PeerConnection::Close");
Harald Alvestrandcdcfab02020-09-28 13:02:071813
Tommife041642021-04-07 08:08:281814 RTC_LOG_THREAD_BLOCK_COUNT();
1815
Harald Alvestrandcdcfab02020-09-28 13:02:071816 if (IsClosed()) {
1817 return;
1818 }
henrike@webrtc.org28e20752013-07-10 00:45:361819 // Update stats here so that we have the most recent stats for tracks and
1820 // streams before the channels are closed.
Henrik Boströmf7859892022-07-04 12:36:371821 legacy_stats_->UpdateStats(kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:361822
Harald Alvestrandcdcfab02020-09-28 13:02:071823 ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed;
1824 Observer()->OnIceConnectionChange(ice_connection_state_);
1825 standardized_ice_connection_state_ =
1826 PeerConnectionInterface::IceConnectionState::kIceConnectionClosed;
1827 connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
1828 Observer()->OnConnectionChange(connection_state_);
1829
Harald Alvestrand9cd199d2020-10-27 07:10:431830 sdp_handler_->Close();
Harald Alvestrandcdcfab02020-09-28 13:02:071831
Harald Alvestrand8ebba742018-05-31 12:00:341832 NoteUsageEvent(UsageEvent::CLOSE_CALLED);
Steve Anton3fe1b152017-12-12 18:20:081833
Harald Alvestrand8101e7b2022-05-23 14:57:471834 if (ConfiguredForMedia()) {
1835 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1836 transceiver->internal()->SetPeerConnectionClosed();
1837 if (!transceiver->stopped())
1838 transceiver->StopInternal();
1839 }
Steve Anton8af21862017-12-15 19:20:131840 }
Steve Anton25cfeb92018-04-26 18:44:001841 // Ensure that all asynchronous stats requests are completed before destroying
1842 // the transport controller below.
1843 if (stats_collector_) {
1844 stats_collector_->WaitForPendingRequest();
1845 }
1846
1847 // Don't destroy BaseChannels until after stats has been cleaned up so that
1848 // the last stats request can still read from the channels.
Tommi29190752023-10-21 14:50:091849 // TODO(tommi): The voice/video channels will be partially uninitialized on
1850 // the network thread (see `RtpTransceiver::ClearChannel`), partially on the
1851 // worker thread (see `PushNewMediaChannelAndDeleteChannel`) and then
1852 // eventually freed on the signaling thread.
1853 // It would be good to combine those steps with the teardown steps here.
1854 sdp_handler_->DestroyMediaChannels();
Steve Anton75737c02017-11-06 18:37:171855
Qingsi Wang93a84392018-01-31 01:13:091856 // The event log is used in the transport controller, which must be outlived
1857 // by the former. CreateOffer by the peer connection is implemented
1858 // asynchronously and if the peer connection is closed without resetting the
1859 // WebRTC session description factory, the session description factory would
1860 // call the transport controller.
Harald Alvestrand9cd199d2020-10-27 07:10:431861 sdp_handler_->ResetSessionDescFactory();
Harald Alvestrand8101e7b2022-05-23 14:57:471862 if (ConfiguredForMedia()) {
1863 rtp_manager_->Close();
1864 }
Qingsi Wang93a84392018-01-31 01:13:091865
Danil Chapovalov9e09a1f2022-09-08 16:38:101866 network_thread()->BlockingCall([this] {
Harald Alvestrandbc32c562022-02-09 12:08:471867 RTC_DCHECK_RUN_ON(network_thread());
Tommi29190752023-10-21 14:50:091868 TeardownDataChannelTransport_n({});
Tomas Gunnarsson92eebef2021-02-10 12:05:441869 transport_controller_.reset();
1870 port_allocator_->DiscardCandidatePool();
1871 if (network_thread_safety_) {
1872 network_thread_safety_->SetNotAlive();
Tomas Gunnarsson92eebef2021-02-10 12:05:441873 }
1874 });
nisseeaabdf62017-05-05 09:23:021875
Tommi29190752023-10-21 14:50:091876 sctp_mid_s_.reset();
1877 SetSctpTransportName("");
1878
Danil Chapovalov9e09a1f2022-09-08 16:38:101879 worker_thread()->BlockingCall([this] {
Karl Wibergb03ab712019-02-14 10:59:571880 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:081881 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 12:18:151882 call_.reset();
Danil Chapovalov49c35d32023-11-27 11:55:391883 StopRtcEventLog_w();
eladalon248fd4f2017-09-06 12:18:151884 });
Harald Alvestrand8ebba742018-05-31 12:00:341885 ReportUsagePattern();
Tomas Gunnarsson2efb8a52021-04-01 14:26:571886
1887 // Signal shutdown to the sdp handler. This invalidates weak pointers for
1888 // internal pending callbacks.
1889 sdp_handler_->PrepareForShutdown();
Tommi1f708ef2023-03-31 16:40:501890 data_channel_controller_.PrepareForShutdown();
1891
1892 // The .h file says that observer can be discarded after close() returns.
1893 // Make sure this is true.
1894 observer_ = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:361895}
1896
Steve Antonba818672017-11-06 18:21:571897void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
Harald Alvestrandcdcfab02020-09-28 13:02:071898 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonba818672017-11-06 18:21:571899 if (ice_connection_state_ == new_state) {
1900 return;
1901 }
1902
deadbeefcbecd352015-09-23 18:50:271903 // After transitioning to "closed", ignore any additional states from
Steve Antonba818672017-11-06 18:21:571904 // TransportController (such as "disconnected").
deadbeefab9b2d12015-10-14 18:33:111905 if (IsClosed()) {
deadbeefcbecd352015-09-23 18:50:271906 return;
1907 }
Steve Antonba818672017-11-06 18:21:571908
Mirko Bonadei675513b2017-11-09 10:09:251909 RTC_LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1910 << " => " << new_state;
Steve Antonba818672017-11-06 18:21:571911 RTC_DCHECK(ice_connection_state_ !=
1912 PeerConnectionInterface::kIceConnectionClosed);
1913
henrike@webrtc.org28e20752013-07-10 00:45:361914 ice_connection_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 08:50:161915 Observer()->OnIceConnectionChange(ice_connection_state_);
henrike@webrtc.org28e20752013-07-10 00:45:361916}
1917
Alex Loiko9289eda2018-11-23 16:18:591918void PeerConnection::SetStandardizedIceConnectionState(
1919 PeerConnectionInterface::IceConnectionState new_state) {
Qingsi Wang36e31472019-05-29 18:37:261920 if (standardized_ice_connection_state_ == new_state) {
Alex Loiko9289eda2018-11-23 16:18:591921 return;
Qingsi Wang36e31472019-05-29 18:37:261922 }
1923
1924 if (IsClosed()) {
Alex Loiko9289eda2018-11-23 16:18:591925 return;
Qingsi Wang36e31472019-05-29 18:37:261926 }
1927
1928 RTC_LOG(LS_INFO) << "Changing standardized IceConnectionState "
1929 << standardized_ice_connection_state_ << " => " << new_state;
1930
Alex Loiko9289eda2018-11-23 16:18:591931 standardized_ice_connection_state_ = new_state;
Jonas Olsson12046902018-12-06 10:25:141932 Observer()->OnStandardizedIceConnectionChange(new_state);
Alex Loiko9289eda2018-11-23 16:18:591933}
1934
Jonas Olsson635474e2018-10-18 13:58:171935void PeerConnection::SetConnectionState(
1936 PeerConnectionInterface::PeerConnectionState new_state) {
Jonas Olsson635474e2018-10-18 13:58:171937 if (connection_state_ == new_state)
1938 return;
1939 if (IsClosed())
1940 return;
1941 connection_state_ = new_state;
1942 Observer()->OnConnectionChange(new_state);
Philipp Hanckebb8f32f2021-02-04 20:50:501943
Philipp Hancke9799fe02022-07-06 07:26:411944 // The first connection state change to connected happens once per
1945 // connection which makes it a good point to report metrics.
Philipp Hanckecd0373f2021-02-24 10:04:301946 if (new_state == PeerConnectionState::kConnected && !was_ever_connected_) {
1947 was_ever_connected_ = true;
Philipp Hancke9799fe02022-07-06 07:26:411948 ReportFirstConnectUsageMetrics();
Philipp Hanckebb8f32f2021-02-04 20:50:501949 }
Jonas Olsson635474e2018-10-18 13:58:171950}
1951
Philipp Hancke9799fe02022-07-06 07:26:411952void PeerConnection::ReportFirstConnectUsageMetrics() {
1953 // Record bundle-policy from configuration. Done here from
1954 // connectionStateChange to limit to actually established connections.
1955 BundlePolicyUsage policy = kBundlePolicyUsageMax;
1956 switch (configuration_.bundle_policy) {
1957 case kBundlePolicyBalanced:
1958 policy = kBundlePolicyUsageBalanced;
1959 break;
1960 case kBundlePolicyMaxBundle:
1961 policy = kBundlePolicyUsageMaxBundle;
1962 break;
1963 case kBundlePolicyMaxCompat:
1964 policy = kBundlePolicyUsageMaxCompat;
1965 break;
1966 }
1967 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundlePolicy", policy,
1968 kBundlePolicyUsageMax);
1969
Philipp Hancke9799fe02022-07-06 07:26:411970 // Record whether there was a local or remote provisional answer.
1971 ProvisionalAnswerUsage pranswer = kProvisionalAnswerNotUsed;
1972 if (local_description()->GetType() == SdpType::kPrAnswer) {
1973 pranswer = kProvisionalAnswerLocal;
1974 } else if (remote_description()->GetType() == SdpType::kPrAnswer) {
1975 pranswer = kProvisionalAnswerRemote;
1976 }
1977 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ProvisionalAnswer", pranswer,
1978 kProvisionalAnswerMax);
1979
Philipp Hancke6f22eb52022-07-14 09:38:441980 auto transport_infos = remote_description()->description()->transport_infos();
Philipp Hancke09672472023-11-15 14:23:061981 if (!transport_infos.empty()) {
1982 // Record the number of valid / invalid ice-ufrag. We do allow certain
1983 // non-spec ice-char for backward-compat reasons. At this point we know
1984 // that the ufrag/pwd consists of a valid ice-char or one of the four
1985 // not allowed characters since we have passed the IsIceChar check done
1986 // by the p2p transport description on setRemoteDescription calls.
Philipp Hancke6f22eb52022-07-14 09:38:441987 auto ice_parameters = transport_infos[0].description.GetIceParameters();
1988 auto is_invalid_char = [](char c) {
1989 return c == '-' || c == '=' || c == '#' || c == '_';
1990 };
1991 bool isUsingInvalidIceCharInUfrag =
1992 absl::c_any_of(ice_parameters.ufrag, is_invalid_char);
1993 bool isUsingInvalidIceCharInPwd =
1994 absl::c_any_of(ice_parameters.pwd, is_invalid_char);
1995 RTC_HISTOGRAM_BOOLEAN(
1996 "WebRTC.PeerConnection.ValidIceChars",
1997 !(isUsingInvalidIceCharInUfrag || isUsingInvalidIceCharInPwd));
Philipp Hancke09672472023-11-15 14:23:061998
1999 // Record whether the hash algorithm of the first transport's
2000 // DTLS fingerprint is still using SHA-1.
2001 if (transport_infos[0].description.identity_fingerprint) {
2002 RTC_HISTOGRAM_BOOLEAN(
2003 "WebRTC.PeerConnection.DtlsFingerprintLegacySha1",
2004 absl::EqualsIgnoreCase(
2005 transport_infos[0].description.identity_fingerprint->algorithm,
2006 "sha-1"));
2007 }
Philipp Hancke6f22eb52022-07-14 09:38:442008 }
Philipp Hancke66efab22023-01-25 10:37:452009
2010 // Record RtcpMuxPolicy setting.
2011 RtcpMuxPolicyUsage rtcp_mux_policy = kRtcpMuxPolicyUsageMax;
2012 switch (configuration_.rtcp_mux_policy) {
2013 case kRtcpMuxPolicyNegotiate:
2014 rtcp_mux_policy = kRtcpMuxPolicyUsageNegotiate;
2015 break;
2016 case kRtcpMuxPolicyRequire:
2017 rtcp_mux_policy = kRtcpMuxPolicyUsageRequire;
2018 break;
2019 }
2020 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.RtcpMuxPolicy",
2021 rtcp_mux_policy, kRtcpMuxPolicyUsageMax);
Philipp Hancke9799fe02022-07-06 07:26:412022}
2023
henrike@webrtc.org28e20752013-07-10 00:45:362024void PeerConnection::OnIceGatheringChange(
2025 PeerConnectionInterface::IceGatheringState new_state) {
2026 if (IsClosed()) {
2027 return;
2028 }
2029 ice_gathering_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 08:50:162030 Observer()->OnIceGatheringChange(ice_gathering_state_);
henrike@webrtc.org28e20752013-07-10 00:45:362031}
2032
jbauch81bf7b02017-03-25 15:31:122033void PeerConnection::OnIceCandidate(
2034 std::unique_ptr<IceCandidateInterface> candidate) {
zhihuang29ff8442016-07-27 18:07:252035 if (IsClosed()) {
2036 return;
2037 }
Qingsi Wang1ba5dec2019-08-19 18:57:172038 ReportIceCandidateCollected(candidate->candidate());
Philipp Hancke1fe14f22022-06-17 09:34:312039 ClearStatsCache();
Harald Alvestrand7a1c7f72018-08-01 08:50:162040 Observer()->OnIceCandidate(candidate.get());
henrike@webrtc.org28e20752013-07-10 00:45:362041}
2042
Eldar Rello0095d372019-12-02 20:22:072043void PeerConnection::OnIceCandidateError(const std::string& address,
2044 int port,
Eldar Relloda13ea22019-06-01 09:23:432045 const std::string& url,
2046 int error_code,
2047 const std::string& error_text) {
2048 if (IsClosed()) {
2049 return;
2050 }
Eldar Rello0095d372019-12-02 20:22:072051 Observer()->OnIceCandidateError(address, port, url, error_code, error_text);
Eldar Relloda13ea22019-06-01 09:23:432052}
2053
Honghai Zhang7fb69db2016-03-14 18:59:182054void PeerConnection::OnIceCandidatesRemoved(
2055 const std::vector<cricket::Candidate>& candidates) {
zhihuang29ff8442016-07-27 18:07:252056 if (IsClosed()) {
2057 return;
2058 }
Harald Alvestrand7a1c7f72018-08-01 08:50:162059 Observer()->OnIceCandidatesRemoved(candidates);
Honghai Zhang7fb69db2016-03-14 18:59:182060}
2061
Alex Drake00c7ecf2019-08-06 17:54:472062void PeerConnection::OnSelectedCandidatePairChanged(
2063 const cricket::CandidatePairChangeEvent& event) {
2064 if (IsClosed()) {
2065 return;
2066 }
Qingsi Wang1ba5dec2019-08-19 18:57:172067
Tommi3b2b2af2024-01-17 13:19:412068 if (event.selected_candidate_pair.local_candidate().is_local() &&
2069 event.selected_candidate_pair.remote_candidate().is_local()) {
Qingsi Wangcc46b10c2019-09-12 18:19:012070 NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
2071 }
2072
Alex Drake00c7ecf2019-08-06 17:54:472073 Observer()->OnIceSelectedCandidatePairChanged(event);
2074}
2075
Tommi840cf782023-10-21 14:47:562076bool PeerConnection::CreateDataChannelTransport(absl::string_view mid) {
Harald Alvestrandcdcfab02020-09-28 13:02:072077 RTC_DCHECK_RUN_ON(signaling_thread());
Tommi840cf782023-10-21 14:47:562078 RTC_DCHECK(!sctp_mid().has_value() || mid == sctp_mid().value());
2079 RTC_LOG(LS_INFO) << "Creating data channel, mid=" << mid;
Steve Antonfa2260d2017-12-29 00:38:232080
Tommi840cf782023-10-21 14:47:562081 absl::optional<std::string> transport_name =
2082 network_thread()->BlockingCall([&] {
2083 RTC_DCHECK_RUN_ON(network_thread());
2084 return SetupDataChannelTransport_n(mid);
2085 });
2086 if (!transport_name)
2087 return false;
2088
Tommiaa3c9f22023-04-18 10:19:192089 sctp_mid_s_ = std::string(mid);
Tommi840cf782023-10-21 14:47:562090 SetSctpTransportName(transport_name.value());
2091
2092 return true;
Tomas Gunnarsson92eebef2021-02-10 12:05:442093}
2094
Tommi840cf782023-10-21 14:47:562095void PeerConnection::DestroyDataChannelTransport(RTCError error) {
Tomas Gunnarsson92eebef2021-02-10 12:05:442096 RTC_DCHECK_RUN_ON(signaling_thread());
Tommi840cf782023-10-21 14:47:562097 network_thread()->BlockingCall([&] {
2098 RTC_DCHECK_RUN_ON(network_thread());
2099 TeardownDataChannelTransport_n(error);
2100 });
Tomas Gunnarsson92eebef2021-02-10 12:05:442101 sctp_mid_s_.reset();
Henrik Boström46053e42023-01-20 12:18:532102 SetSctpTransportName("");
Tomas Gunnarsson92eebef2021-02-10 12:05:442103}
2104
Tommid2afbaf2023-03-02 09:51:162105void PeerConnection::OnSctpDataChannelStateChanged(
Tommi56548982023-03-27 16:07:342106 int channel_id,
Tommid2afbaf2023-03-02 09:51:162107 DataChannelInterface::DataState state) {
2108 RTC_DCHECK_RUN_ON(signaling_thread());
2109 if (stats_collector_)
Tommi56548982023-03-27 16:07:342110 stats_collector_->OnSctpDataChannelStateChanged(channel_id, state);
deadbeefab9b2d12015-10-14 18:33:112111}
2112
Karl Wibergfb3be392019-03-22 13:13:222113PeerConnection::InitializePortAllocatorResult
2114PeerConnection::InitializePortAllocator_n(
Harald Alvestrandb2a74782018-06-28 11:54:072115 const cricket::ServerAddresses& stun_servers,
2116 const std::vector<cricket::RelayServerConfig>& turn_servers,
Taylor Brandstettera1c30352016-05-13 15:15:112117 const RTCConfiguration& configuration) {
Karl Wibergfb3be392019-03-22 13:13:222118 RTC_DCHECK_RUN_ON(network_thread());
2119
Taylor Brandstetterf8e65772016-06-28 00:20:152120 port_allocator_->Initialize();
Taylor Brandstettera1c30352016-05-13 15:15:112121 // To handle both internal and externally created port allocator, we will
2122 // enable BUNDLE here.
Karl Wibergfb3be392019-03-22 13:13:222123 int port_allocator_flags = port_allocator_->flags();
2124 port_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
2125 cricket::PORTALLOCATOR_ENABLE_IPV6 |
2126 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI;
Henrik Boströma445e6a2022-12-01 09:25:122127 if (trials().IsDisabled("WebRTC-IPv6Default")) {
Karl Wibergfb3be392019-03-22 13:13:222128 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
Taylor Brandstettera1c30352016-05-13 15:15:112129 }
zhihuangb09b3f92017-03-07 22:40:512130 if (configuration.disable_ipv6_on_wifi) {
Karl Wibergfb3be392019-03-22 13:13:222131 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
Mirko Bonadei675513b2017-11-09 10:09:252132 RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled.";
zhihuangb09b3f92017-03-07 22:40:512133 }
2134
Taylor Brandstettera1c30352016-05-13 15:15:112135 if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
Karl Wibergfb3be392019-03-22 13:13:222136 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
Mirko Bonadei675513b2017-11-09 10:09:252137 RTC_LOG(LS_INFO) << "TCP candidates are disabled.";
Taylor Brandstettera1c30352016-05-13 15:15:112138 }
2139
honghaiz60347052016-06-01 01:29:122140 if (configuration.candidate_network_policy ==
2141 kCandidateNetworkPolicyLowCost) {
Karl Wibergfb3be392019-03-22 13:13:222142 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
Mirko Bonadei675513b2017-11-09 10:09:252143 RTC_LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
honghaiz60347052016-06-01 01:29:122144 }
2145
Daniel Lazarenko2870b0a2018-01-25 09:30:222146 if (configuration.disable_link_local_networks) {
Karl Wibergfb3be392019-03-22 13:13:222147 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS;
Daniel Lazarenko2870b0a2018-01-25 09:30:222148 RTC_LOG(LS_INFO) << "Disable candidates on link-local network interfaces.";
2149 }
2150
Karl Wibergfb3be392019-03-22 13:13:222151 port_allocator_->set_flags(port_allocator_flags);
Taylor Brandstettera1c30352016-05-13 15:15:112152 // No step delay is used while allocating ports.
2153 port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
Qingsi Wangc129c352019-04-18 17:41:582154 port_allocator_->SetCandidateFilter(
Taylor Brandstettera1c30352016-05-13 15:15:112155 ConvertIceTransportTypeToCandidateFilter(configuration.type));
deadbeefd21eab3e2017-07-26 23:50:112156 port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);
Taylor Brandstettera1c30352016-05-13 15:15:112157
Harald Alvestrandb2a74782018-06-28 11:54:072158 auto turn_servers_copy = turn_servers;
Benjamin Wright6f80f092018-08-14 00:06:262159 for (auto& turn_server : turn_servers_copy) {
2160 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
Benjamin Wrightd6f86e82018-05-08 20:12:252161 }
Taylor Brandstettera1c30352016-05-13 15:15:112162 // Call this last since it may create pooled allocator sessions using the
2163 // properties set above.
Qingsi Wangdb53f8e2018-02-20 22:45:492164 port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-14 00:06:262165 stun_servers, std::move(turn_servers_copy),
Honghai Zhangf8998cf2019-10-14 18:27:502166 configuration.ice_candidate_pool_size,
2167 configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer,
Qingsi Wangdb53f8e2018-02-20 22:45:492168 configuration.stun_candidate_keepalive_interval);
Karl Wibergfb3be392019-03-22 13:13:222169
2170 InitializePortAllocatorResult res;
2171 res.enable_ipv6 = port_allocator_flags & cricket::PORTALLOCATOR_ENABLE_IPV6;
2172 return res;
Taylor Brandstettera1c30352016-05-13 15:15:112173}
2174
deadbeef91dd5672016-05-18 23:55:302175bool PeerConnection::ReconfigurePortAllocator_n(
deadbeef293e9262017-01-11 20:28:302176 const cricket::ServerAddresses& stun_servers,
2177 const std::vector<cricket::RelayServerConfig>& turn_servers,
2178 IceTransportsType type,
2179 int candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 18:27:502180 PortPrunePolicy turn_port_prune_policy,
Harald Alvestranda6544372023-11-13 09:33:562181 TurnCustomizer* turn_customizer,
Karl Wiberg739506e2019-04-03 09:37:282182 absl::optional<int> stun_candidate_keepalive_interval,
2183 bool have_local_description) {
Harald Alvestrandf598e492020-11-04 05:54:102184 RTC_DCHECK_RUN_ON(network_thread());
Qingsi Wangc129c352019-04-18 17:41:582185 port_allocator_->SetCandidateFilter(
deadbeef293e9262017-01-11 20:28:302186 ConvertIceTransportTypeToCandidateFilter(type));
Benjamin Wright6f80f092018-08-14 00:06:262187 // Add the custom tls turn servers if they exist.
2188 auto turn_servers_copy = turn_servers;
2189 for (auto& turn_server : turn_servers_copy) {
2190 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
2191 }
Taylor Brandstettera1c30352016-05-13 15:15:112192 // Call this last since it may create pooled allocator sessions using the
2193 // candidate filter set above.
deadbeef6de92f92016-12-13 02:49:322194 return port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-14 00:06:262195 stun_servers, std::move(turn_servers_copy), candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 18:27:502196 turn_port_prune_policy, turn_customizer,
2197 stun_candidate_keepalive_interval);
Taylor Brandstettera1c30352016-05-13 15:15:112198}
2199
Elad Alon99c3fe52017-10-13 14:29:402200bool PeerConnection::StartRtcEventLog_w(
Bjorn Tereliusde939432017-11-20 16:38:142201 std::unique_ptr<RtcEventLogOutput> output,
2202 int64_t output_period_ms) {
Karl Wibergb03ab712019-02-14 10:59:572203 RTC_DCHECK_RUN_ON(worker_thread());
Danil Chapovalov49c35d32023-11-27 11:55:392204 if (!worker_thread_safety_->alive()) {
zhihuang77985012017-02-07 23:45:162205 return false;
2206 }
Danil Chapovalov3bdb49b2023-11-30 07:59:392207 return env_.event_log().StartLogging(std::move(output), output_period_ms);
ivoc14d5dbe2016-07-04 14:06:552208}
2209
2210void PeerConnection::StopRtcEventLog_w() {
Karl Wibergb03ab712019-02-14 10:59:572211 RTC_DCHECK_RUN_ON(worker_thread());
Danil Chapovalov3bdb49b2023-11-30 07:59:392212 env_.event_log().StopLogging();
ivoc14d5dbe2016-07-04 14:06:552213}
nisseeaabdf62017-05-05 09:23:022214
Tommi335d0842023-03-25 09:56:182215absl::optional<rtc::SSLRole> PeerConnection::GetSctpSslRole_n() {
Tommic61eee22023-03-22 07:25:382216 RTC_DCHECK_RUN_ON(network_thread());
Tommi335d0842023-03-25 09:56:182217 return sctp_mid_n_ ? transport_controller_->GetDtlsRole(*sctp_mid_n_)
2218 : absl::nullopt;
Steve Anton75737c02017-11-06 18:37:172219}
2220
2221bool PeerConnection::GetSslRole(const std::string& content_name,
2222 rtc::SSLRole* role) {
Karl Wiberg2cc368f2019-04-02 09:31:562223 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton75737c02017-11-06 18:37:172224 if (!local_description() || !remote_description()) {
Mirko Bonadei675513b2017-11-09 10:09:252225 RTC_LOG(LS_INFO)
2226 << "Local and Remote descriptions must be applied to get the "
Jonas Olsson45cc8902018-02-13 09:37:072227 "SSL Role of the session.";
Steve Anton75737c02017-11-06 18:37:172228 return false;
2229 }
2230
Danil Chapovalov9e09a1f2022-09-08 16:38:102231 auto dtls_role = network_thread()->BlockingCall([this, content_name]() {
2232 RTC_DCHECK_RUN_ON(network_thread());
2233 return transport_controller_->GetDtlsRole(content_name);
2234 });
Zhi Huange830e682018-03-30 17:48:352235 if (dtls_role) {
2236 *role = *dtls_role;
2237 return true;
2238 }
2239 return false;
Steve Anton75737c02017-11-06 18:37:172240}
2241
Steve Anton75737c02017-11-06 18:37:172242bool PeerConnection::GetTransportDescription(
2243 const SessionDescription* description,
2244 const std::string& content_name,
2245 cricket::TransportDescription* tdesc) {
2246 if (!description || !tdesc) {
2247 return false;
2248 }
2249 const TransportInfo* transport_info =
2250 description->GetTransportInfoByName(content_name);
2251 if (!transport_info) {
2252 return false;
2253 }
2254 *tdesc = transport_info->description;
2255 return true;
2256}
2257
Taylor Brandstetter3a034e12020-07-09 22:32:342258std::vector<DataChannelStats> PeerConnection::GetDataChannelStats() const {
Tommif9e13f82023-04-06 19:21:452259 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson2e94de52020-06-16 14:54:102260 return data_channel_controller_.GetDataChannelStats();
2261}
2262
Danil Chapovalov66cadcc2018-06-19 14:47:432263absl::optional<std::string> PeerConnection::sctp_transport_name() const {
Karl Wiberg2cc368f2019-04-02 09:31:562264 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:472265 if (sctp_mid_s_ && transport_controller_copy_)
Tomas Gunnarsson92eebef2021-02-10 12:05:442266 return sctp_transport_name_s_;
Danil Chapovalov66cadcc2018-06-19 14:47:432267 return absl::optional<std::string>();
Zhi Huange830e682018-03-30 17:48:352268}
2269
Henrik Boström46053e42023-01-20 12:18:532270void PeerConnection::SetSctpTransportName(std::string sctp_transport_name) {
2271 RTC_DCHECK_RUN_ON(signaling_thread());
2272 sctp_transport_name_s_ = std::move(sctp_transport_name);
2273 ClearStatsCache();
2274}
2275
Tomas Gunnarssonbfd9ba82021-04-18 09:55:572276absl::optional<std::string> PeerConnection::sctp_mid() const {
2277 RTC_DCHECK_RUN_ON(signaling_thread());
2278 return sctp_mid_s_;
2279}
2280
Qingsi Wang72a43a12018-02-21 00:03:182281cricket::CandidateStatsList PeerConnection::GetPooledCandidateStats() const {
Tomas Gunnarssone1c8a432021-04-08 13:15:282282 RTC_DCHECK_RUN_ON(network_thread());
2283 if (!network_thread_safety_->alive())
2284 return {};
Philipp Hancke6e57ca22022-06-09 13:58:182285 cricket::CandidateStatsList candidate_stats_list;
2286 port_allocator_->GetCandidateStatsFromPooledSessions(&candidate_stats_list);
2287 return candidate_stats_list;
Qingsi Wang72a43a12018-02-21 00:03:182288}
2289
Steve Anton5dfde182018-02-06 18:34:402290std::map<std::string, cricket::TransportStats>
2291PeerConnection::GetTransportStatsByNames(
2292 const std::set<std::string>& transport_names) {
Markus Handell518669d2021-06-07 11:30:462293 TRACE_EVENT0("webrtc", "PeerConnection::GetTransportStatsByNames");
Karl Wiberg2cc368f2019-04-02 09:31:562294 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarssone1c8a432021-04-08 13:15:282295 if (!network_thread_safety_->alive())
2296 return {};
2297
2298 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton5dfde182018-02-06 18:34:402299 std::map<std::string, cricket::TransportStats> transport_stats_by_name;
2300 for (const std::string& transport_name : transport_names) {
2301 cricket::TransportStats transport_stats;
2302 bool success =
2303 transport_controller_->GetStats(transport_name, &transport_stats);
2304 if (success) {
2305 transport_stats_by_name[transport_name] = std::move(transport_stats);
2306 } else {
2307 RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
2308 << transport_name;
2309 }
2310 }
2311 return transport_stats_by_name;
Steve Anton75737c02017-11-06 18:37:172312}
2313
2314bool PeerConnection::GetLocalCertificate(
2315 const std::string& transport_name,
2316 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282317 RTC_DCHECK_RUN_ON(network_thread());
2318 if (!network_thread_safety_->alive() || !certificate) {
Zhi Huange830e682018-03-30 17:48:352319 return false;
2320 }
2321 *certificate = transport_controller_->GetLocalCertificate(transport_name);
2322 return *certificate != nullptr;
Steve Anton75737c02017-11-06 18:37:172323}
2324
Taylor Brandstetterc3928662018-02-23 21:04:512325std::unique_ptr<rtc::SSLCertChain> PeerConnection::GetRemoteSSLCertChain(
Steve Anton75737c02017-11-06 18:37:172326 const std::string& transport_name) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282327 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstetterc3928662018-02-23 21:04:512328 return transport_controller_->GetRemoteSSLCertChain(transport_name);
Steve Anton75737c02017-11-06 18:37:172329}
2330
Steve Anton75737c02017-11-06 18:37:172331bool PeerConnection::IceRestartPending(const std::string& content_name) const {
Karl Wibergf73f7d62019-04-08 13:36:532332 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:432333 return sdp_handler_->IceRestartPending(content_name);
Steve Anton75737c02017-11-06 18:37:172334}
2335
Steve Anton75737c02017-11-06 18:37:172336bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
Danil Chapovalov9e09a1f2022-09-08 16:38:102337 return network_thread()->BlockingCall([this, &content_name] {
Tommic3257d02021-02-10 17:40:082338 RTC_DCHECK_RUN_ON(network_thread());
2339 return transport_controller_->NeedsIceRestart(content_name);
2340 });
Steve Anton75737c02017-11-06 18:37:172341}
2342
Alex Loiko9289eda2018-11-23 16:18:592343void PeerConnection::OnTransportControllerConnectionState(
2344 cricket::IceConnectionState state) {
2345 switch (state) {
2346 case cricket::kIceConnectionConnecting:
2347 // If the current state is Connected or Completed, then there were
2348 // writable channels but now there are not, so the next state must
2349 // be Disconnected.
2350 // kIceConnectionConnecting is currently used as the default,
2351 // un-connected state by the TransportController, so its only use is
2352 // detecting disconnections.
2353 if (ice_connection_state_ ==
2354 PeerConnectionInterface::kIceConnectionConnected ||
2355 ice_connection_state_ ==
2356 PeerConnectionInterface::kIceConnectionCompleted) {
2357 SetIceConnectionState(
2358 PeerConnectionInterface::kIceConnectionDisconnected);
2359 }
2360 break;
2361 case cricket::kIceConnectionFailed:
2362 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
2363 break;
2364 case cricket::kIceConnectionConnected:
2365 RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
2366 "all transports are writable.";
Tommidba22d32023-06-01 14:08:522367 {
2368 std::vector<RtpTransceiverProxyRefPtr> transceivers;
2369 if (ConfiguredForMedia()) {
2370 transceivers = rtp_manager()->transceivers()->List();
2371 }
2372
2373 network_thread()->PostTask(
2374 SafeTask(network_thread_safety_,
2375 [this, transceivers = std::move(transceivers)] {
2376 RTC_DCHECK_RUN_ON(network_thread());
2377 ReportTransportStats(std::move(transceivers));
2378 }));
2379 }
2380
Alex Loiko9289eda2018-11-23 16:18:592381 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2382 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2383 break;
2384 case cricket::kIceConnectionCompleted:
2385 RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
2386 "all transports are complete.";
2387 if (ice_connection_state_ !=
2388 PeerConnectionInterface::kIceConnectionConnected) {
2389 // If jumping directly from "checking" to "connected",
2390 // signal "connected" first.
2391 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2392 }
2393 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
Tomas Gunnarsson2001dc32021-04-06 09:36:002394
Alex Loiko9289eda2018-11-23 16:18:592395 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
Alex Loiko9289eda2018-11-23 16:18:592396 break;
2397 default:
Artem Titovd3251962021-11-15 15:57:072398 RTC_DCHECK_NOTREACHED();
Alex Loiko9289eda2018-11-23 16:18:592399 }
2400}
2401
Steve Anton75737c02017-11-06 18:37:172402void PeerConnection::OnTransportControllerCandidatesGathered(
2403 const std::string& transport_name,
2404 const cricket::Candidates& candidates) {
Tomas Gunnarsson20f74562021-02-04 09:22:502405 // TODO(bugs.webrtc.org/12427): Expect this to come in on the network thread
2406 // (not signaling as it currently does), handle appropriately.
Steve Anton75737c02017-11-06 18:37:172407 int sdp_mline_index;
2408 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
Mirko Bonadei675513b2017-11-09 10:09:252409 RTC_LOG(LS_ERROR)
2410 << "OnTransportControllerCandidatesGathered: content name "
2411 << transport_name << " not found";
Steve Anton75737c02017-11-06 18:37:172412 return;
2413 }
2414
2415 for (cricket::Candidates::const_iterator citer = candidates.begin();
2416 citer != candidates.end(); ++citer) {
2417 // Use transport_name as the candidate media id.
2418 std::unique_ptr<JsepIceCandidate> candidate(
2419 new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
Harald Alvestrand9cd199d2020-10-27 07:10:432420 sdp_handler_->AddLocalIceCandidate(candidate.get());
Steve Anton75737c02017-11-06 18:37:172421 OnIceCandidate(std::move(candidate));
2422 }
2423}
2424
Eldar Relloda13ea22019-06-01 09:23:432425void PeerConnection::OnTransportControllerCandidateError(
2426 const cricket::IceCandidateErrorEvent& event) {
Eldar Rello0095d372019-12-02 20:22:072427 OnIceCandidateError(event.address, event.port, event.url, event.error_code,
Eldar Relloda13ea22019-06-01 09:23:432428 event.error_text);
2429}
2430
Steve Anton75737c02017-11-06 18:37:172431void PeerConnection::OnTransportControllerCandidatesRemoved(
2432 const std::vector<cricket::Candidate>& candidates) {
Steve Anton75737c02017-11-06 18:37:172433 // Sanity check.
2434 for (const cricket::Candidate& candidate : candidates) {
2435 if (candidate.transport_name().empty()) {
Mirko Bonadei675513b2017-11-09 10:09:252436 RTC_LOG(LS_ERROR) << "OnTransportControllerCandidatesRemoved: "
Jonas Olsson45cc8902018-02-13 09:37:072437 "empty content name in candidate "
Mirko Bonadei675513b2017-11-09 10:09:252438 << candidate.ToString();
Steve Anton75737c02017-11-06 18:37:172439 return;
2440 }
2441 }
Harald Alvestrand9cd199d2020-10-27 07:10:432442 sdp_handler_->RemoveLocalIceCandidates(candidates);
Steve Anton75737c02017-11-06 18:37:172443 OnIceCandidatesRemoved(candidates);
2444}
2445
Alex Drake00c7ecf2019-08-06 17:54:472446void PeerConnection::OnTransportControllerCandidateChanged(
2447 const cricket::CandidatePairChangeEvent& event) {
2448 OnSelectedCandidatePairChanged(event);
2449}
2450
Steve Anton75737c02017-11-06 18:37:172451void PeerConnection::OnTransportControllerDtlsHandshakeError(
2452 rtc::SSLHandshakeError error) {
Qingsi Wang7fc821d2018-07-12 19:54:532453 RTC_HISTOGRAM_ENUMERATION(
2454 "WebRTC.PeerConnection.DtlsHandshakeError", static_cast<int>(error),
2455 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
Steve Anton75737c02017-11-06 18:37:172456}
2457
Steve Anton75737c02017-11-06 18:37:172458// Returns the media index for a local ice candidate given the content name.
2459bool PeerConnection::GetLocalCandidateMediaIndex(
2460 const std::string& content_name,
2461 int* sdp_mline_index) {
2462 if (!local_description() || !sdp_mline_index) {
2463 return false;
2464 }
2465
2466 bool content_found = false;
2467 const ContentInfos& contents = local_description()->description()->contents();
2468 for (size_t index = 0; index < contents.size(); ++index) {
2469 if (contents[index].name == content_name) {
2470 *sdp_mline_index = static_cast<int>(index);
2471 content_found = true;
2472 break;
2473 }
2474 }
2475 return content_found;
2476}
2477
Steve Anton75737c02017-11-06 18:37:172478Call::Stats PeerConnection::GetCallStats() {
2479 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:102480 return worker_thread()->BlockingCall([this] { return GetCallStats(); });
Steve Anton75737c02017-11-06 18:37:172481 }
Karl Wiberg6cab5c82019-03-26 08:57:012482 RTC_DCHECK_RUN_ON(worker_thread());
Henrik Boströme88c95e2020-07-08 09:18:502483 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton75737c02017-11-06 18:37:172484 if (call_) {
2485 return call_->GetStats();
2486 } else {
2487 return Call::Stats();
2488 }
2489}
2490
Fredrik Hernqvistefbe7532023-01-13 15:42:362491absl::optional<AudioDeviceModule::Stats> PeerConnection::GetAudioDeviceStats() {
2492 if (context_->media_engine()) {
2493 return context_->media_engine()->voice().GetAudioDeviceStats();
2494 }
2495 return absl::nullopt;
2496}
2497
Tommiaa3c9f22023-04-18 10:19:192498absl::optional<std::string> PeerConnection::SetupDataChannelTransport_n(
2499 absl::string_view mid) {
2500 sctp_mid_n_ = std::string(mid);
Bjorn A Mellembc3eebc2019-09-23 21:53:542501 DataChannelTransportInterface* transport =
Tommiaa3c9f22023-04-18 10:19:192502 transport_controller_->GetDataChannelTransport(*sctp_mid_n_);
Bjorn A Mellembc3eebc2019-09-23 21:53:542503 if (!transport) {
Piotr (Peter) Slatalab1ae10b2019-03-01 19:14:052504 RTC_LOG(LS_ERROR)
Bjorn A Mellemb689af42019-08-21 17:44:592505 << "Data channel transport is not available for data channels, mid="
2506 << mid;
Tommiaa3c9f22023-04-18 10:19:192507 sctp_mid_n_ = absl::nullopt;
2508 return absl::nullopt;
Bjorn Mellem175aa2e2018-11-08 19:23:222509 }
2510
Tommiaa3c9f22023-04-18 10:19:192511 absl::optional<std::string> transport_name;
Tomas Gunnarssone1c8a432021-04-08 13:15:282512 cricket::DtlsTransportInternal* dtls_transport =
Tommiaa3c9f22023-04-18 10:19:192513 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson92eebef2021-02-10 12:05:442514 if (dtls_transport) {
Tommiaa3c9f22023-04-18 10:19:192515 transport_name = dtls_transport->transport_name();
2516 } else {
2517 // Make sure we still set a valid string.
2518 transport_name = std::string("");
Tomas Gunnarsson92eebef2021-02-10 12:05:442519 }
Bjorn A Mellembc3eebc2019-09-23 21:53:542520
Tommiaa3c9f22023-04-18 10:19:192521 data_channel_controller_.SetupDataChannelTransport_n(transport);
2522
2523 return transport_name;
Bjorn Mellem175aa2e2018-11-08 19:23:222524}
2525
Tommib00d63c2023-04-12 17:49:532526void PeerConnection::TeardownDataChannelTransport_n(RTCError error) {
Tomas Gunnarssond69e0702021-04-07 13:14:432527 if (sctp_mid_n_) {
Artem Titov880fa812021-07-30 20:30:232528 // `sctp_mid_` may still be active through an SCTP transport. If not, unset
Tomas Gunnarssond69e0702021-04-07 13:14:432529 // it.
2530 RTC_LOG(LS_INFO) << "Tearing down data channel transport for mid="
2531 << *sctp_mid_n_;
2532 sctp_mid_n_.reset();
2533 }
2534
Tommib00d63c2023-04-12 17:49:532535 data_channel_controller_.TeardownDataChannelTransport_n(error);
Bjorn Mellem175aa2e2018-11-08 19:23:222536}
2537
Steve Anton75737c02017-11-06 18:37:172538// Returns false if bundle is enabled and rtcp_mux is disabled.
Henrik Boströmf8187e02021-04-26 19:04:262539bool PeerConnection::ValidateBundleSettings(
2540 const SessionDescription* desc,
2541 const std::map<std::string, const cricket::ContentGroup*>&
2542 bundle_groups_by_mid) {
2543 if (bundle_groups_by_mid.empty())
Steve Anton75737c02017-11-06 18:37:172544 return true;
2545
Steve Anton75737c02017-11-06 18:37:172546 const cricket::ContentInfos& contents = desc->contents();
2547 for (cricket::ContentInfos::const_iterator citer = contents.begin();
2548 citer != contents.end(); ++citer) {
2549 const cricket::ContentInfo* content = (&*citer);
2550 RTC_DCHECK(content != NULL);
Henrik Boströmf8187e02021-04-26 19:04:262551 auto it = bundle_groups_by_mid.find(content->name);
Philipp Hancke32dae4b2023-05-12 04:53:552552 if (it != bundle_groups_by_mid.end() &&
2553 !(content->rejected || content->bundle_only) &&
Steve Anton5adfafd2017-12-21 00:34:002554 content->type == MediaProtocolType::kRtp) {
Steve Anton75737c02017-11-06 18:37:172555 if (!HasRtcpMuxEnabled(content))
2556 return false;
2557 }
2558 }
2559 // RTCP-MUX is enabled in all the contents.
2560 return true;
2561}
2562
Philipp Hancke54b925c2021-01-28 08:56:392563void PeerConnection::ReportSdpBundleUsage(
2564 const SessionDescriptionInterface& remote_description) {
2565 RTC_DCHECK_RUN_ON(signaling_thread());
2566
2567 bool using_bundle =
2568 remote_description.description()->HasGroup(cricket::GROUP_TYPE_BUNDLE);
2569 int num_audio_mlines = 0;
2570 int num_video_mlines = 0;
2571 int num_data_mlines = 0;
2572 for (const ContentInfo& content :
2573 remote_description.description()->contents()) {
2574 cricket::MediaType media_type = content.media_description()->type();
2575 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2576 num_audio_mlines += 1;
2577 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2578 num_video_mlines += 1;
2579 } else if (media_type == cricket::MEDIA_TYPE_DATA) {
2580 num_data_mlines += 1;
2581 }
2582 }
2583 bool simple = num_audio_mlines <= 1 && num_video_mlines <= 1;
2584 BundleUsage usage = kBundleUsageMax;
2585 if (num_audio_mlines == 0 && num_video_mlines == 0) {
2586 if (num_data_mlines > 0) {
2587 usage = using_bundle ? kBundleUsageBundleDatachannelOnly
2588 : kBundleUsageNoBundleDatachannelOnly;
2589 } else {
2590 usage = kBundleUsageEmpty;
2591 }
Harald Alvestrandfa67aef2021-12-08 14:30:552592 } else if (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
Philipp Hancke54b925c2021-01-28 08:56:392593 // In plan-b, simple/complex usage will not show up in the number of
2594 // m-lines or BUNDLE.
2595 usage = using_bundle ? kBundleUsageBundlePlanB : kBundleUsageNoBundlePlanB;
2596 } else {
2597 if (simple) {
2598 usage =
2599 using_bundle ? kBundleUsageBundleSimple : kBundleUsageNoBundleSimple;
2600 } else {
2601 usage = using_bundle ? kBundleUsageBundleComplex
2602 : kBundleUsageNoBundleComplex;
2603 }
2604 }
2605 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundleUsage", usage,
2606 kBundleUsageMax);
2607}
2608
Qingsi Wang1ba5dec2019-08-19 18:57:172609void PeerConnection::ReportIceCandidateCollected(
2610 const cricket::Candidate& candidate) {
2611 NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
2612 if (candidate.address().IsPrivateIP()) {
2613 NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
2614 }
2615 if (candidate.address().IsUnresolvedIP()) {
2616 NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
2617 }
2618 if (candidate.address().family() == AF_INET6) {
2619 NoteUsageEvent(UsageEvent::IPV6_CANDIDATE_COLLECTED);
2620 }
2621}
2622
Harald Alvestrand8ebba742018-05-31 12:00:342623void PeerConnection::NoteUsageEvent(UsageEvent event) {
2624 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand44d0dff2020-10-09 05:43:532625 usage_pattern_.NoteUsageEvent(event);
Harald Alvestrand8ebba742018-05-31 12:00:342626}
2627
Tomas Gunnarsson8cb97062021-02-08 17:57:042628// Asynchronously adds remote candidates on the network thread.
2629void PeerConnection::AddRemoteCandidate(const std::string& mid,
2630 const cricket::Candidate& candidate) {
2631 RTC_DCHECK_RUN_ON(signaling_thread());
2632
Byoungchan Lee5a925772022-10-18 17:43:182633 if (candidate.network_type() != rtc::ADAPTER_TYPE_UNKNOWN) {
2634 RTC_DLOG(LS_WARNING) << "Using candidate with adapter type set - this "
2635 "should only happen in test";
2636 }
2637
2638 // Clear fields that do not make sense as remote candidates.
2639 cricket::Candidate new_candidate(candidate);
2640 new_candidate.set_network_type(rtc::ADAPTER_TYPE_UNKNOWN);
2641 new_candidate.set_relay_protocol("");
2642 new_candidate.set_underlying_type_for_vpn(rtc::ADAPTER_TYPE_UNKNOWN);
2643
Danil Chapovalova30439b2022-07-07 08:08:492644 network_thread()->PostTask(SafeTask(
Byoungchan Lee5a925772022-10-18 17:43:182645 network_thread_safety_, [this, mid = mid, candidate = new_candidate] {
Tomas Gunnarsson8cb97062021-02-08 17:57:042646 RTC_DCHECK_RUN_ON(network_thread());
2647 std::vector<cricket::Candidate> candidates = {candidate};
2648 RTCError error =
2649 transport_controller_->AddRemoteCandidates(mid, candidates);
2650 if (error.ok()) {
Danil Chapovalova30439b2022-07-07 08:08:492651 signaling_thread()->PostTask(SafeTask(
Tomas Gunnarsson8cb97062021-02-08 17:57:042652 signaling_thread_safety_.flag(),
2653 [this, candidate = std::move(candidate)] {
2654 ReportRemoteIceCandidateAdded(candidate);
2655 // Candidates successfully submitted for checking.
2656 if (ice_connection_state() ==
2657 PeerConnectionInterface::kIceConnectionNew ||
2658 ice_connection_state() ==
2659 PeerConnectionInterface::kIceConnectionDisconnected) {
2660 // If state is New, then the session has just gotten its first
2661 // remote ICE candidates, so go to Checking. If state is
2662 // Disconnected, the session is re-using old candidates or
2663 // receiving additional ones, so go to Checking. If state is
2664 // Connected, stay Connected.
2665 // TODO(bemasc): If state is Connected, and the new candidates
2666 // are for a newly added transport, then the state actually
2667 // _should_ move to checking. Add a way to distinguish that
2668 // case.
2669 SetIceConnectionState(
2670 PeerConnectionInterface::kIceConnectionChecking);
2671 }
2672 // TODO(bemasc): If state is Completed, go back to Connected.
2673 }));
2674 } else {
2675 RTC_LOG(LS_WARNING) << error.message();
2676 }
2677 }));
2678}
2679
Harald Alvestrand8ebba742018-05-31 12:00:342680void PeerConnection::ReportUsagePattern() const {
Harald Alvestrand44d0dff2020-10-09 05:43:532681 usage_pattern_.ReportUsagePattern(observer_);
Harald Alvestrand8ebba742018-05-31 12:00:342682}
2683
Tomas Gunnarsson8cb97062021-02-08 17:57:042684void PeerConnection::ReportRemoteIceCandidateAdded(
2685 const cricket::Candidate& candidate) {
2686 RTC_DCHECK_RUN_ON(signaling_thread());
2687
2688 NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED);
2689
2690 if (candidate.address().IsPrivateIP()) {
2691 NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED);
2692 }
2693 if (candidate.address().IsUnresolvedIP()) {
2694 NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED);
2695 }
2696 if (candidate.address().family() == AF_INET6) {
2697 NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED);
2698 }
2699}
2700
Steve Anton75737c02017-11-06 18:37:172701bool PeerConnection::SrtpRequired() const {
Tomas Gunnarsson3278a712021-03-30 15:23:422702 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand974044e2024-02-08 13:15:512703 return dtls_enabled_;
Steve Anton75737c02017-11-06 18:37:172704}
2705
2706void PeerConnection::OnTransportControllerGatheringState(
2707 cricket::IceGatheringState state) {
2708 RTC_DCHECK(signaling_thread()->IsCurrent());
2709 if (state == cricket::kIceGatheringGathering) {
2710 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
2711 } else if (state == cricket::kIceGatheringComplete) {
2712 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
Harald Alvestrandbedb6052020-08-20 12:50:102713 } else if (state == cricket::kIceGatheringNew) {
2714 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew);
2715 } else {
2716 RTC_LOG(LS_ERROR) << "Unknown state received: " << state;
Artem Titovd3251962021-11-15 15:57:072717 RTC_DCHECK_NOTREACHED();
Steve Anton75737c02017-11-06 18:37:172718 }
2719}
2720
Tomas Gunnarsson2001dc32021-04-06 09:36:002721// Runs on network_thread().
Tommidba22d32023-06-01 14:08:522722void PeerConnection::ReportTransportStats(
2723 std::vector<RtpTransceiverProxyRefPtr> transceivers) {
Markus Handell518669d2021-06-07 11:30:462724 TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
Tommic3257d02021-02-10 17:40:082725 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Antonc7b964c2018-02-01 22:39:452726 std::map<std::string, std::set<cricket::MediaType>>
2727 media_types_by_transport_name;
Tommidba22d32023-06-01 14:08:522728 for (const auto& transceiver : transceivers) {
2729 if (transceiver->internal()->channel()) {
2730 std::string transport_name(
2731 transceiver->internal()->channel()->transport_name());
2732 media_types_by_transport_name[transport_name].insert(
2733 transceiver->media_type());
Steve Antonc7b964c2018-02-01 22:39:452734 }
Steve Anton75737c02017-11-06 18:37:172735 }
Tomas Gunnarsson2001dc32021-04-06 09:36:002736
Tomas Gunnarsson2001dc32021-04-06 09:36:002737 if (sctp_mid_n_) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282738 cricket::DtlsTransportInternal* dtls_transport =
2739 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson2001dc32021-04-06 09:36:002740 if (dtls_transport) {
2741 media_types_by_transport_name[dtls_transport->transport_name()].insert(
2742 cricket::MEDIA_TYPE_DATA);
2743 }
Steve Anton75737c02017-11-06 18:37:172744 }
Zhi Huange830e682018-03-30 17:48:352745
Tomas Gunnarsson2001dc32021-04-06 09:36:002746 for (const auto& entry : media_types_by_transport_name) {
2747 const std::string& transport_name = entry.first;
2748 const std::set<cricket::MediaType> media_types = entry.second;
2749 cricket::TransportStats stats;
2750 if (transport_controller_->GetStats(transport_name, &stats)) {
2751 ReportBestConnectionState(stats);
2752 ReportNegotiatedCiphers(dtls_enabled_, stats, media_types);
2753 }
2754 }
Steve Anton75737c02017-11-06 18:37:172755}
Tomas Gunnarsson2001dc32021-04-06 09:36:002756
Steve Anton75737c02017-11-06 18:37:172757// Walk through the ConnectionInfos to gather best connection usage
2758// for IPv4 and IPv6.
Tommic3257d02021-02-10 17:40:082759// static (no member state required)
Steve Anton75737c02017-11-06 18:37:172760void PeerConnection::ReportBestConnectionState(
2761 const cricket::TransportStats& stats) {
Steve Antonc7b964c2018-02-01 22:39:452762 for (const cricket::TransportChannelStats& channel_stats :
2763 stats.channel_stats) {
2764 for (const cricket::ConnectionInfo& connection_info :
Jonas Oreland149dc722019-08-28 06:10:272765 channel_stats.ice_transport_stats.connection_infos) {
Steve Antonc7b964c2018-02-01 22:39:452766 if (!connection_info.best_connection) {
Steve Anton75737c02017-11-06 18:37:172767 continue;
2768 }
2769
Steve Antonc7b964c2018-02-01 22:39:452770 const cricket::Candidate& local = connection_info.local_candidate;
2771 const cricket::Candidate& remote = connection_info.remote_candidate;
Steve Anton75737c02017-11-06 18:37:172772
2773 // Increment the counter for IceCandidatePairType.
2774 if (local.protocol() == cricket::TCP_PROTOCOL_NAME ||
Tommi3b2b2af2024-01-17 13:19:412775 (local.is_relay() &&
Steve Anton75737c02017-11-06 18:37:172776 local.relay_protocol() == cricket::TCP_PROTOCOL_NAME)) {
Qingsi Wang7fc821d2018-07-12 19:54:532777 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_TCP",
2778 GetIceCandidatePairCounter(local, remote),
2779 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 18:37:172780 } else if (local.protocol() == cricket::UDP_PROTOCOL_NAME) {
Qingsi Wang7fc821d2018-07-12 19:54:532781 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_UDP",
2782 GetIceCandidatePairCounter(local, remote),
2783 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 18:37:172784 } else {
Karl Wibergc95b9392020-11-07 23:49:372785 RTC_CHECK_NOTREACHED();
Steve Anton75737c02017-11-06 18:37:172786 }
Steve Anton75737c02017-11-06 18:37:172787
2788 // Increment the counter for IP type.
2789 if (local.address().family() == AF_INET) {
Qingsi Wang7fc821d2018-07-12 19:54:532790 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2791 kBestConnections_IPv4,
2792 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 18:37:172793 } else if (local.address().family() == AF_INET6) {
Qingsi Wang7fc821d2018-07-12 19:54:532794 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2795 kBestConnections_IPv6,
2796 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 18:37:172797 } else {
Qingsi Wang1dac6d82018-12-12 23:28:472798 RTC_CHECK(!local.address().hostname().empty() &&
2799 local.address().IsUnresolvedIP());
Steve Anton75737c02017-11-06 18:37:172800 }
2801
2802 return;
2803 }
2804 }
2805}
2806
Tommic3257d02021-02-10 17:40:082807// static
Steve Anton75737c02017-11-06 18:37:172808void PeerConnection::ReportNegotiatedCiphers(
Tommic3257d02021-02-10 17:40:082809 bool dtls_enabled,
Steve Antonc7b964c2018-02-01 22:39:452810 const cricket::TransportStats& stats,
2811 const std::set<cricket::MediaType>& media_types) {
Tommic3257d02021-02-10 17:40:082812 if (!dtls_enabled || stats.channel_stats.empty()) {
Steve Anton75737c02017-11-06 18:37:172813 return;
2814 }
2815
2816 int srtp_crypto_suite = stats.channel_stats[0].srtp_crypto_suite;
2817 int ssl_cipher_suite = stats.channel_stats[0].ssl_cipher_suite;
Mirko Bonadei7750d802021-07-26 15:27:422818 if (srtp_crypto_suite == rtc::kSrtpInvalidCryptoSuite &&
2819 ssl_cipher_suite == rtc::kTlsNullWithNullNull) {
Steve Anton75737c02017-11-06 18:37:172820 return;
2821 }
2822
Mirko Bonadei7750d802021-07-26 15:27:422823 if (ssl_cipher_suite != rtc::kTlsNullWithNullNull) {
Qingsi Wang7fc821d2018-07-12 19:54:532824 for (cricket::MediaType media_type : media_types) {
2825 switch (media_type) {
2826 case cricket::MEDIA_TYPE_AUDIO:
2827 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2828 "WebRTC.PeerConnection.SslCipherSuite.Audio", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422829 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532830 break;
2831 case cricket::MEDIA_TYPE_VIDEO:
2832 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2833 "WebRTC.PeerConnection.SslCipherSuite.Video", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422834 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532835 break;
2836 case cricket::MEDIA_TYPE_DATA:
2837 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2838 "WebRTC.PeerConnection.SslCipherSuite.Data", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422839 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532840 break;
2841 default:
Artem Titovd3251962021-11-15 15:57:072842 RTC_DCHECK_NOTREACHED();
Qingsi Wang7fc821d2018-07-12 19:54:532843 continue;
2844 }
Steve Antonc7b964c2018-02-01 22:39:452845 }
Steve Anton75737c02017-11-06 18:37:172846 }
Philipp Hancke36e4dd22023-09-28 09:02:212847
2848 uint16_t ssl_peer_signature_algorithm =
2849 stats.channel_stats[0].ssl_peer_signature_algorithm;
2850 if (ssl_peer_signature_algorithm != rtc::kSslSignatureAlgorithmUnknown) {
2851 for (cricket::MediaType media_type : media_types) {
2852 switch (media_type) {
2853 case cricket::MEDIA_TYPE_AUDIO:
2854 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2855 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Audio",
2856 ssl_peer_signature_algorithm,
2857 rtc::kSslSignatureAlgorithmMaxValue);
2858 break;
2859 case cricket::MEDIA_TYPE_VIDEO:
2860 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2861 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Video",
2862 ssl_peer_signature_algorithm,
2863 rtc::kSslSignatureAlgorithmMaxValue);
2864 break;
2865 case cricket::MEDIA_TYPE_DATA:
2866 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2867 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Data",
2868 ssl_peer_signature_algorithm,
2869 rtc::kSslSignatureAlgorithmMaxValue);
2870 break;
2871 default:
2872 RTC_DCHECK_NOTREACHED();
2873 continue;
2874 }
2875 }
2876 }
Steve Anton75737c02017-11-06 18:37:172877}
2878
Taylor Brandstettercbaa2542018-04-16 23:42:142879bool PeerConnection::OnTransportChanged(
Zhi Huange830e682018-03-30 17:48:352880 const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 23:42:142881 RtpTransportInternal* rtp_transport,
Harald Alvestrandc85328f2019-02-28 06:51:002882 rtc::scoped_refptr<DtlsTransport> dtls_transport,
Bjorn A Mellembc3eebc2019-09-23 21:53:542883 DataChannelTransportInterface* data_channel_transport) {
Karl Wibergac025892019-03-26 12:08:372884 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstettercbaa2542018-04-16 23:42:142885 bool ret = true;
Harald Alvestrand8101e7b2022-05-23 14:57:472886 if (ConfiguredForMedia()) {
2887 for (const auto& transceiver :
2888 rtp_manager()->transceivers()->UnsafeList()) {
2889 cricket::ChannelInterface* channel = transceiver->internal()->channel();
2890 if (channel && channel->mid() == mid) {
2891 ret = channel->SetRtpTransport(rtp_transport);
2892 }
Harald Alvestrand19ebabc2022-04-28 13:31:172893 }
Zhi Huange830e682018-03-30 17:48:352894 }
Tomas Gunnarsson92eebef2021-02-10 12:05:442895
Harald Alvestrand7a829a82020-02-12 06:38:212896 if (mid == sctp_mid_n_) {
Harald Alvestrand00cf34c2019-12-02 08:56:022897 data_channel_controller_.OnTransportChanged(data_channel_transport);
Tomas Gunnarsson92eebef2021-02-10 12:05:442898 if (dtls_transport) {
Danil Chapovalova30439b2022-07-07 08:08:492899 signaling_thread()->PostTask(SafeTask(
Tomas Gunnarsson92eebef2021-02-10 12:05:442900 signaling_thread_safety_.flag(),
Tomas Gunnarsson94f01942022-01-03 14:59:122901 [this,
2902 name = std::string(dtls_transport->internal()->transport_name())] {
Tomas Gunnarsson92eebef2021-02-10 12:05:442903 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström46053e42023-01-20 12:18:532904 SetSctpTransportName(std::move(name));
Tomas Gunnarsson92eebef2021-02-10 12:05:442905 }));
2906 }
Bjorn A Mellemb689af42019-08-21 17:44:592907 }
Tomas Gunnarsson92eebef2021-02-10 12:05:442908
Taylor Brandstettercbaa2542018-04-16 23:42:142909 return ret;
Steve Anton75737c02017-11-06 18:37:172910}
2911
Harald Alvestrand7a1c7f72018-08-01 08:50:162912PeerConnectionObserver* PeerConnection::Observer() const {
Harald Alvestrand05e4d082019-12-03 13:04:212913 RTC_DCHECK_RUN_ON(signaling_thread());
2914 RTC_DCHECK(observer_);
Harald Alvestrand7a1c7f72018-08-01 08:50:162915 return observer_;
2916}
2917
Tomas Gunnarsson92eebef2021-02-10 12:05:442918void PeerConnection::StartSctpTransport(int local_port,
2919 int remote_port,
2920 int max_message_size) {
2921 RTC_DCHECK_RUN_ON(signaling_thread());
2922 if (!sctp_mid_s_)
2923 return;
2924
Danil Chapovalova30439b2022-07-07 08:08:492925 network_thread()->PostTask(SafeTask(
Tomas Gunnarsson92eebef2021-02-10 12:05:442926 network_thread_safety_,
2927 [this, mid = *sctp_mid_s_, local_port, remote_port, max_message_size] {
2928 rtc::scoped_refptr<SctpTransport> sctp_transport =
Harald Alvestrandbc32c562022-02-09 12:08:472929 transport_controller_n()->GetSctpTransport(mid);
Tomas Gunnarsson92eebef2021-02-10 12:05:442930 if (sctp_transport)
2931 sctp_transport->Start(local_port, remote_port, max_message_size);
2932 }));
2933}
2934
Benjamin Wright8c27cca2018-10-25 17:16:442935CryptoOptions PeerConnection::GetCryptoOptions() {
Harald Alvestrandc06e3742020-10-01 10:23:332936 RTC_DCHECK_RUN_ON(signaling_thread());
Benjamin Wright8c27cca2018-10-25 17:16:442937 // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions
2938 // after it has been removed.
2939 return configuration_.crypto_options.has_value()
2940 ? *configuration_.crypto_options
Harald Alvestrand4da4a872020-11-04 10:34:212941 : options_.crypto_options;
Benjamin Wright8c27cca2018-10-25 17:16:442942}
2943
Harald Alvestrand89061872018-01-02 13:08:342944void PeerConnection::ClearStatsCache() {
Karl Wiberg6cab5c82019-03-26 08:57:012945 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hancke7baa63f2022-09-01 13:39:502946 if (legacy_stats_) {
2947 legacy_stats_->InvalidateCache();
2948 }
Harald Alvestrand89061872018-01-02 13:08:342949 if (stats_collector_) {
2950 stats_collector_->ClearCachedStatsReport();
2951 }
2952}
2953
Henrik Boströme574a312020-08-25 08:20:112954bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
2955 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:432956 return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
Eldar Rello5ab79e62019-10-09 15:29:442957}
2958
Harald Alvestrand1090e442020-10-05 07:01:092959void PeerConnection::RequestUsagePatternReportForTesting() {
Harald Alvestrand00c62ed2021-10-20 08:52:122960 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand1090e442020-10-05 07:01:092961 message_handler_.RequestUsagePatternReport(
2962 [this]() {
2963 RTC_DCHECK_RUN_ON(signaling_thread());
2964 ReportUsagePattern();
2965 },
2966 /* delay_ms= */ 0);
2967}
2968
Tomas Gunnarsson1e40a0c2020-09-28 08:39:312969std::function<void(const rtc::CopyOnWriteBuffer& packet,
2970 int64_t packet_time_us)>
2971PeerConnection::InitializeRtcpCallback() {
Tommic3257d02021-02-10 17:40:082972 RTC_DCHECK_RUN_ON(network_thread());
Per Kcf439a02023-01-05 13:01:392973 return [this](const rtc::CopyOnWriteBuffer& packet,
2974 int64_t /*packet_time_us*/) {
2975 worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, packet]() {
2976 call_ptr_->Receiver()->DeliverRtcpPacket(packet);
2977 }));
Tomas Gunnarsson1e40a0c2020-09-28 08:39:312978 };
2979}
Harald Alvestrandcdcfab02020-09-28 13:02:072980
Per Ke1e94ad2023-03-30 14:53:592981std::function<void(const RtpPacketReceived& parsed_packet)>
2982PeerConnection::InitializeUnDemuxablePacketHandler() {
2983 RTC_DCHECK_RUN_ON(network_thread());
2984 return [this](const RtpPacketReceived& parsed_packet) {
2985 worker_thread()->PostTask(
2986 SafeTask(worker_thread_safety_, [this, parsed_packet]() {
2987 // Deliver the packet anyway to Call to allow Call to do BWE.
2988 // Even if there is no media receiver, the packet has still
2989 // been received on the network and has been correcly parsed.
2990 call_ptr_->Receiver()->DeliverRtpPacket(
2991 MediaType::ANY, parsed_packet,
2992 /*undemuxable_packet_handler=*/
2993 [](const RtpPacketReceived& packet) { return false; });
2994 }));
2995 };
2996}
2997
henrike@webrtc.org28e20752013-07-10 00:45:362998} // namespace webrtc