1 /*
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * 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.
9 */
10
11 #include "pc/peer_connection.h"
12
13 #include <limits.h>
14 #include <stddef.h>
15 #include <algorithm>
16 #include <memory>
17 #include <set>
18 #include <utility>
19
20 #include "absl/algorithm/container.h"
21 #include "absl/strings/match.h"
22 #include "api/jsep_ice_candidate.h"
23 #include "api/rtp_parameters.h"
24 #include "api/rtp_transceiver_direction.h"
25 #include "api/task_queue/queued_task.h"
26 #include "api/transport/webrtc_key_value_config.h"
27 #include "api/uma_metrics.h"
28 #include "api/video/video_codec_constants.h"
29 #include "call/audio_state.h"
30 #include "call/packet_receiver.h"
31 #include "media/base/media_channel.h"
32 #include "media/base/media_config.h"
33 #include "media/base/rid_description.h"
34 #include "media/base/stream_params.h"
35 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
36 #include "p2p/base/connection.h"
37 #include "p2p/base/connection_info.h"
38 #include "p2p/base/dtls_transport_internal.h"
39 #include "p2p/base/p2p_constants.h"
40 #include "p2p/base/p2p_transport_channel.h"
41 #include "p2p/base/transport_info.h"
42 #include "pc/ice_server_parsing.h"
43 #include "pc/rtp_receiver.h"
44 #include "pc/rtp_sender.h"
45 #include "pc/sctp_transport.h"
46 #include "pc/simulcast_description.h"
47 #include "pc/webrtc_session_description_factory.h"
48 #include "rtc_base/bind.h"
49 #include "rtc_base/helpers.h"
50 #include "rtc_base/ip_address.h"
51 #include "rtc_base/location.h"
52 #include "rtc_base/logging.h"
53 #include "rtc_base/net_helper.h"
54 #include "rtc_base/network_constants.h"
55 #include "rtc_base/callback_list.h"
56 #include "rtc_base/socket_address.h"
57 #include "rtc_base/string_encode.h"
58 #include "rtc_base/task_utils/to_queued_task.h"
59 #include "rtc_base/trace_event.h"
60 #include "rtc_base/unique_id_generator.h"
61 #include "system_wrappers/include/metrics.h"
62
63 using cricket::ContentInfo;
64 using cricket::ContentInfos;
65 using cricket::MediaContentDescription;
66 using cricket::MediaProtocolType;
67 using cricket::RidDescription;
68 using cricket::RidDirection;
69 using cricket::SessionDescription;
70 using cricket::SimulcastDescription;
71 using cricket::SimulcastLayer;
72 using cricket::SimulcastLayerList;
73 using cricket::StreamParams;
74 using cricket::TransportInfo;
75
76 using cricket::LOCAL_PORT_TYPE;
77 using cricket::PRFLX_PORT_TYPE;
78 using cricket::RELAY_PORT_TYPE;
79 using cricket::STUN_PORT_TYPE;
80
81 namespace webrtc {
82
83 namespace {
84
85 // UMA metric names.
86 const char kSimulcastNumberOfEncodings[] =
87 "WebRTC.PeerConnection.Simulcast.NumberOfSendEncodings";
88
89 static const int REPORT_USAGE_PATTERN_DELAY_MS = 60000;
90
91
ConvertIceTransportTypeToCandidateFilter(PeerConnectionInterface::IceTransportsType type)92 uint32_t ConvertIceTransportTypeToCandidateFilter(
93 PeerConnectionInterface::IceTransportsType type) {
94 switch (type) {
95 case PeerConnectionInterface::kNone:
96 return cricket::CF_NONE;
97 case PeerConnectionInterface::kRelay:
98 return cricket::CF_RELAY;
99 case PeerConnectionInterface::kNoHost:
100 return (cricket::CF_ALL & ~cricket::CF_HOST);
101 case PeerConnectionInterface::kAll:
102 return cricket::CF_ALL;
103 default:
104 RTC_NOTREACHED();
105 }
106 return cricket::CF_NONE;
107 }
108
GetIceCandidatePairCounter(const cricket::Candidate & local,const cricket::Candidate & remote)109 IceCandidatePairType GetIceCandidatePairCounter(
110 const cricket::Candidate& local,
111 const cricket::Candidate& remote) {
112 const auto& l = local.type();
113 const auto& r = remote.type();
114 const auto& host = LOCAL_PORT_TYPE;
115 const auto& srflx = STUN_PORT_TYPE;
116 const auto& relay = RELAY_PORT_TYPE;
117 const auto& prflx = PRFLX_PORT_TYPE;
118 if (l == host && r == host) {
119 bool local_hostname =
120 !local.address().hostname().empty() && local.address().IsUnresolvedIP();
121 bool remote_hostname = !remote.address().hostname().empty() &&
122 remote.address().IsUnresolvedIP();
123 bool local_private = IPIsPrivate(local.address().ipaddr());
124 bool remote_private = IPIsPrivate(remote.address().ipaddr());
125 if (local_hostname) {
126 if (remote_hostname) {
127 return kIceCandidatePairHostNameHostName;
128 } else if (remote_private) {
129 return kIceCandidatePairHostNameHostPrivate;
130 } else {
131 return kIceCandidatePairHostNameHostPublic;
132 }
133 } else if (local_private) {
134 if (remote_hostname) {
135 return kIceCandidatePairHostPrivateHostName;
136 } else if (remote_private) {
137 return kIceCandidatePairHostPrivateHostPrivate;
138 } else {
139 return kIceCandidatePairHostPrivateHostPublic;
140 }
141 } else {
142 if (remote_hostname) {
143 return kIceCandidatePairHostPublicHostName;
144 } else if (remote_private) {
145 return kIceCandidatePairHostPublicHostPrivate;
146 } else {
147 return kIceCandidatePairHostPublicHostPublic;
148 }
149 }
150 }
151 if (l == host && r == srflx)
152 return kIceCandidatePairHostSrflx;
153 if (l == host && r == relay)
154 return kIceCandidatePairHostRelay;
155 if (l == host && r == prflx)
156 return kIceCandidatePairHostPrflx;
157 if (l == srflx && r == host)
158 return kIceCandidatePairSrflxHost;
159 if (l == srflx && r == srflx)
160 return kIceCandidatePairSrflxSrflx;
161 if (l == srflx && r == relay)
162 return kIceCandidatePairSrflxRelay;
163 if (l == srflx && r == prflx)
164 return kIceCandidatePairSrflxPrflx;
165 if (l == relay && r == host)
166 return kIceCandidatePairRelayHost;
167 if (l == relay && r == srflx)
168 return kIceCandidatePairRelaySrflx;
169 if (l == relay && r == relay)
170 return kIceCandidatePairRelayRelay;
171 if (l == relay && r == prflx)
172 return kIceCandidatePairRelayPrflx;
173 if (l == prflx && r == host)
174 return kIceCandidatePairPrflxHost;
175 if (l == prflx && r == srflx)
176 return kIceCandidatePairPrflxSrflx;
177 if (l == prflx && r == relay)
178 return kIceCandidatePairPrflxRelay;
179 return kIceCandidatePairMax;
180 }
181
182
RTCConfigurationToIceConfigOptionalInt(int rtc_configuration_parameter)183 absl::optional<int> RTCConfigurationToIceConfigOptionalInt(
184 int rtc_configuration_parameter) {
185 if (rtc_configuration_parameter ==
186 webrtc::PeerConnectionInterface::RTCConfiguration::kUndefined) {
187 return absl::nullopt;
188 }
189 return rtc_configuration_parameter;
190 }
191
192 // Check if the changes of IceTransportsType motives an ice restart.
NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,PeerConnectionInterface::IceTransportsType current,PeerConnectionInterface::IceTransportsType modified)193 bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,
194 PeerConnectionInterface::IceTransportsType current,
195 PeerConnectionInterface::IceTransportsType modified) {
196 if (current == modified) {
197 return false;
198 }
199
200 if (!surface_ice_candidates_on_ice_transport_type_changed) {
201 return true;
202 }
203
204 auto current_filter = ConvertIceTransportTypeToCandidateFilter(current);
205 auto modified_filter = ConvertIceTransportTypeToCandidateFilter(modified);
206
207 // If surface_ice_candidates_on_ice_transport_type_changed is true and we
208 // extend the filter, then no ice restart is needed.
209 return (current_filter & modified_filter) != current_filter;
210 }
211
ParseIceConfig(const PeerConnectionInterface::RTCConfiguration & config)212 cricket::IceConfig ParseIceConfig(
213 const PeerConnectionInterface::RTCConfiguration& config) {
214 cricket::ContinualGatheringPolicy gathering_policy;
215 switch (config.continual_gathering_policy) {
216 case PeerConnectionInterface::GATHER_ONCE:
217 gathering_policy = cricket::GATHER_ONCE;
218 break;
219 case PeerConnectionInterface::GATHER_CONTINUALLY:
220 gathering_policy = cricket::GATHER_CONTINUALLY;
221 break;
222 default:
223 RTC_NOTREACHED();
224 gathering_policy = cricket::GATHER_ONCE;
225 }
226
227 cricket::IceConfig ice_config;
228 ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt(
229 config.ice_connection_receiving_timeout);
230 ice_config.prioritize_most_likely_candidate_pairs =
231 config.prioritize_most_likely_ice_candidate_pairs;
232 ice_config.backup_connection_ping_interval =
233 RTCConfigurationToIceConfigOptionalInt(
234 config.ice_backup_candidate_pair_ping_interval);
235 ice_config.continual_gathering_policy = gathering_policy;
236 ice_config.presume_writable_when_fully_relayed =
237 config.presume_writable_when_fully_relayed;
238 ice_config.surface_ice_candidates_on_ice_transport_type_changed =
239 config.surface_ice_candidates_on_ice_transport_type_changed;
240 ice_config.ice_check_interval_strong_connectivity =
241 config.ice_check_interval_strong_connectivity;
242 ice_config.ice_check_interval_weak_connectivity =
243 config.ice_check_interval_weak_connectivity;
244 ice_config.ice_check_min_interval = config.ice_check_min_interval;
245 ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout;
246 ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks;
247 ice_config.ice_inactive_timeout = config.ice_inactive_timeout;
248 ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
249 ice_config.network_preference = config.network_preference;
250 return ice_config;
251 }
252
253 // Ensures the configuration doesn't have any parameters with invalid values,
254 // or values that conflict with other parameters.
255 //
256 // Returns RTCError::OK() if there are no issues.
ValidateConfiguration(const PeerConnectionInterface::RTCConfiguration & config)257 RTCError ValidateConfiguration(
258 const PeerConnectionInterface::RTCConfiguration& config) {
259 return cricket::P2PTransportChannel::ValidateIceConfig(
260 ParseIceConfig(config));
261 }
262
HasRtcpMuxEnabled(const cricket::ContentInfo * content)263 bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) {
264 return content->media_description()->rtcp_mux();
265 }
266
267 } // namespace
268
operator ==(const PeerConnectionInterface::RTCConfiguration & o) const269 bool PeerConnectionInterface::RTCConfiguration::operator==(
270 const PeerConnectionInterface::RTCConfiguration& o) const {
271 // This static_assert prevents us from accidentally breaking operator==.
272 // Note: Order matters! Fields must be ordered the same as RTCConfiguration.
273 struct stuff_being_tested_for_equality {
274 IceServers servers;
275 IceTransportsType type;
276 BundlePolicy bundle_policy;
277 RtcpMuxPolicy rtcp_mux_policy;
278 std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
279 int ice_candidate_pool_size;
280 bool disable_ipv6;
281 bool disable_ipv6_on_wifi;
282 int max_ipv6_networks;
283 bool disable_link_local_networks;
284 bool enable_rtp_data_channel;
285 absl::optional<int> screencast_min_bitrate;
286 absl::optional<bool> combined_audio_video_bwe;
287 absl::optional<bool> enable_dtls_srtp;
288 TcpCandidatePolicy tcp_candidate_policy;
289 CandidateNetworkPolicy candidate_network_policy;
290 int audio_jitter_buffer_max_packets;
291 bool audio_jitter_buffer_fast_accelerate;
292 int audio_jitter_buffer_min_delay_ms;
293 bool audio_jitter_buffer_enable_rtx_handling;
294 int ice_connection_receiving_timeout;
295 int ice_backup_candidate_pair_ping_interval;
296 ContinualGatheringPolicy continual_gathering_policy;
297 bool prioritize_most_likely_ice_candidate_pairs;
298 struct cricket::MediaConfig media_config;
299 bool prune_turn_ports;
300 PortPrunePolicy turn_port_prune_policy;
301 bool presume_writable_when_fully_relayed;
302 bool enable_ice_renomination;
303 bool redetermine_role_on_ice_restart;
304 bool surface_ice_candidates_on_ice_transport_type_changed;
305 absl::optional<int> ice_check_interval_strong_connectivity;
306 absl::optional<int> ice_check_interval_weak_connectivity;
307 absl::optional<int> ice_check_min_interval;
308 absl::optional<int> ice_unwritable_timeout;
309 absl::optional<int> ice_unwritable_min_checks;
310 absl::optional<int> ice_inactive_timeout;
311 absl::optional<int> stun_candidate_keepalive_interval;
312 webrtc::TurnCustomizer* turn_customizer;
313 SdpSemantics sdp_semantics;
314 absl::optional<rtc::AdapterType> network_preference;
315 bool active_reset_srtp_params;
316 absl::optional<CryptoOptions> crypto_options;
317 bool offer_extmap_allow_mixed;
318 std::string turn_logging_id;
319 bool enable_implicit_rollback;
320 absl::optional<bool> allow_codec_switching;
321 absl::optional<int> report_usage_pattern_delay_ms;
322 };
323 static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
324 "Did you add something to RTCConfiguration and forget to "
325 "update operator==?");
326 return type == o.type && servers == o.servers &&
327 bundle_policy == o.bundle_policy &&
328 rtcp_mux_policy == o.rtcp_mux_policy &&
329 tcp_candidate_policy == o.tcp_candidate_policy &&
330 candidate_network_policy == o.candidate_network_policy &&
331 audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
332 audio_jitter_buffer_fast_accelerate ==
333 o.audio_jitter_buffer_fast_accelerate &&
334 audio_jitter_buffer_min_delay_ms ==
335 o.audio_jitter_buffer_min_delay_ms &&
336 audio_jitter_buffer_enable_rtx_handling ==
337 o.audio_jitter_buffer_enable_rtx_handling &&
338 ice_connection_receiving_timeout ==
339 o.ice_connection_receiving_timeout &&
340 ice_backup_candidate_pair_ping_interval ==
341 o.ice_backup_candidate_pair_ping_interval &&
342 continual_gathering_policy == o.continual_gathering_policy &&
343 certificates == o.certificates &&
344 prioritize_most_likely_ice_candidate_pairs ==
345 o.prioritize_most_likely_ice_candidate_pairs &&
346 media_config == o.media_config && disable_ipv6 == o.disable_ipv6 &&
347 disable_ipv6_on_wifi == o.disable_ipv6_on_wifi &&
348 max_ipv6_networks == o.max_ipv6_networks &&
349 disable_link_local_networks == o.disable_link_local_networks &&
350 enable_rtp_data_channel == o.enable_rtp_data_channel &&
351 screencast_min_bitrate == o.screencast_min_bitrate &&
352 combined_audio_video_bwe == o.combined_audio_video_bwe &&
353 enable_dtls_srtp == o.enable_dtls_srtp &&
354 ice_candidate_pool_size == o.ice_candidate_pool_size &&
355 prune_turn_ports == o.prune_turn_ports &&
356 turn_port_prune_policy == o.turn_port_prune_policy &&
357 presume_writable_when_fully_relayed ==
358 o.presume_writable_when_fully_relayed &&
359 enable_ice_renomination == o.enable_ice_renomination &&
360 redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
361 surface_ice_candidates_on_ice_transport_type_changed ==
362 o.surface_ice_candidates_on_ice_transport_type_changed &&
363 ice_check_interval_strong_connectivity ==
364 o.ice_check_interval_strong_connectivity &&
365 ice_check_interval_weak_connectivity ==
366 o.ice_check_interval_weak_connectivity &&
367 ice_check_min_interval == o.ice_check_min_interval &&
368 ice_unwritable_timeout == o.ice_unwritable_timeout &&
369 ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
370 ice_inactive_timeout == o.ice_inactive_timeout &&
371 stun_candidate_keepalive_interval ==
372 o.stun_candidate_keepalive_interval &&
373 turn_customizer == o.turn_customizer &&
374 sdp_semantics == o.sdp_semantics &&
375 network_preference == o.network_preference &&
376 active_reset_srtp_params == o.active_reset_srtp_params &&
377 crypto_options == o.crypto_options &&
378 offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
379 turn_logging_id == o.turn_logging_id &&
380 enable_implicit_rollback == o.enable_implicit_rollback &&
381 allow_codec_switching == o.allow_codec_switching &&
382 report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms;
383 }
384
operator !=(const PeerConnectionInterface::RTCConfiguration & o) const385 bool PeerConnectionInterface::RTCConfiguration::operator!=(
386 const PeerConnectionInterface::RTCConfiguration& o) const {
387 return !(*this == o);
388 }
389
Create(rtc::scoped_refptr<ConnectionContext> context,const PeerConnectionFactoryInterface::Options & options,std::unique_ptr<RtcEventLog> event_log,std::unique_ptr<Call> call,const PeerConnectionInterface::RTCConfiguration & configuration,PeerConnectionDependencies dependencies)390 rtc::scoped_refptr<PeerConnection> PeerConnection::Create(
391 rtc::scoped_refptr<ConnectionContext> context,
392 const PeerConnectionFactoryInterface::Options& options,
393 std::unique_ptr<RtcEventLog> event_log,
394 std::unique_ptr<Call> call,
395 const PeerConnectionInterface::RTCConfiguration& configuration,
396 PeerConnectionDependencies dependencies) {
397 RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
398 ParseIceConfig(configuration));
399 if (!config_error.ok()) {
400 RTC_LOG(LS_ERROR) << "Invalid configuration: " << config_error.message();
401 return nullptr;
402 }
403
404 if (!dependencies.allocator) {
405 RTC_LOG(LS_ERROR)
406 << "PeerConnection initialized without a PortAllocator? "
407 "This shouldn't happen if using PeerConnectionFactory.";
408 return nullptr;
409 }
410
411 if (!dependencies.observer) {
412 // TODO(deadbeef): Why do we do this?
413 RTC_LOG(LS_ERROR) << "PeerConnection initialized without a "
414 "PeerConnectionObserver";
415 return nullptr;
416 }
417
418 bool is_unified_plan =
419 configuration.sdp_semantics == SdpSemantics::kUnifiedPlan;
420 // The PeerConnection constructor consumes some, but not all, dependencies.
421 rtc::scoped_refptr<PeerConnection> pc(
422 new rtc::RefCountedObject<PeerConnection>(
423 context, options, is_unified_plan, std::move(event_log),
424 std::move(call), dependencies));
425 if (!pc->Initialize(configuration, std::move(dependencies))) {
426 return nullptr;
427 }
428 return pc;
429 }
430
PeerConnection(rtc::scoped_refptr<ConnectionContext> context,const PeerConnectionFactoryInterface::Options & options,bool is_unified_plan,std::unique_ptr<RtcEventLog> event_log,std::unique_ptr<Call> call,PeerConnectionDependencies & dependencies)431 PeerConnection::PeerConnection(
432 rtc::scoped_refptr<ConnectionContext> context,
433 const PeerConnectionFactoryInterface::Options& options,
434 bool is_unified_plan,
435 std::unique_ptr<RtcEventLog> event_log,
436 std::unique_ptr<Call> call,
437 PeerConnectionDependencies& dependencies)
438 : context_(context),
439 options_(options),
440 observer_(dependencies.observer),
441 is_unified_plan_(is_unified_plan),
442 event_log_(std::move(event_log)),
443 event_log_ptr_(event_log_.get()),
444 async_resolver_factory_(std::move(dependencies.async_resolver_factory)),
445 port_allocator_(std::move(dependencies.allocator)),
446 ice_transport_factory_(std::move(dependencies.ice_transport_factory)),
447 tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
448 call_(std::move(call)),
449 call_ptr_(call_.get()),
450 data_channel_controller_(this),
451 message_handler_(signaling_thread()) {}
452
~PeerConnection()453 PeerConnection::~PeerConnection() {
454 TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
455 RTC_DCHECK_RUN_ON(signaling_thread());
456
457 if (sdp_handler_) {
458 sdp_handler_->PrepareForShutdown();
459 }
460
461 // Need to stop transceivers before destroying the stats collector because
462 // AudioRtpSender has a reference to the StatsCollector it will update when
463 // stopping.
464 if (rtp_manager()) {
465 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
466 transceiver->StopInternal();
467 }
468 }
469
470 stats_.reset(nullptr);
471 if (stats_collector_) {
472 stats_collector_->WaitForPendingRequest();
473 stats_collector_ = nullptr;
474 }
475
476 if (sdp_handler_) {
477 // Don't destroy BaseChannels until after stats has been cleaned up so that
478 // the last stats request can still read from the channels.
479 sdp_handler_->DestroyAllChannels();
480
481 RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
482
483 sdp_handler_->ResetSessionDescFactory();
484 }
485 transport_controller_.reset();
486
487 // port_allocator_ lives on the network thread and should be destroyed there.
488 network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
489 RTC_DCHECK_RUN_ON(network_thread());
490 port_allocator_.reset();
491 });
492 // call_ and event_log_ must be destroyed on the worker thread.
493 worker_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
494 RTC_DCHECK_RUN_ON(worker_thread());
495 call_safety_.reset();
496 call_.reset();
497 // The event log must outlive call (and any other object that uses it).
498 event_log_.reset();
499 });
500 }
501
Initialize(const PeerConnectionInterface::RTCConfiguration & configuration,PeerConnectionDependencies dependencies)502 bool PeerConnection::Initialize(
503 const PeerConnectionInterface::RTCConfiguration& configuration,
504 PeerConnectionDependencies dependencies) {
505 RTC_DCHECK_RUN_ON(signaling_thread());
506 TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
507
508 cricket::ServerAddresses stun_servers;
509 std::vector<cricket::RelayServerConfig> turn_servers;
510
511 RTCErrorType parse_error =
512 ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
513 if (parse_error != RTCErrorType::NONE) {
514 return false;
515 }
516
517 // Add the turn logging id to all turn servers
518 for (cricket::RelayServerConfig& turn_server : turn_servers) {
519 turn_server.turn_logging_id = configuration.turn_logging_id;
520 }
521
522 // The port allocator lives on the network thread and should be initialized
523 // there.
524 const auto pa_result =
525 network_thread()->Invoke<InitializePortAllocatorResult>(
526 RTC_FROM_HERE,
527 rtc::Bind(&PeerConnection::InitializePortAllocator_n, this,
528 stun_servers, turn_servers, configuration));
529
530 // Note if STUN or TURN servers were supplied.
531 if (!stun_servers.empty()) {
532 NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
533 }
534 if (!turn_servers.empty()) {
535 NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
536 }
537
538 // Send information about IPv4/IPv6 status.
539 PeerConnectionAddressFamilyCounter address_family;
540 if (pa_result.enable_ipv6) {
541 address_family = kPeerConnection_IPv6;
542 } else {
543 address_family = kPeerConnection_IPv4;
544 }
545 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", address_family,
546 kPeerConnectionAddressFamilyCounter_Max);
547
548 // RFC 3264: The numeric value of the session id and version in the
549 // o line MUST be representable with a "64 bit signed integer".
550 // Due to this constraint session id |session_id_| is max limited to
551 // LLONG_MAX.
552 session_id_ = rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX);
553 JsepTransportController::Config config;
554 config.redetermine_role_on_ice_restart =
555 configuration.redetermine_role_on_ice_restart;
556 config.ssl_max_version = options_.ssl_max_version;
557 config.disable_encryption = options_.disable_encryption;
558 config.bundle_policy = configuration.bundle_policy;
559 config.rtcp_mux_policy = configuration.rtcp_mux_policy;
560 // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove
561 // this stub.
562 config.crypto_options = configuration.crypto_options.has_value()
563 ? *configuration.crypto_options
564 : options_.crypto_options;
565 config.transport_observer = this;
566 config.rtcp_handler = InitializeRtcpCallback();
567 config.event_log = event_log_ptr_;
568 #if defined(ENABLE_EXTERNAL_AUTH)
569 config.enable_external_auth = true;
570 #endif
571 config.active_reset_srtp_params = configuration.active_reset_srtp_params;
572
573 if (options_.disable_encryption) {
574 dtls_enabled_ = false;
575 } else {
576 // Enable DTLS by default if we have an identity store or a certificate.
577 dtls_enabled_ =
578 (dependencies.cert_generator || !configuration.certificates.empty());
579 // |configuration| can override the default |dtls_enabled_| value.
580 if (configuration.enable_dtls_srtp) {
581 dtls_enabled_ = *(configuration.enable_dtls_srtp);
582 }
583 }
584
585 if (configuration.enable_rtp_data_channel) {
586 // Enable creation of RTP data channels if the kEnableRtpDataChannels is
587 // set. It takes precendence over the disable_sctp_data_channels
588 // PeerConnectionFactoryInterface::Options.
589 data_channel_controller_.set_data_channel_type(cricket::DCT_RTP);
590 } else {
591 // DTLS has to be enabled to use SCTP.
592 if (!options_.disable_sctp_data_channels && dtls_enabled_) {
593 data_channel_controller_.set_data_channel_type(cricket::DCT_SCTP);
594 config.sctp_factory = context_->sctp_transport_factory();
595 }
596 }
597
598 config.ice_transport_factory = ice_transport_factory_.get();
599
600 transport_controller_.reset(new JsepTransportController(
601 signaling_thread(), network_thread(), port_allocator_.get(),
602 async_resolver_factory_.get(), config));
603 transport_controller_->SignalStandardizedIceConnectionState.connect(
604 this, &PeerConnection::SetStandardizedIceConnectionState);
605 transport_controller_->SignalConnectionState.connect(
606 this, &PeerConnection::SetConnectionState);
607 transport_controller_->SignalIceGatheringState.connect(
608 this, &PeerConnection::OnTransportControllerGatheringState);
609 transport_controller_->SignalIceCandidatesGathered.connect(
610 this, &PeerConnection::OnTransportControllerCandidatesGathered);
611 transport_controller_->SignalIceCandidateError.connect(
612 this, &PeerConnection::OnTransportControllerCandidateError);
613 transport_controller_->SignalIceCandidatesRemoved.connect(
614 this, &PeerConnection::OnTransportControllerCandidatesRemoved);
615 transport_controller_->SignalDtlsHandshakeError.connect(
616 this, &PeerConnection::OnTransportControllerDtlsHandshakeError);
617 transport_controller_->SignalIceCandidatePairChanged.connect(
618 this, &PeerConnection::OnTransportControllerCandidateChanged);
619
620 transport_controller_->SignalIceConnectionState.AddReceiver(
621 [this](cricket::IceConnectionState s) {
622 RTC_DCHECK_RUN_ON(signaling_thread());
623 OnTransportControllerConnectionState(s);
624 });
625
626 configuration_ = configuration;
627
628 transport_controller_->SetIceConfig(ParseIceConfig(configuration));
629
630 stats_ = std::make_unique<StatsCollector>(this);
631 stats_collector_ = RTCStatsCollector::Create(this);
632
633 sdp_handler_ =
634 SdpOfferAnswerHandler::Create(this, configuration, dependencies);
635
636 rtp_manager_ = std::make_unique<RtpTransmissionManager>(
637 IsUnifiedPlan(), signaling_thread(), worker_thread(), channel_manager(),
638 &usage_pattern_, observer_, stats_.get(), [this]() {
639 RTC_DCHECK_RUN_ON(signaling_thread());
640 sdp_handler_->UpdateNegotiationNeeded();
641 });
642
643 // Add default audio/video transceivers for Plan B SDP.
644 if (!IsUnifiedPlan()) {
645 rtp_manager()->transceivers()->Add(
646 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
647 signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_AUDIO)));
648 rtp_manager()->transceivers()->Add(
649 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
650 signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_VIDEO)));
651 }
652
653 int delay_ms = configuration.report_usage_pattern_delay_ms
654 ? *configuration.report_usage_pattern_delay_ms
655 : REPORT_USAGE_PATTERN_DELAY_MS;
656 message_handler_.RequestUsagePatternReport(
657 [this]() {
658 RTC_DCHECK_RUN_ON(signaling_thread());
659 ReportUsagePattern();
660 },
661 delay_ms);
662
663 return true;
664 }
665
local_streams()666 rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::local_streams() {
667 RTC_DCHECK_RUN_ON(signaling_thread());
668 RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
669 "Plan SdpSemantics. Please use GetSenders "
670 "instead.";
671 return sdp_handler_->local_streams();
672 }
673
remote_streams()674 rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
675 RTC_DCHECK_RUN_ON(signaling_thread());
676 RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
677 "Plan SdpSemantics. Please use GetReceivers "
678 "instead.";
679 return sdp_handler_->remote_streams();
680 }
681
AddStream(MediaStreamInterface * local_stream)682 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
683 RTC_DCHECK_RUN_ON(signaling_thread());
684 RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
685 "SdpSemantics. Please use AddTrack instead.";
686 TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
687 return sdp_handler_->AddStream(local_stream);
688 }
689
RemoveStream(MediaStreamInterface * local_stream)690 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
691 RTC_DCHECK_RUN_ON(signaling_thread());
692 RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified "
693 "Plan SdpSemantics. Please use RemoveTrack "
694 "instead.";
695 TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
696 sdp_handler_->RemoveStream(local_stream);
697 }
698
AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string> & stream_ids)699 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
700 rtc::scoped_refptr<MediaStreamTrackInterface> track,
701 const std::vector<std::string>& stream_ids) {
702 RTC_DCHECK_RUN_ON(signaling_thread());
703 TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
704 if (!track) {
705 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Track is null.");
706 }
707 if (!(track->kind() == MediaStreamTrackInterface::kAudioKind ||
708 track->kind() == MediaStreamTrackInterface::kVideoKind)) {
709 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
710 "Track has invalid kind: " + track->kind());
711 }
712 if (IsClosed()) {
713 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
714 "PeerConnection is closed.");
715 }
716 if (rtp_manager()->FindSenderForTrack(track)) {
717 LOG_AND_RETURN_ERROR(
718 RTCErrorType::INVALID_PARAMETER,
719 "Sender already exists for track " + track->id() + ".");
720 }
721 auto sender_or_error = rtp_manager()->AddTrack(track, stream_ids);
722 if (sender_or_error.ok()) {
723 sdp_handler_->UpdateNegotiationNeeded();
724 stats_->AddTrack(track);
725 }
726 return sender_or_error;
727 }
728
RemoveTrack(RtpSenderInterface * sender)729 bool PeerConnection::RemoveTrack(RtpSenderInterface* sender) {
730 TRACE_EVENT0("webrtc", "PeerConnection::RemoveTrack");
731 return RemoveTrackNew(sender).ok();
732 }
733
RemoveTrackNew(rtc::scoped_refptr<RtpSenderInterface> sender)734 RTCError PeerConnection::RemoveTrackNew(
735 rtc::scoped_refptr<RtpSenderInterface> sender) {
736 RTC_DCHECK_RUN_ON(signaling_thread());
737 if (!sender) {
738 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Sender is null.");
739 }
740 if (IsClosed()) {
741 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
742 "PeerConnection is closed.");
743 }
744 if (IsUnifiedPlan()) {
745 auto transceiver = FindTransceiverBySender(sender);
746 if (!transceiver || !sender->track()) {
747 return RTCError::OK();
748 }
749 sender->SetTrack(nullptr);
750 if (transceiver->direction() == RtpTransceiverDirection::kSendRecv) {
751 transceiver->internal()->set_direction(
752 RtpTransceiverDirection::kRecvOnly);
753 } else if (transceiver->direction() == RtpTransceiverDirection::kSendOnly) {
754 transceiver->internal()->set_direction(
755 RtpTransceiverDirection::kInactive);
756 }
757 } else {
758 bool removed;
759 if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
760 removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender(
761 sender);
762 } else {
763 RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
764 removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender(
765 sender);
766 }
767 if (!removed) {
768 LOG_AND_RETURN_ERROR(
769 RTCErrorType::INVALID_PARAMETER,
770 "Couldn't find sender " + sender->id() + " to remove.");
771 }
772 }
773 sdp_handler_->UpdateNegotiationNeeded();
774 return RTCError::OK();
775 }
776
777 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
FindTransceiverBySender(rtc::scoped_refptr<RtpSenderInterface> sender)778 PeerConnection::FindTransceiverBySender(
779 rtc::scoped_refptr<RtpSenderInterface> sender) {
780 return rtp_manager()->transceivers()->FindBySender(sender);
781 }
782
783 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track)784 PeerConnection::AddTransceiver(
785 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
786 return AddTransceiver(track, RtpTransceiverInit());
787 }
788
789 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track,const RtpTransceiverInit & init)790 PeerConnection::AddTransceiver(
791 rtc::scoped_refptr<MediaStreamTrackInterface> track,
792 const RtpTransceiverInit& init) {
793 RTC_DCHECK_RUN_ON(signaling_thread());
794 RTC_CHECK(IsUnifiedPlan())
795 << "AddTransceiver is only available with Unified Plan SdpSemantics";
796 if (!track) {
797 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "track is null");
798 }
799 cricket::MediaType media_type;
800 if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
801 media_type = cricket::MEDIA_TYPE_AUDIO;
802 } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
803 media_type = cricket::MEDIA_TYPE_VIDEO;
804 } else {
805 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
806 "Track kind is not audio or video");
807 }
808 return AddTransceiver(media_type, track, init);
809 }
810
811 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type)812 PeerConnection::AddTransceiver(cricket::MediaType media_type) {
813 return AddTransceiver(media_type, RtpTransceiverInit());
814 }
815
816 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type,const RtpTransceiverInit & init)817 PeerConnection::AddTransceiver(cricket::MediaType media_type,
818 const RtpTransceiverInit& init) {
819 RTC_DCHECK_RUN_ON(signaling_thread());
820 RTC_CHECK(IsUnifiedPlan())
821 << "AddTransceiver is only available with Unified Plan SdpSemantics";
822 if (!(media_type == cricket::MEDIA_TYPE_AUDIO ||
823 media_type == cricket::MEDIA_TYPE_VIDEO)) {
824 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
825 "media type is not audio or video");
826 }
827 return AddTransceiver(media_type, nullptr, init);
828 }
829
830 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type,rtc::scoped_refptr<MediaStreamTrackInterface> track,const RtpTransceiverInit & init,bool update_negotiation_needed)831 PeerConnection::AddTransceiver(
832 cricket::MediaType media_type,
833 rtc::scoped_refptr<MediaStreamTrackInterface> track,
834 const RtpTransceiverInit& init,
835 bool update_negotiation_needed) {
836 RTC_DCHECK_RUN_ON(signaling_thread());
837 RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
838 media_type == cricket::MEDIA_TYPE_VIDEO));
839 if (track) {
840 RTC_DCHECK_EQ(media_type,
841 (track->kind() == MediaStreamTrackInterface::kAudioKind
842 ? cricket::MEDIA_TYPE_AUDIO
843 : cricket::MEDIA_TYPE_VIDEO));
844 }
845
846 RTC_HISTOGRAM_COUNTS_LINEAR(kSimulcastNumberOfEncodings,
847 init.send_encodings.size(), 0, 7, 8);
848
849 size_t num_rids = absl::c_count_if(init.send_encodings,
850 [](const RtpEncodingParameters& encoding) {
851 return !encoding.rid.empty();
852 });
853 if (num_rids > 0 && num_rids != init.send_encodings.size()) {
854 LOG_AND_RETURN_ERROR(
855 RTCErrorType::INVALID_PARAMETER,
856 "RIDs must be provided for either all or none of the send encodings.");
857 }
858
859 if (num_rids > 0 && absl::c_any_of(init.send_encodings,
860 [](const RtpEncodingParameters& encoding) {
861 return !IsLegalRsidName(encoding.rid);
862 })) {
863 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
864 "Invalid RID value provided.");
865 }
866
867 if (absl::c_any_of(init.send_encodings,
868 [](const RtpEncodingParameters& encoding) {
869 return encoding.ssrc.has_value();
870 })) {
871 LOG_AND_RETURN_ERROR(
872 RTCErrorType::UNSUPPORTED_PARAMETER,
873 "Attempted to set an unimplemented parameter of RtpParameters.");
874 }
875
876 RtpParameters parameters;
877 parameters.encodings = init.send_encodings;
878
879 // Encodings are dropped from the tail if too many are provided.
880 if (parameters.encodings.size() > kMaxSimulcastStreams) {
881 parameters.encodings.erase(
882 parameters.encodings.begin() + kMaxSimulcastStreams,
883 parameters.encodings.end());
884 }
885
886 // Single RID should be removed.
887 if (parameters.encodings.size() == 1 &&
888 !parameters.encodings[0].rid.empty()) {
889 RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
890 parameters.encodings[0].rid.clear();
891 }
892
893 // If RIDs were not provided, they are generated for simulcast scenario.
894 if (parameters.encodings.size() > 1 && num_rids == 0) {
895 rtc::UniqueStringGenerator rid_generator;
896 for (RtpEncodingParameters& encoding : parameters.encodings) {
897 encoding.rid = rid_generator();
898 }
899 }
900
901 if (UnimplementedRtpParameterHasValue(parameters)) {
902 LOG_AND_RETURN_ERROR(
903 RTCErrorType::UNSUPPORTED_PARAMETER,
904 "Attempted to set an unimplemented parameter of RtpParameters.");
905 }
906
907 auto result = cricket::CheckRtpParametersValues(parameters);
908 if (!result.ok()) {
909 LOG_AND_RETURN_ERROR(result.type(), result.message());
910 }
911
912 RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
913 << " transceiver in response to a call to AddTransceiver.";
914 // Set the sender ID equal to the track ID if the track is specified unless
915 // that sender ID is already in use.
916 std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
917 ? track->id()
918 : rtc::CreateRandomUuid());
919 auto sender = rtp_manager()->CreateSender(
920 media_type, sender_id, track, init.stream_ids, parameters.encodings);
921 auto receiver =
922 rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
923 auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
924 transceiver->internal()->set_direction(init.direction);
925
926 if (update_negotiation_needed) {
927 sdp_handler_->UpdateNegotiationNeeded();
928 }
929
930 return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
931 }
932
OnNegotiationNeeded()933 void PeerConnection::OnNegotiationNeeded() {
934 RTC_DCHECK_RUN_ON(signaling_thread());
935 RTC_DCHECK(!IsClosed());
936 sdp_handler_->UpdateNegotiationNeeded();
937 }
938
CreateSender(const std::string & kind,const std::string & stream_id)939 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
940 const std::string& kind,
941 const std::string& stream_id) {
942 RTC_DCHECK_RUN_ON(signaling_thread());
943 RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified "
944 "Plan SdpSemantics. Please use AddTransceiver "
945 "instead.";
946 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
947 if (IsClosed()) {
948 return nullptr;
949 }
950
951 // Internally we need to have one stream with Plan B semantics, so we
952 // generate a random stream ID if not specified.
953 std::vector<std::string> stream_ids;
954 if (stream_id.empty()) {
955 stream_ids.push_back(rtc::CreateRandomUuid());
956 RTC_LOG(LS_INFO)
957 << "No stream_id specified for sender. Generated stream ID: "
958 << stream_ids[0];
959 } else {
960 stream_ids.push_back(stream_id);
961 }
962
963 // TODO(steveanton): Move construction of the RtpSenders to RtpTransceiver.
964 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
965 if (kind == MediaStreamTrackInterface::kAudioKind) {
966 auto audio_sender = AudioRtpSender::Create(
967 worker_thread(), rtc::CreateRandomUuid(), stats_.get(), rtp_manager());
968 audio_sender->SetMediaChannel(rtp_manager()->voice_media_channel());
969 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
970 signaling_thread(), audio_sender);
971 rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
972 } else if (kind == MediaStreamTrackInterface::kVideoKind) {
973 auto video_sender = VideoRtpSender::Create(
974 worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
975 video_sender->SetMediaChannel(rtp_manager()->video_media_channel());
976 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
977 signaling_thread(), video_sender);
978 rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender);
979 } else {
980 RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
981 return nullptr;
982 }
983 new_sender->internal()->set_stream_ids(stream_ids);
984
985 return new_sender;
986 }
987
GetSenders() const988 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
989 const {
990 RTC_DCHECK_RUN_ON(signaling_thread());
991 std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
992 for (const auto& sender : rtp_manager()->GetSendersInternal()) {
993 ret.push_back(sender);
994 }
995 return ret;
996 }
997
998 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
GetReceivers() const999 PeerConnection::GetReceivers() const {
1000 RTC_DCHECK_RUN_ON(signaling_thread());
1001 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
1002 for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
1003 ret.push_back(receiver);
1004 }
1005 return ret;
1006 }
1007
1008 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
GetTransceivers() const1009 PeerConnection::GetTransceivers() const {
1010 RTC_DCHECK_RUN_ON(signaling_thread());
1011 RTC_CHECK(IsUnifiedPlan())
1012 << "GetTransceivers is only supported with Unified Plan SdpSemantics.";
1013 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
1014 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1015 all_transceivers.push_back(transceiver);
1016 }
1017 return all_transceivers;
1018 }
1019
GetStats(StatsObserver * observer,MediaStreamTrackInterface * track,StatsOutputLevel level)1020 bool PeerConnection::GetStats(StatsObserver* observer,
1021 MediaStreamTrackInterface* track,
1022 StatsOutputLevel level) {
1023 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1024 RTC_DCHECK_RUN_ON(signaling_thread());
1025 if (!observer) {
1026 RTC_LOG(LS_ERROR) << "GetStats - observer is NULL.";
1027 return false;
1028 }
1029
1030 stats_->UpdateStats(level);
1031 // The StatsCollector is used to tell if a track is valid because it may
1032 // remember tracks that the PeerConnection previously removed.
1033 if (track && !stats_->IsValidTrack(track->id())) {
1034 RTC_LOG(LS_WARNING) << "GetStats is called with an invalid track: "
1035 << track->id();
1036 return false;
1037 }
1038 message_handler_.PostGetStats(observer, stats_.get(), track);
1039 return true;
1040 }
1041
GetStats(RTCStatsCollectorCallback * callback)1042 void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
1043 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1044 RTC_DCHECK_RUN_ON(signaling_thread());
1045 RTC_DCHECK(stats_collector_);
1046 RTC_DCHECK(callback);
1047 stats_collector_->GetStatsReport(callback);
1048 }
1049
GetStats(rtc::scoped_refptr<RtpSenderInterface> selector,rtc::scoped_refptr<RTCStatsCollectorCallback> callback)1050 void PeerConnection::GetStats(
1051 rtc::scoped_refptr<RtpSenderInterface> selector,
1052 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1053 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1054 RTC_DCHECK_RUN_ON(signaling_thread());
1055 RTC_DCHECK(callback);
1056 RTC_DCHECK(stats_collector_);
1057 rtc::scoped_refptr<RtpSenderInternal> internal_sender;
1058 if (selector) {
1059 for (const auto& proxy_transceiver :
1060 rtp_manager()->transceivers()->List()) {
1061 for (const auto& proxy_sender :
1062 proxy_transceiver->internal()->senders()) {
1063 if (proxy_sender == selector) {
1064 internal_sender = proxy_sender->internal();
1065 break;
1066 }
1067 }
1068 if (internal_sender)
1069 break;
1070 }
1071 }
1072 // If there is no |internal_sender| then |selector| is either null or does not
1073 // belong to the PeerConnection (in Plan B, senders can be removed from the
1074 // PeerConnection). This means that "all the stats objects representing the
1075 // selector" is an empty set. Invoking GetStatsReport() with a null selector
1076 // produces an empty stats report.
1077 stats_collector_->GetStatsReport(internal_sender, callback);
1078 }
1079
GetStats(rtc::scoped_refptr<RtpReceiverInterface> selector,rtc::scoped_refptr<RTCStatsCollectorCallback> callback)1080 void PeerConnection::GetStats(
1081 rtc::scoped_refptr<RtpReceiverInterface> selector,
1082 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1083 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1084 RTC_DCHECK_RUN_ON(signaling_thread());
1085 RTC_DCHECK(callback);
1086 RTC_DCHECK(stats_collector_);
1087 rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
1088 if (selector) {
1089 for (const auto& proxy_transceiver :
1090 rtp_manager()->transceivers()->List()) {
1091 for (const auto& proxy_receiver :
1092 proxy_transceiver->internal()->receivers()) {
1093 if (proxy_receiver == selector) {
1094 internal_receiver = proxy_receiver->internal();
1095 break;
1096 }
1097 }
1098 if (internal_receiver)
1099 break;
1100 }
1101 }
1102 // If there is no |internal_receiver| then |selector| is either null or does
1103 // not belong to the PeerConnection (in Plan B, receivers can be removed from
1104 // the PeerConnection). This means that "all the stats objects representing
1105 // the selector" is an empty set. Invoking GetStatsReport() with a null
1106 // selector produces an empty stats report.
1107 stats_collector_->GetStatsReport(internal_receiver, callback);
1108 }
1109
signaling_state()1110 PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
1111 RTC_DCHECK_RUN_ON(signaling_thread());
1112 return sdp_handler_->signaling_state();
1113 }
1114
1115 PeerConnectionInterface::IceConnectionState
ice_connection_state()1116 PeerConnection::ice_connection_state() {
1117 RTC_DCHECK_RUN_ON(signaling_thread());
1118 return ice_connection_state_;
1119 }
1120
1121 PeerConnectionInterface::IceConnectionState
standardized_ice_connection_state()1122 PeerConnection::standardized_ice_connection_state() {
1123 RTC_DCHECK_RUN_ON(signaling_thread());
1124 return standardized_ice_connection_state_;
1125 }
1126
1127 PeerConnectionInterface::PeerConnectionState
peer_connection_state()1128 PeerConnection::peer_connection_state() {
1129 RTC_DCHECK_RUN_ON(signaling_thread());
1130 return connection_state_;
1131 }
1132
1133 PeerConnectionInterface::IceGatheringState
ice_gathering_state()1134 PeerConnection::ice_gathering_state() {
1135 RTC_DCHECK_RUN_ON(signaling_thread());
1136 return ice_gathering_state_;
1137 }
1138
can_trickle_ice_candidates()1139 absl::optional<bool> PeerConnection::can_trickle_ice_candidates() {
1140 RTC_DCHECK_RUN_ON(signaling_thread());
1141 const SessionDescriptionInterface* description = current_remote_description();
1142 if (!description) {
1143 description = pending_remote_description();
1144 }
1145 if (!description) {
1146 return absl::nullopt;
1147 }
1148 // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
1149 if (description->description()->transport_infos().size() < 1) {
1150 return absl::nullopt;
1151 }
1152 return description->description()->transport_infos()[0].description.HasOption(
1153 "trickle");
1154 }
1155
CreateDataChannel(const std::string & label,const DataChannelInit * config)1156 rtc::scoped_refptr<DataChannelInterface> PeerConnection::CreateDataChannel(
1157 const std::string& label,
1158 const DataChannelInit* config) {
1159 RTC_DCHECK_RUN_ON(signaling_thread());
1160 TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
1161
1162 bool first_datachannel = !data_channel_controller_.HasDataChannels();
1163
1164 std::unique_ptr<InternalDataChannelInit> internal_config;
1165 if (config) {
1166 internal_config.reset(new InternalDataChannelInit(*config));
1167 }
1168 rtc::scoped_refptr<DataChannelInterface> channel(
1169 data_channel_controller_.InternalCreateDataChannelWithProxy(
1170 label, internal_config.get()));
1171 if (!channel.get()) {
1172 return nullptr;
1173 }
1174
1175 // Trigger the onRenegotiationNeeded event for every new RTP DataChannel, or
1176 // the first SCTP DataChannel.
1177 if (data_channel_type() == cricket::DCT_RTP || first_datachannel) {
1178 sdp_handler_->UpdateNegotiationNeeded();
1179 }
1180 NoteUsageEvent(UsageEvent::DATA_ADDED);
1181 return channel;
1182 }
1183
RestartIce()1184 void PeerConnection::RestartIce() {
1185 RTC_DCHECK_RUN_ON(signaling_thread());
1186 sdp_handler_->RestartIce();
1187 }
1188
CreateOffer(CreateSessionDescriptionObserver * observer,const RTCOfferAnswerOptions & options)1189 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
1190 const RTCOfferAnswerOptions& options) {
1191 RTC_DCHECK_RUN_ON(signaling_thread());
1192 sdp_handler_->CreateOffer(observer, options);
1193 }
1194
CreateAnswer(CreateSessionDescriptionObserver * observer,const RTCOfferAnswerOptions & options)1195 void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
1196 const RTCOfferAnswerOptions& options) {
1197 RTC_DCHECK_RUN_ON(signaling_thread());
1198 sdp_handler_->CreateAnswer(observer, options);
1199 }
1200
SetLocalDescription(SetSessionDescriptionObserver * observer,SessionDescriptionInterface * desc_ptr)1201 void PeerConnection::SetLocalDescription(
1202 SetSessionDescriptionObserver* observer,
1203 SessionDescriptionInterface* desc_ptr) {
1204 RTC_DCHECK_RUN_ON(signaling_thread());
1205 sdp_handler_->SetLocalDescription(observer, desc_ptr);
1206 }
1207
SetLocalDescription(std::unique_ptr<SessionDescriptionInterface> desc,rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer)1208 void PeerConnection::SetLocalDescription(
1209 std::unique_ptr<SessionDescriptionInterface> desc,
1210 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1211 RTC_DCHECK_RUN_ON(signaling_thread());
1212 sdp_handler_->SetLocalDescription(std::move(desc), observer);
1213 }
1214
SetLocalDescription(SetSessionDescriptionObserver * observer)1215 void PeerConnection::SetLocalDescription(
1216 SetSessionDescriptionObserver* observer) {
1217 RTC_DCHECK_RUN_ON(signaling_thread());
1218 sdp_handler_->SetLocalDescription(observer);
1219 }
1220
SetLocalDescription(rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer)1221 void PeerConnection::SetLocalDescription(
1222 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1223 RTC_DCHECK_RUN_ON(signaling_thread());
1224 sdp_handler_->SetLocalDescription(observer);
1225 }
1226
SetRemoteDescription(SetSessionDescriptionObserver * observer,SessionDescriptionInterface * desc_ptr)1227 void PeerConnection::SetRemoteDescription(
1228 SetSessionDescriptionObserver* observer,
1229 SessionDescriptionInterface* desc_ptr) {
1230 RTC_DCHECK_RUN_ON(signaling_thread());
1231 sdp_handler_->SetRemoteDescription(observer, desc_ptr);
1232 }
1233
SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer)1234 void PeerConnection::SetRemoteDescription(
1235 std::unique_ptr<SessionDescriptionInterface> desc,
1236 rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
1237 RTC_DCHECK_RUN_ON(signaling_thread());
1238 sdp_handler_->SetRemoteDescription(std::move(desc), observer);
1239 }
1240
GetConfiguration()1241 PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
1242 RTC_DCHECK_RUN_ON(signaling_thread());
1243 return configuration_;
1244 }
1245
SetConfiguration(const RTCConfiguration & configuration)1246 RTCError PeerConnection::SetConfiguration(
1247 const RTCConfiguration& configuration) {
1248 RTC_DCHECK_RUN_ON(signaling_thread());
1249 TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
1250 if (IsClosed()) {
1251 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1252 "SetConfiguration: PeerConnection is closed.");
1253 }
1254
1255 // According to JSEP, after setLocalDescription, changing the candidate pool
1256 // size is not allowed, and changing the set of ICE servers will not result
1257 // in new candidates being gathered.
1258 if (local_description() && configuration.ice_candidate_pool_size !=
1259 configuration_.ice_candidate_pool_size) {
1260 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1261 "Can't change candidate pool size after calling "
1262 "SetLocalDescription.");
1263 }
1264
1265 if (local_description() &&
1266 configuration.crypto_options != configuration_.crypto_options) {
1267 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1268 "Can't change crypto_options after calling "
1269 "SetLocalDescription.");
1270 }
1271
1272 // The simplest (and most future-compatible) way to tell if the config was
1273 // modified in an invalid way is to copy each property we do support
1274 // modifying, then use operator==. There are far more properties we don't
1275 // support modifying than those we do, and more could be added.
1276 RTCConfiguration modified_config = configuration_;
1277 modified_config.servers = configuration.servers;
1278 modified_config.type = configuration.type;
1279 modified_config.ice_candidate_pool_size =
1280 configuration.ice_candidate_pool_size;
1281 modified_config.prune_turn_ports = configuration.prune_turn_ports;
1282 modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy;
1283 modified_config.surface_ice_candidates_on_ice_transport_type_changed =
1284 configuration.surface_ice_candidates_on_ice_transport_type_changed;
1285 modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
1286 modified_config.ice_check_interval_strong_connectivity =
1287 configuration.ice_check_interval_strong_connectivity;
1288 modified_config.ice_check_interval_weak_connectivity =
1289 configuration.ice_check_interval_weak_connectivity;
1290 modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
1291 modified_config.ice_unwritable_min_checks =
1292 configuration.ice_unwritable_min_checks;
1293 modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
1294 modified_config.stun_candidate_keepalive_interval =
1295 configuration.stun_candidate_keepalive_interval;
1296 modified_config.turn_customizer = configuration.turn_customizer;
1297 modified_config.network_preference = configuration.network_preference;
1298 modified_config.active_reset_srtp_params =
1299 configuration.active_reset_srtp_params;
1300 modified_config.turn_logging_id = configuration.turn_logging_id;
1301 modified_config.allow_codec_switching = configuration.allow_codec_switching;
1302 if (configuration != modified_config) {
1303 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1304 "Modifying the configuration in an unsupported way.");
1305 }
1306
1307 // Validate the modified configuration.
1308 RTCError validate_error = ValidateConfiguration(modified_config);
1309 if (!validate_error.ok()) {
1310 return validate_error;
1311 }
1312
1313 // Note that this isn't possible through chromium, since it's an unsigned
1314 // short in WebIDL.
1315 if (configuration.ice_candidate_pool_size < 0 ||
1316 configuration.ice_candidate_pool_size > static_cast<int>(UINT16_MAX)) {
1317 return RTCError(RTCErrorType::INVALID_RANGE);
1318 }
1319
1320 // Parse ICE servers before hopping to network thread.
1321 cricket::ServerAddresses stun_servers;
1322 std::vector<cricket::RelayServerConfig> turn_servers;
1323 RTCErrorType parse_error =
1324 ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
1325 if (parse_error != RTCErrorType::NONE) {
1326 return RTCError(parse_error);
1327 }
1328 // Add the turn logging id to all turn servers
1329 for (cricket::RelayServerConfig& turn_server : turn_servers) {
1330 turn_server.turn_logging_id = configuration.turn_logging_id;
1331 }
1332
1333 // Note if STUN or TURN servers were supplied.
1334 if (!stun_servers.empty()) {
1335 NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
1336 }
1337 if (!turn_servers.empty()) {
1338 NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
1339 }
1340
1341 // In theory this shouldn't fail.
1342 if (!network_thread()->Invoke<bool>(
1343 RTC_FROM_HERE,
1344 rtc::Bind(&PeerConnection::ReconfigurePortAllocator_n, this,
1345 stun_servers, turn_servers, modified_config.type,
1346 modified_config.ice_candidate_pool_size,
1347 modified_config.GetTurnPortPrunePolicy(),
1348 modified_config.turn_customizer,
1349 modified_config.stun_candidate_keepalive_interval,
1350 static_cast<bool>(local_description())))) {
1351 LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
1352 "Failed to apply configuration to PortAllocator.");
1353 }
1354
1355 // As described in JSEP, calling setConfiguration with new ICE servers or
1356 // candidate policy must set a "needs-ice-restart" bit so that the next offer
1357 // triggers an ICE restart which will pick up the changes.
1358 if (modified_config.servers != configuration_.servers ||
1359 NeedIceRestart(
1360 configuration_.surface_ice_candidates_on_ice_transport_type_changed,
1361 configuration_.type, modified_config.type) ||
1362 modified_config.GetTurnPortPrunePolicy() !=
1363 configuration_.GetTurnPortPrunePolicy()) {
1364 transport_controller_->SetNeedsIceRestartFlag();
1365 }
1366
1367 transport_controller_->SetIceConfig(ParseIceConfig(modified_config));
1368
1369 if (configuration_.active_reset_srtp_params !=
1370 modified_config.active_reset_srtp_params) {
1371 transport_controller_->SetActiveResetSrtpParams(
1372 modified_config.active_reset_srtp_params);
1373 }
1374
1375 if (modified_config.allow_codec_switching.has_value()) {
1376 std::vector<cricket::VideoMediaChannel*> channels;
1377 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1378 if (transceiver->media_type() != cricket::MEDIA_TYPE_VIDEO)
1379 continue;
1380
1381 auto* video_channel = static_cast<cricket::VideoChannel*>(
1382 transceiver->internal()->channel());
1383 if (video_channel)
1384 channels.push_back(video_channel->media_channel());
1385 }
1386
1387 worker_thread()->Invoke<void>(
1388 RTC_FROM_HERE,
1389 [channels = std::move(channels),
1390 allow_codec_switching = *modified_config.allow_codec_switching]() {
1391 for (auto* ch : channels)
1392 ch->SetVideoCodecSwitchingEnabled(allow_codec_switching);
1393 });
1394 }
1395
1396 configuration_ = modified_config;
1397 return RTCError::OK();
1398 }
1399
AddIceCandidate(const IceCandidateInterface * ice_candidate)1400 bool PeerConnection::AddIceCandidate(
1401 const IceCandidateInterface* ice_candidate) {
1402 RTC_DCHECK_RUN_ON(signaling_thread());
1403 return sdp_handler_->AddIceCandidate(ice_candidate);
1404 }
1405
AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate,std::function<void (RTCError)> callback)1406 void PeerConnection::AddIceCandidate(
1407 std::unique_ptr<IceCandidateInterface> candidate,
1408 std::function<void(RTCError)> callback) {
1409 RTC_DCHECK_RUN_ON(signaling_thread());
1410 sdp_handler_->AddIceCandidate(std::move(candidate), callback);
1411 }
1412
RemoveIceCandidates(const std::vector<cricket::Candidate> & candidates)1413 bool PeerConnection::RemoveIceCandidates(
1414 const std::vector<cricket::Candidate>& candidates) {
1415 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
1416 RTC_DCHECK_RUN_ON(signaling_thread());
1417 return sdp_handler_->RemoveIceCandidates(candidates);
1418 }
1419
SetBitrate(const BitrateSettings & bitrate)1420 RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
1421 if (!worker_thread()->IsCurrent()) {
1422 return worker_thread()->Invoke<RTCError>(
1423 RTC_FROM_HERE, [&]() { return SetBitrate(bitrate); });
1424 }
1425 RTC_DCHECK_RUN_ON(worker_thread());
1426
1427 const bool has_min = bitrate.min_bitrate_bps.has_value();
1428 const bool has_start = bitrate.start_bitrate_bps.has_value();
1429 const bool has_max = bitrate.max_bitrate_bps.has_value();
1430 if (has_min && *bitrate.min_bitrate_bps < 0) {
1431 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1432 "min_bitrate_bps <= 0");
1433 }
1434 if (has_start) {
1435 if (has_min && *bitrate.start_bitrate_bps < *bitrate.min_bitrate_bps) {
1436 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1437 "start_bitrate_bps < min_bitrate_bps");
1438 } else if (*bitrate.start_bitrate_bps < 0) {
1439 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1440 "curent_bitrate_bps < 0");
1441 }
1442 }
1443 if (has_max) {
1444 if (has_start && *bitrate.max_bitrate_bps < *bitrate.start_bitrate_bps) {
1445 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1446 "max_bitrate_bps < start_bitrate_bps");
1447 } else if (has_min && *bitrate.max_bitrate_bps < *bitrate.min_bitrate_bps) {
1448 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1449 "max_bitrate_bps < min_bitrate_bps");
1450 } else if (*bitrate.max_bitrate_bps < 0) {
1451 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1452 "max_bitrate_bps < 0");
1453 }
1454 }
1455
1456 RTC_DCHECK(call_.get());
1457 call_->SetClientBitratePreferences(bitrate);
1458
1459 return RTCError::OK();
1460 }
1461
SetAudioPlayout(bool playout)1462 void PeerConnection::SetAudioPlayout(bool playout) {
1463 if (!worker_thread()->IsCurrent()) {
1464 worker_thread()->Invoke<void>(
1465 RTC_FROM_HERE,
1466 rtc::Bind(&PeerConnection::SetAudioPlayout, this, playout));
1467 return;
1468 }
1469 auto audio_state =
1470 context_->channel_manager()->media_engine()->voice().GetAudioState();
1471 audio_state->SetPlayout(playout);
1472 }
1473
SetAudioRecording(bool recording)1474 void PeerConnection::SetAudioRecording(bool recording) {
1475 if (!worker_thread()->IsCurrent()) {
1476 worker_thread()->Invoke<void>(
1477 RTC_FROM_HERE,
1478 rtc::Bind(&PeerConnection::SetAudioRecording, this, recording));
1479 return;
1480 }
1481 auto audio_state =
1482 context_->channel_manager()->media_engine()->voice().GetAudioState();
1483 audio_state->SetRecording(recording);
1484 }
1485
AddAdaptationResource(rtc::scoped_refptr<Resource> resource)1486 void PeerConnection::AddAdaptationResource(
1487 rtc::scoped_refptr<Resource> resource) {
1488 if (!worker_thread()->IsCurrent()) {
1489 return worker_thread()->Invoke<void>(RTC_FROM_HERE, [this, resource]() {
1490 return AddAdaptationResource(resource);
1491 });
1492 }
1493 RTC_DCHECK_RUN_ON(worker_thread());
1494 if (!call_) {
1495 // The PeerConnection has been closed.
1496 return;
1497 }
1498 call_->AddAdaptationResource(resource);
1499 }
1500
StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,int64_t output_period_ms)1501 bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
1502 int64_t output_period_ms) {
1503 return worker_thread()->Invoke<bool>(
1504 RTC_FROM_HERE,
1505 [this, output = std::move(output), output_period_ms]() mutable {
1506 return StartRtcEventLog_w(std::move(output), output_period_ms);
1507 });
1508 }
1509
StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output)1510 bool PeerConnection::StartRtcEventLog(
1511 std::unique_ptr<RtcEventLogOutput> output) {
1512 int64_t output_period_ms = webrtc::RtcEventLog::kImmediateOutput;
1513 if (absl::StartsWith(context_->trials().Lookup("WebRTC-RtcEventLogNewFormat"),
1514 "Enabled")) {
1515 output_period_ms = 5000;
1516 }
1517 return StartRtcEventLog(std::move(output), output_period_ms);
1518 }
1519
StopRtcEventLog()1520 void PeerConnection::StopRtcEventLog() {
1521 worker_thread()->Invoke<void>(
1522 RTC_FROM_HERE, rtc::Bind(&PeerConnection::StopRtcEventLog_w, this));
1523 }
1524
1525 rtc::scoped_refptr<DtlsTransportInterface>
LookupDtlsTransportByMid(const std::string & mid)1526 PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
1527 RTC_DCHECK_RUN_ON(signaling_thread());
1528 return transport_controller_->LookupDtlsTransportByMid(mid);
1529 }
1530
1531 rtc::scoped_refptr<DtlsTransport>
LookupDtlsTransportByMidInternal(const std::string & mid)1532 PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
1533 RTC_DCHECK_RUN_ON(signaling_thread());
1534 return transport_controller_->LookupDtlsTransportByMid(mid);
1535 }
1536
GetSctpTransport() const1537 rtc::scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport()
1538 const {
1539 RTC_DCHECK_RUN_ON(signaling_thread());
1540 if (!sctp_mid_s_) {
1541 return nullptr;
1542 }
1543 return transport_controller_->GetSctpTransport(*sctp_mid_s_);
1544 }
1545
local_description() const1546 const SessionDescriptionInterface* PeerConnection::local_description() const {
1547 RTC_DCHECK_RUN_ON(signaling_thread());
1548 return sdp_handler_->local_description();
1549 }
1550
remote_description() const1551 const SessionDescriptionInterface* PeerConnection::remote_description() const {
1552 RTC_DCHECK_RUN_ON(signaling_thread());
1553 return sdp_handler_->remote_description();
1554 }
1555
current_local_description() const1556 const SessionDescriptionInterface* PeerConnection::current_local_description()
1557 const {
1558 RTC_DCHECK_RUN_ON(signaling_thread());
1559 return sdp_handler_->current_local_description();
1560 }
1561
current_remote_description() const1562 const SessionDescriptionInterface* PeerConnection::current_remote_description()
1563 const {
1564 RTC_DCHECK_RUN_ON(signaling_thread());
1565 return sdp_handler_->current_remote_description();
1566 }
1567
pending_local_description() const1568 const SessionDescriptionInterface* PeerConnection::pending_local_description()
1569 const {
1570 RTC_DCHECK_RUN_ON(signaling_thread());
1571 return sdp_handler_->pending_local_description();
1572 }
1573
pending_remote_description() const1574 const SessionDescriptionInterface* PeerConnection::pending_remote_description()
1575 const {
1576 RTC_DCHECK_RUN_ON(signaling_thread());
1577 return sdp_handler_->pending_remote_description();
1578 }
1579
Close()1580 void PeerConnection::Close() {
1581 RTC_DCHECK_RUN_ON(signaling_thread());
1582 TRACE_EVENT0("webrtc", "PeerConnection::Close");
1583
1584 if (IsClosed()) {
1585 return;
1586 }
1587 // Update stats here so that we have the most recent stats for tracks and
1588 // streams before the channels are closed.
1589 stats_->UpdateStats(kStatsOutputLevelStandard);
1590
1591 ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed;
1592 Observer()->OnIceConnectionChange(ice_connection_state_);
1593 standardized_ice_connection_state_ =
1594 PeerConnectionInterface::IceConnectionState::kIceConnectionClosed;
1595 connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
1596 Observer()->OnConnectionChange(connection_state_);
1597
1598 sdp_handler_->Close();
1599
1600 NoteUsageEvent(UsageEvent::CLOSE_CALLED);
1601
1602 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1603 transceiver->internal()->SetPeerConnectionClosed();
1604 if (!transceiver->stopped())
1605 transceiver->StopInternal();
1606 }
1607
1608 // Ensure that all asynchronous stats requests are completed before destroying
1609 // the transport controller below.
1610 if (stats_collector_) {
1611 stats_collector_->WaitForPendingRequest();
1612 }
1613
1614 // Don't destroy BaseChannels until after stats has been cleaned up so that
1615 // the last stats request can still read from the channels.
1616 sdp_handler_->DestroyAllChannels();
1617
1618 // The event log is used in the transport controller, which must be outlived
1619 // by the former. CreateOffer by the peer connection is implemented
1620 // asynchronously and if the peer connection is closed without resetting the
1621 // WebRTC session description factory, the session description factory would
1622 // call the transport controller.
1623 sdp_handler_->ResetSessionDescFactory();
1624 transport_controller_.reset();
1625 rtp_manager_->Close();
1626
1627 network_thread()->Invoke<void>(
1628 RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::DiscardCandidatePool,
1629 port_allocator_.get()));
1630
1631 worker_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1632 RTC_DCHECK_RUN_ON(worker_thread());
1633 call_safety_.reset();
1634 call_.reset();
1635 // The event log must outlive call (and any other object that uses it).
1636 event_log_.reset();
1637 });
1638 ReportUsagePattern();
1639 // The .h file says that observer can be discarded after close() returns.
1640 // Make sure this is true.
1641 observer_ = nullptr;
1642 }
1643
SetIceConnectionState(IceConnectionState new_state)1644 void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
1645 RTC_DCHECK_RUN_ON(signaling_thread());
1646 if (ice_connection_state_ == new_state) {
1647 return;
1648 }
1649
1650 // After transitioning to "closed", ignore any additional states from
1651 // TransportController (such as "disconnected").
1652 if (IsClosed()) {
1653 return;
1654 }
1655
1656 RTC_LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1657 << " => " << new_state;
1658 RTC_DCHECK(ice_connection_state_ !=
1659 PeerConnectionInterface::kIceConnectionClosed);
1660
1661 ice_connection_state_ = new_state;
1662 Observer()->OnIceConnectionChange(ice_connection_state_);
1663 }
1664
SetStandardizedIceConnectionState(PeerConnectionInterface::IceConnectionState new_state)1665 void PeerConnection::SetStandardizedIceConnectionState(
1666 PeerConnectionInterface::IceConnectionState new_state) {
1667 if (standardized_ice_connection_state_ == new_state) {
1668 return;
1669 }
1670
1671 if (IsClosed()) {
1672 return;
1673 }
1674
1675 RTC_LOG(LS_INFO) << "Changing standardized IceConnectionState "
1676 << standardized_ice_connection_state_ << " => " << new_state;
1677
1678 standardized_ice_connection_state_ = new_state;
1679 Observer()->OnStandardizedIceConnectionChange(new_state);
1680 }
1681
SetConnectionState(PeerConnectionInterface::PeerConnectionState new_state)1682 void PeerConnection::SetConnectionState(
1683 PeerConnectionInterface::PeerConnectionState new_state) {
1684 if (connection_state_ == new_state)
1685 return;
1686 if (IsClosed())
1687 return;
1688 connection_state_ = new_state;
1689 Observer()->OnConnectionChange(new_state);
1690 }
1691
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)1692 void PeerConnection::OnIceGatheringChange(
1693 PeerConnectionInterface::IceGatheringState new_state) {
1694 if (IsClosed()) {
1695 return;
1696 }
1697 ice_gathering_state_ = new_state;
1698 Observer()->OnIceGatheringChange(ice_gathering_state_);
1699 }
1700
OnIceCandidate(std::unique_ptr<IceCandidateInterface> candidate)1701 void PeerConnection::OnIceCandidate(
1702 std::unique_ptr<IceCandidateInterface> candidate) {
1703 if (IsClosed()) {
1704 return;
1705 }
1706 ReportIceCandidateCollected(candidate->candidate());
1707 Observer()->OnIceCandidate(candidate.get());
1708 }
1709
OnIceCandidateError(const std::string & address,int port,const std::string & url,int error_code,const std::string & error_text)1710 void PeerConnection::OnIceCandidateError(const std::string& address,
1711 int port,
1712 const std::string& url,
1713 int error_code,
1714 const std::string& error_text) {
1715 if (IsClosed()) {
1716 return;
1717 }
1718 Observer()->OnIceCandidateError(address, port, url, error_code, error_text);
1719 // Leftover not to break wpt test during migration to the new API.
1720 Observer()->OnIceCandidateError(address + ":", url, error_code, error_text);
1721 }
1722
OnIceCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)1723 void PeerConnection::OnIceCandidatesRemoved(
1724 const std::vector<cricket::Candidate>& candidates) {
1725 if (IsClosed()) {
1726 return;
1727 }
1728 Observer()->OnIceCandidatesRemoved(candidates);
1729 }
1730
OnSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent & event)1731 void PeerConnection::OnSelectedCandidatePairChanged(
1732 const cricket::CandidatePairChangeEvent& event) {
1733 if (IsClosed()) {
1734 return;
1735 }
1736
1737 if (event.selected_candidate_pair.local_candidate().type() ==
1738 LOCAL_PORT_TYPE &&
1739 event.selected_candidate_pair.remote_candidate().type() ==
1740 LOCAL_PORT_TYPE) {
1741 NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
1742 }
1743
1744 Observer()->OnIceSelectedCandidatePairChanged(event);
1745 }
1746
GetDataMid() const1747 absl::optional<std::string> PeerConnection::GetDataMid() const {
1748 RTC_DCHECK_RUN_ON(signaling_thread());
1749 switch (data_channel_type()) {
1750 case cricket::DCT_RTP:
1751 if (!data_channel_controller_.rtp_data_channel()) {
1752 return absl::nullopt;
1753 }
1754 return data_channel_controller_.rtp_data_channel()->content_name();
1755 case cricket::DCT_SCTP:
1756 return sctp_mid_s_;
1757 default:
1758 return absl::nullopt;
1759 }
1760 }
1761
OnSctpDataChannelClosed(DataChannelInterface * channel)1762 void PeerConnection::OnSctpDataChannelClosed(DataChannelInterface* channel) {
1763 // Since data_channel_controller doesn't do signals, this
1764 // signal is relayed here.
1765 data_channel_controller_.OnSctpDataChannelClosed(
1766 static_cast<SctpDataChannel*>(channel));
1767 }
1768
FindDataChannelBySid(int sid) const1769 SctpDataChannel* PeerConnection::FindDataChannelBySid(int sid) const {
1770 return data_channel_controller_.FindDataChannelBySid(sid);
1771 }
1772
1773 PeerConnection::InitializePortAllocatorResult
InitializePortAllocator_n(const cricket::ServerAddresses & stun_servers,const std::vector<cricket::RelayServerConfig> & turn_servers,const RTCConfiguration & configuration)1774 PeerConnection::InitializePortAllocator_n(
1775 const cricket::ServerAddresses& stun_servers,
1776 const std::vector<cricket::RelayServerConfig>& turn_servers,
1777 const RTCConfiguration& configuration) {
1778 RTC_DCHECK_RUN_ON(network_thread());
1779
1780 port_allocator_->Initialize();
1781 // To handle both internal and externally created port allocator, we will
1782 // enable BUNDLE here.
1783 int port_allocator_flags = port_allocator_->flags();
1784 port_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
1785 cricket::PORTALLOCATOR_ENABLE_IPV6 |
1786 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI;
1787 // If the disable-IPv6 flag was specified, we'll not override it
1788 // by experiment.
1789 if (configuration.disable_ipv6) {
1790 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
1791 } else if (absl::StartsWith(context_->trials().Lookup("WebRTC-IPv6Default"),
1792 "Disabled")) {
1793 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
1794 }
1795 if (configuration.disable_ipv6_on_wifi) {
1796 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1797 RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled.";
1798 }
1799
1800 if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
1801 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
1802 RTC_LOG(LS_INFO) << "TCP candidates are disabled.";
1803 }
1804
1805 if (configuration.candidate_network_policy ==
1806 kCandidateNetworkPolicyLowCost) {
1807 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
1808 RTC_LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
1809 }
1810
1811 if (configuration.disable_link_local_networks) {
1812 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS;
1813 RTC_LOG(LS_INFO) << "Disable candidates on link-local network interfaces.";
1814 }
1815
1816 port_allocator_->set_flags(port_allocator_flags);
1817 // No step delay is used while allocating ports.
1818 port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
1819 port_allocator_->SetCandidateFilter(
1820 ConvertIceTransportTypeToCandidateFilter(configuration.type));
1821 port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);
1822
1823 auto turn_servers_copy = turn_servers;
1824 for (auto& turn_server : turn_servers_copy) {
1825 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
1826 }
1827 // Call this last since it may create pooled allocator sessions using the
1828 // properties set above.
1829 port_allocator_->SetConfiguration(
1830 stun_servers, std::move(turn_servers_copy),
1831 configuration.ice_candidate_pool_size,
1832 configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer,
1833 configuration.stun_candidate_keepalive_interval);
1834
1835 InitializePortAllocatorResult res;
1836 res.enable_ipv6 = port_allocator_flags & cricket::PORTALLOCATOR_ENABLE_IPV6;
1837 return res;
1838 }
1839
ReconfigurePortAllocator_n(const cricket::ServerAddresses & stun_servers,const std::vector<cricket::RelayServerConfig> & turn_servers,IceTransportsType type,int candidate_pool_size,PortPrunePolicy turn_port_prune_policy,webrtc::TurnCustomizer * turn_customizer,absl::optional<int> stun_candidate_keepalive_interval,bool have_local_description)1840 bool PeerConnection::ReconfigurePortAllocator_n(
1841 const cricket::ServerAddresses& stun_servers,
1842 const std::vector<cricket::RelayServerConfig>& turn_servers,
1843 IceTransportsType type,
1844 int candidate_pool_size,
1845 PortPrunePolicy turn_port_prune_policy,
1846 webrtc::TurnCustomizer* turn_customizer,
1847 absl::optional<int> stun_candidate_keepalive_interval,
1848 bool have_local_description) {
1849 RTC_DCHECK_RUN_ON(network_thread());
1850 port_allocator_->SetCandidateFilter(
1851 ConvertIceTransportTypeToCandidateFilter(type));
1852 // According to JSEP, after setLocalDescription, changing the candidate pool
1853 // size is not allowed, and changing the set of ICE servers will not result
1854 // in new candidates being gathered.
1855 if (have_local_description) {
1856 port_allocator_->FreezeCandidatePool();
1857 }
1858 // Add the custom tls turn servers if they exist.
1859 auto turn_servers_copy = turn_servers;
1860 for (auto& turn_server : turn_servers_copy) {
1861 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
1862 }
1863 // Call this last since it may create pooled allocator sessions using the
1864 // candidate filter set above.
1865 return port_allocator_->SetConfiguration(
1866 stun_servers, std::move(turn_servers_copy), candidate_pool_size,
1867 turn_port_prune_policy, turn_customizer,
1868 stun_candidate_keepalive_interval);
1869 }
1870
channel_manager() const1871 cricket::ChannelManager* PeerConnection::channel_manager() const {
1872 return context_->channel_manager();
1873 }
1874
StartRtcEventLog_w(std::unique_ptr<RtcEventLogOutput> output,int64_t output_period_ms)1875 bool PeerConnection::StartRtcEventLog_w(
1876 std::unique_ptr<RtcEventLogOutput> output,
1877 int64_t output_period_ms) {
1878 RTC_DCHECK_RUN_ON(worker_thread());
1879 if (!event_log_) {
1880 return false;
1881 }
1882 return event_log_->StartLogging(std::move(output), output_period_ms);
1883 }
1884
StopRtcEventLog_w()1885 void PeerConnection::StopRtcEventLog_w() {
1886 RTC_DCHECK_RUN_ON(worker_thread());
1887 if (event_log_) {
1888 event_log_->StopLogging();
1889 }
1890 }
1891
GetChannel(const std::string & content_name)1892 cricket::ChannelInterface* PeerConnection::GetChannel(
1893 const std::string& content_name) {
1894 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1895 cricket::ChannelInterface* channel = transceiver->internal()->channel();
1896 if (channel && channel->content_name() == content_name) {
1897 return channel;
1898 }
1899 }
1900 if (rtp_data_channel() &&
1901 rtp_data_channel()->content_name() == content_name) {
1902 return rtp_data_channel();
1903 }
1904 return nullptr;
1905 }
1906
GetSctpSslRole(rtc::SSLRole * role)1907 bool PeerConnection::GetSctpSslRole(rtc::SSLRole* role) {
1908 RTC_DCHECK_RUN_ON(signaling_thread());
1909 if (!local_description() || !remote_description()) {
1910 RTC_LOG(LS_VERBOSE)
1911 << "Local and Remote descriptions must be applied to get the "
1912 "SSL Role of the SCTP transport.";
1913 return false;
1914 }
1915 if (!data_channel_controller_.data_channel_transport()) {
1916 RTC_LOG(LS_INFO) << "Non-rejected SCTP m= section is needed to get the "
1917 "SSL Role of the SCTP transport.";
1918 return false;
1919 }
1920
1921 absl::optional<rtc::SSLRole> dtls_role;
1922 if (sctp_mid_s_) {
1923 dtls_role = transport_controller_->GetDtlsRole(*sctp_mid_s_);
1924 if (!dtls_role && sdp_handler_->is_caller().has_value()) {
1925 dtls_role =
1926 *sdp_handler_->is_caller() ? rtc::SSL_SERVER : rtc::SSL_CLIENT;
1927 }
1928 *role = *dtls_role;
1929 return true;
1930 }
1931 return false;
1932 }
1933
GetSslRole(const std::string & content_name,rtc::SSLRole * role)1934 bool PeerConnection::GetSslRole(const std::string& content_name,
1935 rtc::SSLRole* role) {
1936 RTC_DCHECK_RUN_ON(signaling_thread());
1937 if (!local_description() || !remote_description()) {
1938 RTC_LOG(LS_INFO)
1939 << "Local and Remote descriptions must be applied to get the "
1940 "SSL Role of the session.";
1941 return false;
1942 }
1943
1944 auto dtls_role = transport_controller_->GetDtlsRole(content_name);
1945 if (dtls_role) {
1946 *role = *dtls_role;
1947 return true;
1948 }
1949 return false;
1950 }
1951
GetTransportDescription(const SessionDescription * description,const std::string & content_name,cricket::TransportDescription * tdesc)1952 bool PeerConnection::GetTransportDescription(
1953 const SessionDescription* description,
1954 const std::string& content_name,
1955 cricket::TransportDescription* tdesc) {
1956 if (!description || !tdesc) {
1957 return false;
1958 }
1959 const TransportInfo* transport_info =
1960 description->GetTransportInfoByName(content_name);
1961 if (!transport_info) {
1962 return false;
1963 }
1964 *tdesc = transport_info->description;
1965 return true;
1966 }
1967
GetDataChannelStats() const1968 std::vector<DataChannelStats> PeerConnection::GetDataChannelStats() const {
1969 RTC_DCHECK_RUN_ON(signaling_thread());
1970 return data_channel_controller_.GetDataChannelStats();
1971 }
1972
sctp_transport_name() const1973 absl::optional<std::string> PeerConnection::sctp_transport_name() const {
1974 RTC_DCHECK_RUN_ON(signaling_thread());
1975 if (sctp_mid_s_ && transport_controller_) {
1976 auto dtls_transport = transport_controller_->GetDtlsTransport(*sctp_mid_s_);
1977 if (dtls_transport) {
1978 return dtls_transport->transport_name();
1979 }
1980 return absl::optional<std::string>();
1981 }
1982 return absl::optional<std::string>();
1983 }
1984
GetPooledCandidateStats() const1985 cricket::CandidateStatsList PeerConnection::GetPooledCandidateStats() const {
1986 cricket::CandidateStatsList candidate_states_list;
1987 network_thread()->Invoke<void>(
1988 RTC_FROM_HERE,
1989 rtc::Bind(&cricket::PortAllocator::GetCandidateStatsFromPooledSessions,
1990 port_allocator_.get(), &candidate_states_list));
1991 return candidate_states_list;
1992 }
1993
GetTransportNamesByMid() const1994 std::map<std::string, std::string> PeerConnection::GetTransportNamesByMid()
1995 const {
1996 RTC_DCHECK_RUN_ON(signaling_thread());
1997 std::map<std::string, std::string> transport_names_by_mid;
1998 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1999 cricket::ChannelInterface* channel = transceiver->internal()->channel();
2000 if (channel) {
2001 transport_names_by_mid[channel->content_name()] =
2002 channel->transport_name();
2003 }
2004 }
2005 if (data_channel_controller_.rtp_data_channel()) {
2006 transport_names_by_mid[data_channel_controller_.rtp_data_channel()
2007 ->content_name()] =
2008 data_channel_controller_.rtp_data_channel()->transport_name();
2009 }
2010 if (data_channel_controller_.data_channel_transport()) {
2011 absl::optional<std::string> transport_name = sctp_transport_name();
2012 RTC_DCHECK(transport_name);
2013 transport_names_by_mid[*sctp_mid_s_] = *transport_name;
2014 }
2015 return transport_names_by_mid;
2016 }
2017
2018 std::map<std::string, cricket::TransportStats>
GetTransportStatsByNames(const std::set<std::string> & transport_names)2019 PeerConnection::GetTransportStatsByNames(
2020 const std::set<std::string>& transport_names) {
2021 if (!network_thread()->IsCurrent()) {
2022 return network_thread()
2023 ->Invoke<std::map<std::string, cricket::TransportStats>>(
2024 RTC_FROM_HERE,
2025 [&] { return GetTransportStatsByNames(transport_names); });
2026 }
2027 RTC_DCHECK_RUN_ON(network_thread());
2028 std::map<std::string, cricket::TransportStats> transport_stats_by_name;
2029 for (const std::string& transport_name : transport_names) {
2030 cricket::TransportStats transport_stats;
2031 bool success =
2032 transport_controller_->GetStats(transport_name, &transport_stats);
2033 if (success) {
2034 transport_stats_by_name[transport_name] = std::move(transport_stats);
2035 } else {
2036 RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
2037 << transport_name;
2038 }
2039 }
2040 return transport_stats_by_name;
2041 }
2042
GetLocalCertificate(const std::string & transport_name,rtc::scoped_refptr<rtc::RTCCertificate> * certificate)2043 bool PeerConnection::GetLocalCertificate(
2044 const std::string& transport_name,
2045 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
2046 if (!certificate) {
2047 return false;
2048 }
2049 *certificate = transport_controller_->GetLocalCertificate(transport_name);
2050 return *certificate != nullptr;
2051 }
2052
GetRemoteSSLCertChain(const std::string & transport_name)2053 std::unique_ptr<rtc::SSLCertChain> PeerConnection::GetRemoteSSLCertChain(
2054 const std::string& transport_name) {
2055 return transport_controller_->GetRemoteSSLCertChain(transport_name);
2056 }
2057
data_channel_type() const2058 cricket::DataChannelType PeerConnection::data_channel_type() const {
2059 return data_channel_controller_.data_channel_type();
2060 }
2061
IceRestartPending(const std::string & content_name) const2062 bool PeerConnection::IceRestartPending(const std::string& content_name) const {
2063 RTC_DCHECK_RUN_ON(signaling_thread());
2064 return sdp_handler_->IceRestartPending(content_name);
2065 }
2066
NeedsIceRestart(const std::string & content_name) const2067 bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
2068 return transport_controller_->NeedsIceRestart(content_name);
2069 }
2070
OnTransportControllerConnectionState(cricket::IceConnectionState state)2071 void PeerConnection::OnTransportControllerConnectionState(
2072 cricket::IceConnectionState state) {
2073 switch (state) {
2074 case cricket::kIceConnectionConnecting:
2075 // If the current state is Connected or Completed, then there were
2076 // writable channels but now there are not, so the next state must
2077 // be Disconnected.
2078 // kIceConnectionConnecting is currently used as the default,
2079 // un-connected state by the TransportController, so its only use is
2080 // detecting disconnections.
2081 if (ice_connection_state_ ==
2082 PeerConnectionInterface::kIceConnectionConnected ||
2083 ice_connection_state_ ==
2084 PeerConnectionInterface::kIceConnectionCompleted) {
2085 SetIceConnectionState(
2086 PeerConnectionInterface::kIceConnectionDisconnected);
2087 }
2088 break;
2089 case cricket::kIceConnectionFailed:
2090 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
2091 break;
2092 case cricket::kIceConnectionConnected:
2093 RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
2094 "all transports are writable.";
2095 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2096 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2097 break;
2098 case cricket::kIceConnectionCompleted:
2099 RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
2100 "all transports are complete.";
2101 if (ice_connection_state_ !=
2102 PeerConnectionInterface::kIceConnectionConnected) {
2103 // If jumping directly from "checking" to "connected",
2104 // signal "connected" first.
2105 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2106 }
2107 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
2108 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2109 ReportTransportStats();
2110 break;
2111 default:
2112 RTC_NOTREACHED();
2113 }
2114 }
2115
OnTransportControllerCandidatesGathered(const std::string & transport_name,const cricket::Candidates & candidates)2116 void PeerConnection::OnTransportControllerCandidatesGathered(
2117 const std::string& transport_name,
2118 const cricket::Candidates& candidates) {
2119 int sdp_mline_index;
2120 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
2121 RTC_LOG(LS_ERROR)
2122 << "OnTransportControllerCandidatesGathered: content name "
2123 << transport_name << " not found";
2124 return;
2125 }
2126
2127 for (cricket::Candidates::const_iterator citer = candidates.begin();
2128 citer != candidates.end(); ++citer) {
2129 // Use transport_name as the candidate media id.
2130 std::unique_ptr<JsepIceCandidate> candidate(
2131 new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
2132 sdp_handler_->AddLocalIceCandidate(candidate.get());
2133 OnIceCandidate(std::move(candidate));
2134 }
2135 }
2136
OnTransportControllerCandidateError(const cricket::IceCandidateErrorEvent & event)2137 void PeerConnection::OnTransportControllerCandidateError(
2138 const cricket::IceCandidateErrorEvent& event) {
2139 OnIceCandidateError(event.address, event.port, event.url, event.error_code,
2140 event.error_text);
2141 }
2142
OnTransportControllerCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)2143 void PeerConnection::OnTransportControllerCandidatesRemoved(
2144 const std::vector<cricket::Candidate>& candidates) {
2145 // Sanity check.
2146 for (const cricket::Candidate& candidate : candidates) {
2147 if (candidate.transport_name().empty()) {
2148 RTC_LOG(LS_ERROR) << "OnTransportControllerCandidatesRemoved: "
2149 "empty content name in candidate "
2150 << candidate.ToString();
2151 return;
2152 }
2153 }
2154 sdp_handler_->RemoveLocalIceCandidates(candidates);
2155 OnIceCandidatesRemoved(candidates);
2156 }
2157
OnTransportControllerCandidateChanged(const cricket::CandidatePairChangeEvent & event)2158 void PeerConnection::OnTransportControllerCandidateChanged(
2159 const cricket::CandidatePairChangeEvent& event) {
2160 OnSelectedCandidatePairChanged(event);
2161 }
2162
OnTransportControllerDtlsHandshakeError(rtc::SSLHandshakeError error)2163 void PeerConnection::OnTransportControllerDtlsHandshakeError(
2164 rtc::SSLHandshakeError error) {
2165 RTC_HISTOGRAM_ENUMERATION(
2166 "WebRTC.PeerConnection.DtlsHandshakeError", static_cast<int>(error),
2167 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
2168 }
2169
2170 // Returns the media index for a local ice candidate given the content name.
GetLocalCandidateMediaIndex(const std::string & content_name,int * sdp_mline_index)2171 bool PeerConnection::GetLocalCandidateMediaIndex(
2172 const std::string& content_name,
2173 int* sdp_mline_index) {
2174 if (!local_description() || !sdp_mline_index) {
2175 return false;
2176 }
2177
2178 bool content_found = false;
2179 const ContentInfos& contents = local_description()->description()->contents();
2180 for (size_t index = 0; index < contents.size(); ++index) {
2181 if (contents[index].name == content_name) {
2182 *sdp_mline_index = static_cast<int>(index);
2183 content_found = true;
2184 break;
2185 }
2186 }
2187 return content_found;
2188 }
2189
GetCallStats()2190 Call::Stats PeerConnection::GetCallStats() {
2191 if (!worker_thread()->IsCurrent()) {
2192 return worker_thread()->Invoke<Call::Stats>(
2193 RTC_FROM_HERE, rtc::Bind(&PeerConnection::GetCallStats, this));
2194 }
2195 RTC_DCHECK_RUN_ON(worker_thread());
2196 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
2197 if (call_) {
2198 return call_->GetStats();
2199 } else {
2200 return Call::Stats();
2201 }
2202 }
2203
SetupDataChannelTransport_n(const std::string & mid)2204 bool PeerConnection::SetupDataChannelTransport_n(const std::string& mid) {
2205 DataChannelTransportInterface* transport =
2206 transport_controller_->GetDataChannelTransport(mid);
2207 if (!transport) {
2208 RTC_LOG(LS_ERROR)
2209 << "Data channel transport is not available for data channels, mid="
2210 << mid;
2211 return false;
2212 }
2213 RTC_LOG(LS_INFO) << "Setting up data channel transport for mid=" << mid;
2214
2215 data_channel_controller_.set_data_channel_transport(transport);
2216 data_channel_controller_.SetupDataChannelTransport_n();
2217 sctp_mid_n_ = mid;
2218
2219 // Note: setting the data sink and checking initial state must be done last,
2220 // after setting up the data channel. Setting the data sink may trigger
2221 // callbacks to PeerConnection which require the transport to be completely
2222 // set up (eg. OnReadyToSend()).
2223 transport->SetDataSink(&data_channel_controller_);
2224 return true;
2225 }
2226
TeardownDataChannelTransport_n()2227 void PeerConnection::TeardownDataChannelTransport_n() {
2228 if (!sctp_mid_n_ && !data_channel_controller_.data_channel_transport()) {
2229 return;
2230 }
2231 RTC_LOG(LS_INFO) << "Tearing down data channel transport for mid="
2232 << *sctp_mid_n_;
2233
2234 // |sctp_mid_| may still be active through an SCTP transport. If not, unset
2235 // it.
2236 sctp_mid_n_.reset();
2237 data_channel_controller_.TeardownDataChannelTransport_n();
2238 }
2239
2240 // Returns false if bundle is enabled and rtcp_mux is disabled.
ValidateBundleSettings(const SessionDescription * desc)2241 bool PeerConnection::ValidateBundleSettings(const SessionDescription* desc) {
2242 bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE);
2243 if (!bundle_enabled)
2244 return true;
2245
2246 const cricket::ContentGroup* bundle_group =
2247 desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
2248 RTC_DCHECK(bundle_group != NULL);
2249
2250 const cricket::ContentInfos& contents = desc->contents();
2251 for (cricket::ContentInfos::const_iterator citer = contents.begin();
2252 citer != contents.end(); ++citer) {
2253 const cricket::ContentInfo* content = (&*citer);
2254 RTC_DCHECK(content != NULL);
2255 if (bundle_group->HasContentName(content->name) && !content->rejected &&
2256 content->type == MediaProtocolType::kRtp) {
2257 if (!HasRtcpMuxEnabled(content))
2258 return false;
2259 }
2260 }
2261 // RTCP-MUX is enabled in all the contents.
2262 return true;
2263 }
2264
ReportSdpFormatReceived(const SessionDescriptionInterface & remote_offer)2265 void PeerConnection::ReportSdpFormatReceived(
2266 const SessionDescriptionInterface& remote_offer) {
2267 int num_audio_mlines = 0;
2268 int num_video_mlines = 0;
2269 int num_audio_tracks = 0;
2270 int num_video_tracks = 0;
2271 for (const ContentInfo& content : remote_offer.description()->contents()) {
2272 cricket::MediaType media_type = content.media_description()->type();
2273 int num_tracks = std::max(
2274 1, static_cast<int>(content.media_description()->streams().size()));
2275 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2276 num_audio_mlines += 1;
2277 num_audio_tracks += num_tracks;
2278 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2279 num_video_mlines += 1;
2280 num_video_tracks += num_tracks;
2281 }
2282 }
2283 SdpFormatReceived format = kSdpFormatReceivedNoTracks;
2284 if (num_audio_mlines > 1 || num_video_mlines > 1) {
2285 format = kSdpFormatReceivedComplexUnifiedPlan;
2286 } else if (num_audio_tracks > 1 || num_video_tracks > 1) {
2287 format = kSdpFormatReceivedComplexPlanB;
2288 } else if (num_audio_tracks > 0 || num_video_tracks > 0) {
2289 format = kSdpFormatReceivedSimple;
2290 }
2291 switch (remote_offer.GetType()) {
2292 case SdpType::kOffer:
2293 // Historically only offers were counted.
2294 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceived",
2295 format, kSdpFormatReceivedMax);
2296 break;
2297 case SdpType::kAnswer:
2298 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceivedAnswer",
2299 format, kSdpFormatReceivedMax);
2300 break;
2301 default:
2302 RTC_LOG(LS_ERROR) << "Can not report SdpFormatReceived for "
2303 << SdpTypeToString(remote_offer.GetType());
2304 break;
2305 }
2306 }
2307
ReportIceCandidateCollected(const cricket::Candidate & candidate)2308 void PeerConnection::ReportIceCandidateCollected(
2309 const cricket::Candidate& candidate) {
2310 NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
2311 if (candidate.address().IsPrivateIP()) {
2312 NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
2313 }
2314 if (candidate.address().IsUnresolvedIP()) {
2315 NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
2316 }
2317 if (candidate.address().family() == AF_INET6) {
2318 NoteUsageEvent(UsageEvent::IPV6_CANDIDATE_COLLECTED);
2319 }
2320 }
2321
NoteUsageEvent(UsageEvent event)2322 void PeerConnection::NoteUsageEvent(UsageEvent event) {
2323 RTC_DCHECK_RUN_ON(signaling_thread());
2324 usage_pattern_.NoteUsageEvent(event);
2325 }
2326
ReportUsagePattern() const2327 void PeerConnection::ReportUsagePattern() const {
2328 usage_pattern_.ReportUsagePattern(observer_);
2329 }
2330
SrtpRequired() const2331 bool PeerConnection::SrtpRequired() const {
2332 return (dtls_enabled_ ||
2333 sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() ==
2334 cricket::SEC_REQUIRED);
2335 }
2336
OnTransportControllerGatheringState(cricket::IceGatheringState state)2337 void PeerConnection::OnTransportControllerGatheringState(
2338 cricket::IceGatheringState state) {
2339 RTC_DCHECK(signaling_thread()->IsCurrent());
2340 if (state == cricket::kIceGatheringGathering) {
2341 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
2342 } else if (state == cricket::kIceGatheringComplete) {
2343 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
2344 } else if (state == cricket::kIceGatheringNew) {
2345 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew);
2346 } else {
2347 RTC_LOG(LS_ERROR) << "Unknown state received: " << state;
2348 RTC_NOTREACHED();
2349 }
2350 }
2351
ReportTransportStats()2352 void PeerConnection::ReportTransportStats() {
2353 std::map<std::string, std::set<cricket::MediaType>>
2354 media_types_by_transport_name;
2355 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
2356 if (transceiver->internal()->channel()) {
2357 const std::string& transport_name =
2358 transceiver->internal()->channel()->transport_name();
2359 media_types_by_transport_name[transport_name].insert(
2360 transceiver->media_type());
2361 }
2362 }
2363 if (rtp_data_channel()) {
2364 media_types_by_transport_name[rtp_data_channel()->transport_name()].insert(
2365 cricket::MEDIA_TYPE_DATA);
2366 }
2367
2368 absl::optional<std::string> transport_name = sctp_transport_name();
2369 if (transport_name) {
2370 media_types_by_transport_name[*transport_name].insert(
2371 cricket::MEDIA_TYPE_DATA);
2372 }
2373
2374 for (const auto& entry : media_types_by_transport_name) {
2375 const std::string& transport_name = entry.first;
2376 const std::set<cricket::MediaType> media_types = entry.second;
2377 cricket::TransportStats stats;
2378 if (transport_controller_->GetStats(transport_name, &stats)) {
2379 ReportBestConnectionState(stats);
2380 ReportNegotiatedCiphers(stats, media_types);
2381 }
2382 }
2383 }
2384 // Walk through the ConnectionInfos to gather best connection usage
2385 // for IPv4 and IPv6.
ReportBestConnectionState(const cricket::TransportStats & stats)2386 void PeerConnection::ReportBestConnectionState(
2387 const cricket::TransportStats& stats) {
2388 for (const cricket::TransportChannelStats& channel_stats :
2389 stats.channel_stats) {
2390 for (const cricket::ConnectionInfo& connection_info :
2391 channel_stats.ice_transport_stats.connection_infos) {
2392 if (!connection_info.best_connection) {
2393 continue;
2394 }
2395
2396 const cricket::Candidate& local = connection_info.local_candidate;
2397 const cricket::Candidate& remote = connection_info.remote_candidate;
2398
2399 // Increment the counter for IceCandidatePairType.
2400 if (local.protocol() == cricket::TCP_PROTOCOL_NAME ||
2401 (local.type() == RELAY_PORT_TYPE &&
2402 local.relay_protocol() == cricket::TCP_PROTOCOL_NAME)) {
2403 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_TCP",
2404 GetIceCandidatePairCounter(local, remote),
2405 kIceCandidatePairMax);
2406 } else if (local.protocol() == cricket::UDP_PROTOCOL_NAME) {
2407 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_UDP",
2408 GetIceCandidatePairCounter(local, remote),
2409 kIceCandidatePairMax);
2410 } else {
2411 RTC_CHECK_NOTREACHED();
2412 }
2413
2414 // Increment the counter for IP type.
2415 if (local.address().family() == AF_INET) {
2416 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2417 kBestConnections_IPv4,
2418 kPeerConnectionAddressFamilyCounter_Max);
2419 } else if (local.address().family() == AF_INET6) {
2420 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2421 kBestConnections_IPv6,
2422 kPeerConnectionAddressFamilyCounter_Max);
2423 } else {
2424 RTC_CHECK(!local.address().hostname().empty() &&
2425 local.address().IsUnresolvedIP());
2426 }
2427
2428 return;
2429 }
2430 }
2431 }
2432
ReportNegotiatedCiphers(const cricket::TransportStats & stats,const std::set<cricket::MediaType> & media_types)2433 void PeerConnection::ReportNegotiatedCiphers(
2434 const cricket::TransportStats& stats,
2435 const std::set<cricket::MediaType>& media_types) {
2436 if (!dtls_enabled_ || stats.channel_stats.empty()) {
2437 return;
2438 }
2439
2440 int srtp_crypto_suite = stats.channel_stats[0].srtp_crypto_suite;
2441 int ssl_cipher_suite = stats.channel_stats[0].ssl_cipher_suite;
2442 if (srtp_crypto_suite == rtc::SRTP_INVALID_CRYPTO_SUITE &&
2443 ssl_cipher_suite == rtc::TLS_NULL_WITH_NULL_NULL) {
2444 return;
2445 }
2446
2447 if (srtp_crypto_suite != rtc::SRTP_INVALID_CRYPTO_SUITE) {
2448 for (cricket::MediaType media_type : media_types) {
2449 switch (media_type) {
2450 case cricket::MEDIA_TYPE_AUDIO:
2451 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2452 "WebRTC.PeerConnection.SrtpCryptoSuite.Audio", srtp_crypto_suite,
2453 rtc::SRTP_CRYPTO_SUITE_MAX_VALUE);
2454 break;
2455 case cricket::MEDIA_TYPE_VIDEO:
2456 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2457 "WebRTC.PeerConnection.SrtpCryptoSuite.Video", srtp_crypto_suite,
2458 rtc::SRTP_CRYPTO_SUITE_MAX_VALUE);
2459 break;
2460 case cricket::MEDIA_TYPE_DATA:
2461 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2462 "WebRTC.PeerConnection.SrtpCryptoSuite.Data", srtp_crypto_suite,
2463 rtc::SRTP_CRYPTO_SUITE_MAX_VALUE);
2464 break;
2465 default:
2466 RTC_NOTREACHED();
2467 continue;
2468 }
2469 }
2470 }
2471
2472 if (ssl_cipher_suite != rtc::TLS_NULL_WITH_NULL_NULL) {
2473 for (cricket::MediaType media_type : media_types) {
2474 switch (media_type) {
2475 case cricket::MEDIA_TYPE_AUDIO:
2476 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2477 "WebRTC.PeerConnection.SslCipherSuite.Audio", ssl_cipher_suite,
2478 rtc::SSL_CIPHER_SUITE_MAX_VALUE);
2479 break;
2480 case cricket::MEDIA_TYPE_VIDEO:
2481 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2482 "WebRTC.PeerConnection.SslCipherSuite.Video", ssl_cipher_suite,
2483 rtc::SSL_CIPHER_SUITE_MAX_VALUE);
2484 break;
2485 case cricket::MEDIA_TYPE_DATA:
2486 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2487 "WebRTC.PeerConnection.SslCipherSuite.Data", ssl_cipher_suite,
2488 rtc::SSL_CIPHER_SUITE_MAX_VALUE);
2489 break;
2490 default:
2491 RTC_NOTREACHED();
2492 continue;
2493 }
2494 }
2495 }
2496 }
2497
OnSentPacket_w(const rtc::SentPacket & sent_packet)2498 void PeerConnection::OnSentPacket_w(const rtc::SentPacket& sent_packet) {
2499 RTC_DCHECK_RUN_ON(worker_thread());
2500 RTC_DCHECK(call_);
2501 call_->OnSentPacket(sent_packet);
2502 }
2503
OnTransportChanged(const std::string & mid,RtpTransportInternal * rtp_transport,rtc::scoped_refptr<DtlsTransport> dtls_transport,DataChannelTransportInterface * data_channel_transport)2504 bool PeerConnection::OnTransportChanged(
2505 const std::string& mid,
2506 RtpTransportInternal* rtp_transport,
2507 rtc::scoped_refptr<DtlsTransport> dtls_transport,
2508 DataChannelTransportInterface* data_channel_transport) {
2509 RTC_DCHECK_RUN_ON(network_thread());
2510 bool ret = true;
2511 auto base_channel = GetChannel(mid);
2512 if (base_channel) {
2513 ret = base_channel->SetRtpTransport(rtp_transport);
2514 }
2515 if (mid == sctp_mid_n_) {
2516 data_channel_controller_.OnTransportChanged(data_channel_transport);
2517 }
2518 return ret;
2519 }
2520
Observer() const2521 PeerConnectionObserver* PeerConnection::Observer() const {
2522 RTC_DCHECK_RUN_ON(signaling_thread());
2523 RTC_DCHECK(observer_);
2524 return observer_;
2525 }
2526
GetCryptoOptions()2527 CryptoOptions PeerConnection::GetCryptoOptions() {
2528 RTC_DCHECK_RUN_ON(signaling_thread());
2529 // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions
2530 // after it has been removed.
2531 return configuration_.crypto_options.has_value()
2532 ? *configuration_.crypto_options
2533 : options_.crypto_options;
2534 }
2535
ClearStatsCache()2536 void PeerConnection::ClearStatsCache() {
2537 RTC_DCHECK_RUN_ON(signaling_thread());
2538 if (stats_collector_) {
2539 stats_collector_->ClearCachedStatsReport();
2540 }
2541 }
2542
ShouldFireNegotiationNeededEvent(uint32_t event_id)2543 bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
2544 RTC_DCHECK_RUN_ON(signaling_thread());
2545 return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
2546 }
2547
RequestUsagePatternReportForTesting()2548 void PeerConnection::RequestUsagePatternReportForTesting() {
2549 message_handler_.RequestUsagePatternReport(
2550 [this]() {
2551 RTC_DCHECK_RUN_ON(signaling_thread());
2552 ReportUsagePattern();
2553 },
2554 /* delay_ms= */ 0);
2555 }
2556
2557 std::function<void(const rtc::CopyOnWriteBuffer& packet,
2558 int64_t packet_time_us)>
InitializeRtcpCallback()2559 PeerConnection::InitializeRtcpCallback() {
2560 RTC_DCHECK_RUN_ON(signaling_thread());
2561
2562 auto flag =
2563 worker_thread()->Invoke<rtc::scoped_refptr<PendingTaskSafetyFlag>>(
2564 RTC_FROM_HERE, [this] {
2565 RTC_DCHECK_RUN_ON(worker_thread());
2566 if (!call_)
2567 return rtc::scoped_refptr<PendingTaskSafetyFlag>();
2568 if (!call_safety_)
2569 call_safety_.reset(new ScopedTaskSafety());
2570 return call_safety_->flag();
2571 });
2572
2573 if (!flag)
2574 return [](const rtc::CopyOnWriteBuffer&, int64_t) {};
2575
2576 return [this, flag = std::move(flag)](const rtc::CopyOnWriteBuffer& packet,
2577 int64_t packet_time_us) {
2578 RTC_DCHECK_RUN_ON(network_thread());
2579 // TODO(bugs.webrtc.org/11993): We should actually be delivering this call
2580 // directly to the Call class somehow directly on the network thread and not
2581 // incur this hop here. The DeliverPacket() method will eventually just have
2582 // to hop back over to the network thread.
2583 worker_thread()->PostTask(ToQueuedTask(flag, [this, packet,
2584 packet_time_us] {
2585 RTC_DCHECK_RUN_ON(worker_thread());
2586 call_->Receiver()->DeliverPacket(MediaType::ANY, packet, packet_time_us);
2587 }));
2588 };
2589 }
2590
2591 } // namespace webrtc
2592