• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include <algorithm>
17 #include <memory>
18 #include <set>
19 #include <string>
20 #include <utility>
21 
22 #include "absl/algorithm/container.h"
23 #include "absl/strings/match.h"
24 #include "absl/strings/string_view.h"
25 #include "api/jsep_ice_candidate.h"
26 #include "api/rtp_parameters.h"
27 #include "api/rtp_transceiver_direction.h"
28 #include "api/uma_metrics.h"
29 #include "api/video/video_codec_constants.h"
30 #include "call/audio_state.h"
31 #include "call/packet_receiver.h"
32 #include "media/base/media_channel.h"
33 #include "media/base/media_config.h"
34 #include "media/base/media_engine.h"
35 #include "media/base/rid_description.h"
36 #include "media/base/stream_params.h"
37 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
38 #include "p2p/base/basic_async_resolver_factory.h"
39 #include "p2p/base/connection.h"
40 #include "p2p/base/connection_info.h"
41 #include "p2p/base/dtls_transport_internal.h"
42 #include "p2p/base/p2p_constants.h"
43 #include "p2p/base/p2p_transport_channel.h"
44 #include "p2p/base/transport_info.h"
45 #include "pc/ice_server_parsing.h"
46 #include "pc/rtp_receiver.h"
47 #include "pc/rtp_receiver_proxy.h"
48 #include "pc/rtp_sender.h"
49 #include "pc/rtp_sender_proxy.h"
50 #include "pc/sctp_transport.h"
51 #include "pc/simulcast_description.h"
52 #include "pc/webrtc_session_description_factory.h"
53 #include "rtc_base/helpers.h"
54 #include "rtc_base/ip_address.h"
55 #include "rtc_base/logging.h"
56 #include "rtc_base/net_helper.h"
57 #include "rtc_base/network.h"
58 #include "rtc_base/network_constants.h"
59 #include "rtc_base/socket_address.h"
60 #include "rtc_base/string_encode.h"
61 #include "rtc_base/trace_event.h"
62 #include "rtc_base/unique_id_generator.h"
63 #include "system_wrappers/include/metrics.h"
64 
65 using cricket::ContentInfo;
66 using cricket::ContentInfos;
67 using cricket::MediaContentDescription;
68 using cricket::MediaProtocolType;
69 using cricket::RidDescription;
70 using cricket::RidDirection;
71 using cricket::SessionDescription;
72 using cricket::SimulcastDescription;
73 using cricket::SimulcastLayer;
74 using cricket::SimulcastLayerList;
75 using cricket::StreamParams;
76 using cricket::TransportInfo;
77 
78 using cricket::LOCAL_PORT_TYPE;
79 using cricket::PRFLX_PORT_TYPE;
80 using cricket::RELAY_PORT_TYPE;
81 using cricket::STUN_PORT_TYPE;
82 
83 namespace webrtc {
84 
85 namespace {
86 
87 // UMA metric names.
88 const char kSimulcastNumberOfEncodings[] =
89     "WebRTC.PeerConnection.Simulcast.NumberOfSendEncodings";
90 
91 static const int REPORT_USAGE_PATTERN_DELAY_MS = 60000;
92 
ConvertIceTransportTypeToCandidateFilter(PeerConnectionInterface::IceTransportsType type)93 uint32_t ConvertIceTransportTypeToCandidateFilter(
94     PeerConnectionInterface::IceTransportsType type) {
95   switch (type) {
96     case PeerConnectionInterface::kNone:
97       return cricket::CF_NONE;
98     case PeerConnectionInterface::kRelay:
99       return cricket::CF_RELAY;
100     case PeerConnectionInterface::kNoHost:
101       return (cricket::CF_ALL & ~cricket::CF_HOST);
102     case PeerConnectionInterface::kAll:
103       return cricket::CF_ALL;
104     default:
105       RTC_DCHECK_NOTREACHED();
106   }
107   return cricket::CF_NONE;
108 }
109 
GetIceCandidatePairCounter(const cricket::Candidate & local,const cricket::Candidate & remote)110 IceCandidatePairType GetIceCandidatePairCounter(
111     const cricket::Candidate& local,
112     const cricket::Candidate& remote) {
113   const auto& l = local.type();
114   const auto& r = remote.type();
115   const auto& host = LOCAL_PORT_TYPE;
116   const auto& srflx = STUN_PORT_TYPE;
117   const auto& relay = RELAY_PORT_TYPE;
118   const auto& prflx = PRFLX_PORT_TYPE;
119   if (l == host && r == host) {
120     bool local_hostname =
121         !local.address().hostname().empty() && local.address().IsUnresolvedIP();
122     bool remote_hostname = !remote.address().hostname().empty() &&
123                            remote.address().IsUnresolvedIP();
124     bool local_private = IPIsPrivate(local.address().ipaddr());
125     bool remote_private = IPIsPrivate(remote.address().ipaddr());
126     if (local_hostname) {
127       if (remote_hostname) {
128         return kIceCandidatePairHostNameHostName;
129       } else if (remote_private) {
130         return kIceCandidatePairHostNameHostPrivate;
131       } else {
132         return kIceCandidatePairHostNameHostPublic;
133       }
134     } else if (local_private) {
135       if (remote_hostname) {
136         return kIceCandidatePairHostPrivateHostName;
137       } else if (remote_private) {
138         return kIceCandidatePairHostPrivateHostPrivate;
139       } else {
140         return kIceCandidatePairHostPrivateHostPublic;
141       }
142     } else {
143       if (remote_hostname) {
144         return kIceCandidatePairHostPublicHostName;
145       } else if (remote_private) {
146         return kIceCandidatePairHostPublicHostPrivate;
147       } else {
148         return kIceCandidatePairHostPublicHostPublic;
149       }
150     }
151   }
152   if (l == host && r == srflx)
153     return kIceCandidatePairHostSrflx;
154   if (l == host && r == relay)
155     return kIceCandidatePairHostRelay;
156   if (l == host && r == prflx)
157     return kIceCandidatePairHostPrflx;
158   if (l == srflx && r == host)
159     return kIceCandidatePairSrflxHost;
160   if (l == srflx && r == srflx)
161     return kIceCandidatePairSrflxSrflx;
162   if (l == srflx && r == relay)
163     return kIceCandidatePairSrflxRelay;
164   if (l == srflx && r == prflx)
165     return kIceCandidatePairSrflxPrflx;
166   if (l == relay && r == host)
167     return kIceCandidatePairRelayHost;
168   if (l == relay && r == srflx)
169     return kIceCandidatePairRelaySrflx;
170   if (l == relay && r == relay)
171     return kIceCandidatePairRelayRelay;
172   if (l == relay && r == prflx)
173     return kIceCandidatePairRelayPrflx;
174   if (l == prflx && r == host)
175     return kIceCandidatePairPrflxHost;
176   if (l == prflx && r == srflx)
177     return kIceCandidatePairPrflxSrflx;
178   if (l == prflx && r == relay)
179     return kIceCandidatePairPrflxRelay;
180   return kIceCandidatePairMax;
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_DCHECK_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   ice_config.stable_writable_connection_ping_interval =
251       config.stable_writable_connection_ping_interval_ms;
252   return ice_config;
253 }
254 
255 // Ensures the configuration doesn't have any parameters with invalid values,
256 // or values that conflict with other parameters.
257 //
258 // Returns RTCError::OK() if there are no issues.
ValidateConfiguration(const PeerConnectionInterface::RTCConfiguration & config)259 RTCError ValidateConfiguration(
260     const PeerConnectionInterface::RTCConfiguration& config) {
261   return cricket::P2PTransportChannel::ValidateIceConfig(
262       ParseIceConfig(config));
263 }
264 
HasRtcpMuxEnabled(const cricket::ContentInfo * content)265 bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) {
266   return content->media_description()->rtcp_mux();
267 }
268 
DtlsEnabled(const PeerConnectionInterface::RTCConfiguration & configuration,const PeerConnectionFactoryInterface::Options & options,const PeerConnectionDependencies & dependencies)269 bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration,
270                  const PeerConnectionFactoryInterface::Options& options,
271                  const PeerConnectionDependencies& dependencies) {
272   if (options.disable_encryption)
273     return false;
274 
275   // Enable DTLS by default if we have an identity store or a certificate.
276   bool default_enabled =
277       (dependencies.cert_generator || !configuration.certificates.empty());
278 
279 #if defined(WEBRTC_FUCHSIA)
280   // The `configuration` can override the default value.
281   return configuration.enable_dtls_srtp.value_or(default_enabled);
282 #else
283   return default_enabled;
284 #endif
285 }
286 
287 }  // namespace
288 
operator ==(const PeerConnectionInterface::RTCConfiguration & o) const289 bool PeerConnectionInterface::RTCConfiguration::operator==(
290     const PeerConnectionInterface::RTCConfiguration& o) const {
291   // This static_assert prevents us from accidentally breaking operator==.
292   // Note: Order matters! Fields must be ordered the same as RTCConfiguration.
293   struct stuff_being_tested_for_equality {
294     IceServers servers;
295     IceTransportsType type;
296     BundlePolicy bundle_policy;
297     RtcpMuxPolicy rtcp_mux_policy;
298     std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
299     int ice_candidate_pool_size;
300     bool disable_ipv6_on_wifi;
301     int max_ipv6_networks;
302     bool disable_link_local_networks;
303     absl::optional<int> screencast_min_bitrate;
304     absl::optional<bool> combined_audio_video_bwe;
305 #if defined(WEBRTC_FUCHSIA)
306     absl::optional<bool> enable_dtls_srtp;
307 #endif
308     TcpCandidatePolicy tcp_candidate_policy;
309     CandidateNetworkPolicy candidate_network_policy;
310     int audio_jitter_buffer_max_packets;
311     bool audio_jitter_buffer_fast_accelerate;
312     int audio_jitter_buffer_min_delay_ms;
313     int ice_connection_receiving_timeout;
314     int ice_backup_candidate_pair_ping_interval;
315     ContinualGatheringPolicy continual_gathering_policy;
316     bool prioritize_most_likely_ice_candidate_pairs;
317     struct cricket::MediaConfig media_config;
318     bool prune_turn_ports;
319     PortPrunePolicy turn_port_prune_policy;
320     bool presume_writable_when_fully_relayed;
321     bool enable_ice_renomination;
322     bool redetermine_role_on_ice_restart;
323     bool surface_ice_candidates_on_ice_transport_type_changed;
324     absl::optional<int> ice_check_interval_strong_connectivity;
325     absl::optional<int> ice_check_interval_weak_connectivity;
326     absl::optional<int> ice_check_min_interval;
327     absl::optional<int> ice_unwritable_timeout;
328     absl::optional<int> ice_unwritable_min_checks;
329     absl::optional<int> ice_inactive_timeout;
330     absl::optional<int> stun_candidate_keepalive_interval;
331     webrtc::TurnCustomizer* turn_customizer;
332     SdpSemantics sdp_semantics;
333     absl::optional<rtc::AdapterType> network_preference;
334     bool active_reset_srtp_params;
335     absl::optional<CryptoOptions> crypto_options;
336     bool offer_extmap_allow_mixed;
337     std::string turn_logging_id;
338     bool enable_implicit_rollback;
339     absl::optional<bool> allow_codec_switching;
340     absl::optional<int> report_usage_pattern_delay_ms;
341     absl::optional<int> stable_writable_connection_ping_interval_ms;
342     webrtc::VpnPreference vpn_preference;
343     std::vector<rtc::NetworkMask> vpn_list;
344     PortAllocatorConfig port_allocator_config;
345     absl::optional<TimeDelta> pacer_burst_interval;
346   };
347   static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
348                 "Did you add something to RTCConfiguration and forget to "
349                 "update operator==?");
350   return type == o.type && servers == o.servers &&
351          bundle_policy == o.bundle_policy &&
352          rtcp_mux_policy == o.rtcp_mux_policy &&
353          tcp_candidate_policy == o.tcp_candidate_policy &&
354          candidate_network_policy == o.candidate_network_policy &&
355          audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
356          audio_jitter_buffer_fast_accelerate ==
357              o.audio_jitter_buffer_fast_accelerate &&
358          audio_jitter_buffer_min_delay_ms ==
359              o.audio_jitter_buffer_min_delay_ms &&
360          ice_connection_receiving_timeout ==
361              o.ice_connection_receiving_timeout &&
362          ice_backup_candidate_pair_ping_interval ==
363              o.ice_backup_candidate_pair_ping_interval &&
364          continual_gathering_policy == o.continual_gathering_policy &&
365          certificates == o.certificates &&
366          prioritize_most_likely_ice_candidate_pairs ==
367              o.prioritize_most_likely_ice_candidate_pairs &&
368          media_config == o.media_config &&
369          disable_ipv6_on_wifi == o.disable_ipv6_on_wifi &&
370          max_ipv6_networks == o.max_ipv6_networks &&
371          disable_link_local_networks == o.disable_link_local_networks &&
372          screencast_min_bitrate == o.screencast_min_bitrate &&
373          combined_audio_video_bwe == o.combined_audio_video_bwe &&
374 #if defined(WEBRTC_FUCHSIA)
375          enable_dtls_srtp == o.enable_dtls_srtp &&
376 #endif
377          ice_candidate_pool_size == o.ice_candidate_pool_size &&
378          prune_turn_ports == o.prune_turn_ports &&
379          turn_port_prune_policy == o.turn_port_prune_policy &&
380          presume_writable_when_fully_relayed ==
381              o.presume_writable_when_fully_relayed &&
382          enable_ice_renomination == o.enable_ice_renomination &&
383          redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
384          surface_ice_candidates_on_ice_transport_type_changed ==
385              o.surface_ice_candidates_on_ice_transport_type_changed &&
386          ice_check_interval_strong_connectivity ==
387              o.ice_check_interval_strong_connectivity &&
388          ice_check_interval_weak_connectivity ==
389              o.ice_check_interval_weak_connectivity &&
390          ice_check_min_interval == o.ice_check_min_interval &&
391          ice_unwritable_timeout == o.ice_unwritable_timeout &&
392          ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
393          ice_inactive_timeout == o.ice_inactive_timeout &&
394          stun_candidate_keepalive_interval ==
395              o.stun_candidate_keepalive_interval &&
396          turn_customizer == o.turn_customizer &&
397          sdp_semantics == o.sdp_semantics &&
398          network_preference == o.network_preference &&
399          active_reset_srtp_params == o.active_reset_srtp_params &&
400          crypto_options == o.crypto_options &&
401          offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
402          turn_logging_id == o.turn_logging_id &&
403          enable_implicit_rollback == o.enable_implicit_rollback &&
404          allow_codec_switching == o.allow_codec_switching &&
405          report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms &&
406          stable_writable_connection_ping_interval_ms ==
407              o.stable_writable_connection_ping_interval_ms &&
408          vpn_preference == o.vpn_preference && vpn_list == o.vpn_list &&
409          port_allocator_config.min_port == o.port_allocator_config.min_port &&
410          port_allocator_config.max_port == o.port_allocator_config.max_port &&
411          port_allocator_config.flags == o.port_allocator_config.flags &&
412          pacer_burst_interval == o.pacer_burst_interval;
413 }
414 
operator !=(const PeerConnectionInterface::RTCConfiguration & o) const415 bool PeerConnectionInterface::RTCConfiguration::operator!=(
416     const PeerConnectionInterface::RTCConfiguration& o) const {
417   return !(*this == o);
418 }
419 
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)420 RTCErrorOr<rtc::scoped_refptr<PeerConnection>> PeerConnection::Create(
421     rtc::scoped_refptr<ConnectionContext> context,
422     const PeerConnectionFactoryInterface::Options& options,
423     std::unique_ptr<RtcEventLog> event_log,
424     std::unique_ptr<Call> call,
425     const PeerConnectionInterface::RTCConfiguration& configuration,
426     PeerConnectionDependencies dependencies) {
427   // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
428   if (configuration.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
429     RTC_LOG(LS_WARNING)
430         << "PeerConnection constructed with legacy SDP semantics!";
431   }
432 
433   RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
434       ParseIceConfig(configuration));
435   if (!config_error.ok()) {
436     RTC_LOG(LS_ERROR) << "Invalid ICE configuration: "
437                       << config_error.message();
438     return config_error;
439   }
440 
441   if (!dependencies.allocator) {
442     RTC_LOG(LS_ERROR)
443         << "PeerConnection initialized without a PortAllocator? "
444            "This shouldn't happen if using PeerConnectionFactory.";
445     return RTCError(
446         RTCErrorType::INVALID_PARAMETER,
447         "Attempt to create a PeerConnection without a PortAllocatorFactory");
448   }
449 
450   if (!dependencies.observer) {
451     // TODO(deadbeef): Why do we do this?
452     RTC_LOG(LS_ERROR) << "PeerConnection initialized without a "
453                          "PeerConnectionObserver";
454     return RTCError(RTCErrorType::INVALID_PARAMETER,
455                     "Attempt to create a PeerConnection without an observer");
456   }
457 
458   bool is_unified_plan =
459       configuration.sdp_semantics == SdpSemantics::kUnifiedPlan;
460   bool dtls_enabled = DtlsEnabled(configuration, options, dependencies);
461 
462   // Interim code: If an AsyncResolverFactory is given, but not an
463   // AsyncDnsResolverFactory, wrap it in a WrappingAsyncDnsResolverFactory
464   // If neither is given, create a WrappingAsyncDnsResolverFactory wrapping
465   // a BasicAsyncResolver.
466   // TODO(bugs.webrtc.org/12598): Remove code once all callers pass a
467   // AsyncDnsResolverFactory.
468   if (dependencies.async_dns_resolver_factory &&
469       dependencies.async_resolver_factory) {
470     RTC_LOG(LS_ERROR)
471         << "Attempt to set both old and new type of DNS resolver factory";
472     return RTCError(RTCErrorType::INVALID_PARAMETER,
473                     "Both old and new type of DNS resolver given");
474   }
475   if (dependencies.async_resolver_factory) {
476     dependencies.async_dns_resolver_factory =
477         std::make_unique<WrappingAsyncDnsResolverFactory>(
478             std::move(dependencies.async_resolver_factory));
479   } else {
480     dependencies.async_dns_resolver_factory =
481         std::make_unique<WrappingAsyncDnsResolverFactory>(
482             std::make_unique<BasicAsyncResolverFactory>());
483   }
484 
485   // The PeerConnection constructor consumes some, but not all, dependencies.
486   auto pc = rtc::make_ref_counted<PeerConnection>(
487       context, options, is_unified_plan, std::move(event_log), std::move(call),
488       dependencies, dtls_enabled);
489   RTCError init_error = pc->Initialize(configuration, std::move(dependencies));
490   if (!init_error.ok()) {
491     RTC_LOG(LS_ERROR) << "PeerConnection initialization failed";
492     return init_error;
493   }
494   return pc;
495 }
496 
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,bool dtls_enabled)497 PeerConnection::PeerConnection(
498     rtc::scoped_refptr<ConnectionContext> context,
499     const PeerConnectionFactoryInterface::Options& options,
500     bool is_unified_plan,
501     std::unique_ptr<RtcEventLog> event_log,
502     std::unique_ptr<Call> call,
503     PeerConnectionDependencies& dependencies,
504     bool dtls_enabled)
505     : context_(context),
506       trials_(std::move(dependencies.trials), &context->field_trials()),
507       options_(options),
508       observer_(dependencies.observer),
509       is_unified_plan_(is_unified_plan),
510       event_log_(std::move(event_log)),
511       event_log_ptr_(event_log_.get()),
512       async_dns_resolver_factory_(
513           std::move(dependencies.async_dns_resolver_factory)),
514       port_allocator_(std::move(dependencies.allocator)),
515       ice_transport_factory_(std::move(dependencies.ice_transport_factory)),
516       tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
517       call_(std::move(call)),
518       call_ptr_(call_.get()),
519       // RFC 3264: The numeric value of the session id and version in the
520       // o line MUST be representable with a "64 bit signed integer".
521       // Due to this constraint session id `session_id_` is max limited to
522       // LLONG_MAX.
523       session_id_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
524       dtls_enabled_(dtls_enabled),
525       data_channel_controller_(this),
526       message_handler_(signaling_thread()),
527       weak_factory_(this) {
528   worker_thread()->BlockingCall([this] {
529     RTC_DCHECK_RUN_ON(worker_thread());
530     worker_thread_safety_ = PendingTaskSafetyFlag::Create();
531     if (!call_)
532       worker_thread_safety_->SetNotAlive();
533   });
534 }
535 
~PeerConnection()536 PeerConnection::~PeerConnection() {
537   TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
538   RTC_DCHECK_RUN_ON(signaling_thread());
539 
540   if (sdp_handler_) {
541     sdp_handler_->PrepareForShutdown();
542   }
543 
544   // Need to stop transceivers before destroying the stats collector because
545   // AudioRtpSender has a reference to the LegacyStatsCollector it will update
546   // when stopping.
547   if (rtp_manager()) {
548     for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
549       transceiver->StopInternal();
550     }
551   }
552 
553   legacy_stats_.reset(nullptr);
554   if (stats_collector_) {
555     stats_collector_->WaitForPendingRequest();
556     stats_collector_ = nullptr;
557   }
558 
559   if (sdp_handler_) {
560     // Don't destroy BaseChannels until after stats has been cleaned up so that
561     // the last stats request can still read from the channels.
562     sdp_handler_->DestroyAllChannels();
563 
564     RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
565 
566     sdp_handler_->ResetSessionDescFactory();
567   }
568 
569   // port_allocator_ and transport_controller_ live on the network thread and
570   // should be destroyed there.
571   transport_controller_copy_ = nullptr;
572   network_thread()->BlockingCall([this] {
573     RTC_DCHECK_RUN_ON(network_thread());
574     TeardownDataChannelTransport_n();
575     transport_controller_.reset();
576     port_allocator_.reset();
577     if (network_thread_safety_)
578       network_thread_safety_->SetNotAlive();
579   });
580 
581   // call_ and event_log_ must be destroyed on the worker thread.
582   worker_thread()->BlockingCall([this] {
583     RTC_DCHECK_RUN_ON(worker_thread());
584     worker_thread_safety_->SetNotAlive();
585     call_.reset();
586     // The event log must outlive call (and any other object that uses it).
587     event_log_.reset();
588   });
589 }
590 
Initialize(const PeerConnectionInterface::RTCConfiguration & configuration,PeerConnectionDependencies dependencies)591 RTCError PeerConnection::Initialize(
592     const PeerConnectionInterface::RTCConfiguration& configuration,
593     PeerConnectionDependencies dependencies) {
594   RTC_DCHECK_RUN_ON(signaling_thread());
595   TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
596 
597   cricket::ServerAddresses stun_servers;
598   std::vector<cricket::RelayServerConfig> turn_servers;
599 
600   RTCError parse_error = ParseIceServersOrError(configuration.servers,
601                                                 &stun_servers, &turn_servers);
602   if (!parse_error.ok()) {
603     return parse_error;
604   }
605 
606   // Restrict number of TURN servers.
607   if (!trials().IsDisabled("WebRTC-LimitTurnServers") &&
608       turn_servers.size() > cricket::kMaxTurnServers) {
609     RTC_LOG(LS_WARNING) << "Number of configured TURN servers is "
610                         << turn_servers.size()
611                         << " which exceeds the maximum allowed number of "
612                         << cricket::kMaxTurnServers;
613     turn_servers.resize(cricket::kMaxTurnServers);
614   }
615 
616   // Add the turn logging id to all turn servers
617   for (cricket::RelayServerConfig& turn_server : turn_servers) {
618     turn_server.turn_logging_id = configuration.turn_logging_id;
619   }
620 
621   // Note if STUN or TURN servers were supplied.
622   if (!stun_servers.empty()) {
623     NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
624   }
625   if (!turn_servers.empty()) {
626     NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
627   }
628 
629   // Network thread initialization.
630   transport_controller_copy_ =
631       network_thread()->BlockingCall([&] {
632         RTC_DCHECK_RUN_ON(network_thread());
633         network_thread_safety_ = PendingTaskSafetyFlag::Create();
634         InitializePortAllocatorResult pa_result = InitializePortAllocator_n(
635             stun_servers, turn_servers, configuration);
636         // Send information about IPv4/IPv6 status.
637         PeerConnectionAddressFamilyCounter address_family =
638             pa_result.enable_ipv6 ? kPeerConnection_IPv6 : kPeerConnection_IPv4;
639         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
640                                   address_family,
641                                   kPeerConnectionAddressFamilyCounter_Max);
642         return InitializeTransportController_n(configuration, dependencies);
643       });
644 
645   configuration_ = configuration;
646 
647   legacy_stats_ = std::make_unique<LegacyStatsCollector>(this);
648   stats_collector_ = RTCStatsCollector::Create(this);
649 
650   sdp_handler_ = SdpOfferAnswerHandler::Create(this, configuration,
651                                                dependencies, context_.get());
652 
653   rtp_manager_ = std::make_unique<RtpTransmissionManager>(
654       IsUnifiedPlan(), context_.get(), &usage_pattern_, observer_,
655       legacy_stats_.get(), [this]() {
656         RTC_DCHECK_RUN_ON(signaling_thread());
657         sdp_handler_->UpdateNegotiationNeeded();
658       });
659 
660   // Add default audio/video transceivers for Plan B SDP.
661   if (!IsUnifiedPlan()) {
662     rtp_manager()->transceivers()->Add(
663         RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
664             signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
665                                     cricket::MEDIA_TYPE_AUDIO, context())));
666     rtp_manager()->transceivers()->Add(
667         RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
668             signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
669                                     cricket::MEDIA_TYPE_VIDEO, context())));
670   }
671 
672   int delay_ms = configuration.report_usage_pattern_delay_ms
673                      ? *configuration.report_usage_pattern_delay_ms
674                      : REPORT_USAGE_PATTERN_DELAY_MS;
675   message_handler_.RequestUsagePatternReport(
676       [this]() {
677         RTC_DCHECK_RUN_ON(signaling_thread());
678         ReportUsagePattern();
679       },
680       delay_ms);
681 
682   return RTCError::OK();
683 }
684 
InitializeTransportController_n(const RTCConfiguration & configuration,const PeerConnectionDependencies & dependencies)685 JsepTransportController* PeerConnection::InitializeTransportController_n(
686     const RTCConfiguration& configuration,
687     const PeerConnectionDependencies& dependencies) {
688   JsepTransportController::Config config;
689   config.redetermine_role_on_ice_restart =
690       configuration.redetermine_role_on_ice_restart;
691   config.ssl_max_version = options_.ssl_max_version;
692   config.disable_encryption = options_.disable_encryption;
693   config.bundle_policy = configuration.bundle_policy;
694   config.rtcp_mux_policy = configuration.rtcp_mux_policy;
695   // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove
696   // this stub.
697   config.crypto_options = configuration.crypto_options.has_value()
698                               ? *configuration.crypto_options
699                               : options_.crypto_options;
700   config.transport_observer = this;
701   config.rtcp_handler = InitializeRtcpCallback();
702   config.event_log = event_log_ptr_;
703 #if defined(ENABLE_EXTERNAL_AUTH)
704   config.enable_external_auth = true;
705 #endif
706   config.active_reset_srtp_params = configuration.active_reset_srtp_params;
707 
708   // DTLS has to be enabled to use SCTP.
709   if (dtls_enabled_) {
710     config.sctp_factory = context_->sctp_transport_factory();
711   }
712 
713   config.ice_transport_factory = ice_transport_factory_.get();
714   config.on_dtls_handshake_error_ =
715       [weak_ptr = weak_factory_.GetWeakPtr()](rtc::SSLHandshakeError s) {
716         if (weak_ptr) {
717           weak_ptr->OnTransportControllerDtlsHandshakeError(s);
718         }
719       };
720 
721   config.field_trials = trials_.get();
722 
723   transport_controller_.reset(
724       new JsepTransportController(network_thread(), port_allocator_.get(),
725                                   async_dns_resolver_factory_.get(), config));
726 
727   transport_controller_->SubscribeIceConnectionState(
728       [this](cricket::IceConnectionState s) {
729         RTC_DCHECK_RUN_ON(network_thread());
730         if (s == cricket::kIceConnectionConnected) {
731           ReportTransportStats();
732         }
733         signaling_thread()->PostTask(
734             SafeTask(signaling_thread_safety_.flag(), [this, s]() {
735               RTC_DCHECK_RUN_ON(signaling_thread());
736               OnTransportControllerConnectionState(s);
737             }));
738       });
739   transport_controller_->SubscribeConnectionState(
740       [this](PeerConnectionInterface::PeerConnectionState s) {
741         RTC_DCHECK_RUN_ON(network_thread());
742         signaling_thread()->PostTask(
743             SafeTask(signaling_thread_safety_.flag(), [this, s]() {
744               RTC_DCHECK_RUN_ON(signaling_thread());
745               SetConnectionState(s);
746             }));
747       });
748   transport_controller_->SubscribeStandardizedIceConnectionState(
749       [this](PeerConnectionInterface::IceConnectionState s) {
750         RTC_DCHECK_RUN_ON(network_thread());
751         signaling_thread()->PostTask(
752             SafeTask(signaling_thread_safety_.flag(), [this, s]() {
753               RTC_DCHECK_RUN_ON(signaling_thread());
754               SetStandardizedIceConnectionState(s);
755             }));
756       });
757   transport_controller_->SubscribeIceGatheringState(
758       [this](cricket::IceGatheringState s) {
759         RTC_DCHECK_RUN_ON(network_thread());
760         signaling_thread()->PostTask(
761             SafeTask(signaling_thread_safety_.flag(), [this, s]() {
762               RTC_DCHECK_RUN_ON(signaling_thread());
763               OnTransportControllerGatheringState(s);
764             }));
765       });
766   transport_controller_->SubscribeIceCandidateGathered(
767       [this](const std::string& transport,
768              const std::vector<cricket::Candidate>& candidates) {
769         RTC_DCHECK_RUN_ON(network_thread());
770         signaling_thread()->PostTask(
771             SafeTask(signaling_thread_safety_.flag(),
772                      [this, t = transport, c = candidates]() {
773                        RTC_DCHECK_RUN_ON(signaling_thread());
774                        OnTransportControllerCandidatesGathered(t, c);
775                      }));
776       });
777   transport_controller_->SubscribeIceCandidateError(
778       [this](const cricket::IceCandidateErrorEvent& event) {
779         RTC_DCHECK_RUN_ON(network_thread());
780         signaling_thread()->PostTask(
781             SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
782               RTC_DCHECK_RUN_ON(signaling_thread());
783               OnTransportControllerCandidateError(event);
784             }));
785       });
786   transport_controller_->SubscribeIceCandidatesRemoved(
787       [this](const std::vector<cricket::Candidate>& c) {
788         RTC_DCHECK_RUN_ON(network_thread());
789         signaling_thread()->PostTask(
790             SafeTask(signaling_thread_safety_.flag(), [this, c = c]() {
791               RTC_DCHECK_RUN_ON(signaling_thread());
792               OnTransportControllerCandidatesRemoved(c);
793             }));
794       });
795   transport_controller_->SubscribeIceCandidatePairChanged(
796       [this](const cricket::CandidatePairChangeEvent& event) {
797         RTC_DCHECK_RUN_ON(network_thread());
798         signaling_thread()->PostTask(
799             SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
800               RTC_DCHECK_RUN_ON(signaling_thread());
801               OnTransportControllerCandidateChanged(event);
802             }));
803       });
804 
805   transport_controller_->SetIceConfig(ParseIceConfig(configuration));
806   return transport_controller_.get();
807 }
808 
local_streams()809 rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::local_streams() {
810   RTC_DCHECK_RUN_ON(signaling_thread());
811   RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
812                                  "Plan SdpSemantics. Please use GetSenders "
813                                  "instead.";
814   return sdp_handler_->local_streams();
815 }
816 
remote_streams()817 rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
818   RTC_DCHECK_RUN_ON(signaling_thread());
819   RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
820                                  "Plan SdpSemantics. Please use GetReceivers "
821                                  "instead.";
822   return sdp_handler_->remote_streams();
823 }
824 
AddStream(MediaStreamInterface * local_stream)825 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
826   RTC_DCHECK_RUN_ON(signaling_thread());
827   RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
828                                  "SdpSemantics. Please use AddTrack instead.";
829   TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
830   if (!ConfiguredForMedia()) {
831     RTC_LOG(LS_ERROR) << "AddStream: Not configured for media";
832     return false;
833   }
834   return sdp_handler_->AddStream(local_stream);
835 }
836 
RemoveStream(MediaStreamInterface * local_stream)837 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
838   RTC_DCHECK_RUN_ON(signaling_thread());
839   RTC_DCHECK(ConfiguredForMedia());
840   RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified "
841                                  "Plan SdpSemantics. Please use RemoveTrack "
842                                  "instead.";
843   TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
844   sdp_handler_->RemoveStream(local_stream);
845 }
846 
AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string> & stream_ids)847 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
848     rtc::scoped_refptr<MediaStreamTrackInterface> track,
849     const std::vector<std::string>& stream_ids) {
850   return AddTrack(std::move(track), stream_ids, nullptr);
851 }
852 
AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string> & stream_ids,const std::vector<RtpEncodingParameters> & init_send_encodings)853 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
854     rtc::scoped_refptr<MediaStreamTrackInterface> track,
855     const std::vector<std::string>& stream_ids,
856     const std::vector<RtpEncodingParameters>& init_send_encodings) {
857   return AddTrack(std::move(track), stream_ids, &init_send_encodings);
858 }
859 
AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string> & stream_ids,const std::vector<RtpEncodingParameters> * init_send_encodings)860 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
861     rtc::scoped_refptr<MediaStreamTrackInterface> track,
862     const std::vector<std::string>& stream_ids,
863     const std::vector<RtpEncodingParameters>* init_send_encodings) {
864   RTC_DCHECK_RUN_ON(signaling_thread());
865   TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
866   if (!ConfiguredForMedia()) {
867     LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
868                          "Not configured for media");
869   }
870   if (!track) {
871     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Track is null.");
872   }
873   if (!(track->kind() == MediaStreamTrackInterface::kAudioKind ||
874         track->kind() == MediaStreamTrackInterface::kVideoKind)) {
875     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
876                          "Track has invalid kind: " + track->kind());
877   }
878   if (IsClosed()) {
879     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
880                          "PeerConnection is closed.");
881   }
882   if (rtp_manager()->FindSenderForTrack(track.get())) {
883     LOG_AND_RETURN_ERROR(
884         RTCErrorType::INVALID_PARAMETER,
885         "Sender already exists for track " + track->id() + ".");
886   }
887   auto sender_or_error =
888       rtp_manager()->AddTrack(track, stream_ids, init_send_encodings);
889   if (sender_or_error.ok()) {
890     sdp_handler_->UpdateNegotiationNeeded();
891     legacy_stats_->AddTrack(track.get());
892   }
893   return sender_or_error;
894 }
895 
RemoveTrackOrError(rtc::scoped_refptr<RtpSenderInterface> sender)896 RTCError PeerConnection::RemoveTrackOrError(
897     rtc::scoped_refptr<RtpSenderInterface> sender) {
898   RTC_DCHECK_RUN_ON(signaling_thread());
899   if (!ConfiguredForMedia()) {
900     LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
901                          "Not configured for media");
902   }
903   if (!sender) {
904     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Sender is null.");
905   }
906   if (IsClosed()) {
907     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
908                          "PeerConnection is closed.");
909   }
910   if (IsUnifiedPlan()) {
911     auto transceiver = FindTransceiverBySender(sender);
912     if (!transceiver || !sender->track()) {
913       return RTCError::OK();
914     }
915     sender->SetTrack(nullptr);
916     if (transceiver->direction() == RtpTransceiverDirection::kSendRecv) {
917       transceiver->internal()->set_direction(
918           RtpTransceiverDirection::kRecvOnly);
919     } else if (transceiver->direction() == RtpTransceiverDirection::kSendOnly) {
920       transceiver->internal()->set_direction(
921           RtpTransceiverDirection::kInactive);
922     }
923   } else {
924     bool removed;
925     if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
926       removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender(
927           sender.get());
928     } else {
929       RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
930       removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender(
931           sender.get());
932     }
933     if (!removed) {
934       LOG_AND_RETURN_ERROR(
935           RTCErrorType::INVALID_PARAMETER,
936           "Couldn't find sender " + sender->id() + " to remove.");
937     }
938   }
939   sdp_handler_->UpdateNegotiationNeeded();
940   return RTCError::OK();
941 }
942 
943 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
FindTransceiverBySender(rtc::scoped_refptr<RtpSenderInterface> sender)944 PeerConnection::FindTransceiverBySender(
945     rtc::scoped_refptr<RtpSenderInterface> sender) {
946   return rtp_manager()->transceivers()->FindBySender(sender);
947 }
948 
949 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track)950 PeerConnection::AddTransceiver(
951     rtc::scoped_refptr<MediaStreamTrackInterface> track) {
952   if (!ConfiguredForMedia()) {
953     LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
954                          "Not configured for media");
955   }
956 
957   return AddTransceiver(track, RtpTransceiverInit());
958 }
959 
GetRtpTransport(const std::string & mid)960 RtpTransportInternal* PeerConnection::GetRtpTransport(const std::string& mid) {
961   // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
962   // This might be done by caching the value on the signaling thread.
963   RTC_DCHECK_RUN_ON(signaling_thread());
964   return network_thread()->BlockingCall([this, &mid] {
965     RTC_DCHECK_RUN_ON(network_thread());
966     auto rtp_transport = transport_controller_->GetRtpTransport(mid);
967     RTC_DCHECK(rtp_transport);
968     return rtp_transport;
969   });
970 }
971 
972 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track,const RtpTransceiverInit & init)973 PeerConnection::AddTransceiver(
974     rtc::scoped_refptr<MediaStreamTrackInterface> track,
975     const RtpTransceiverInit& init) {
976   RTC_DCHECK_RUN_ON(signaling_thread());
977   if (!ConfiguredForMedia()) {
978     LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
979                          "Not configured for media");
980   }
981   RTC_CHECK(IsUnifiedPlan())
982       << "AddTransceiver is only available with Unified Plan SdpSemantics";
983   if (!track) {
984     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "track is null");
985   }
986   cricket::MediaType media_type;
987   if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
988     media_type = cricket::MEDIA_TYPE_AUDIO;
989   } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
990     media_type = cricket::MEDIA_TYPE_VIDEO;
991   } else {
992     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
993                          "Track kind is not audio or video");
994   }
995   return AddTransceiver(media_type, track, init);
996 }
997 
998 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type)999 PeerConnection::AddTransceiver(cricket::MediaType media_type) {
1000   return AddTransceiver(media_type, RtpTransceiverInit());
1001 }
1002 
1003 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type,const RtpTransceiverInit & init)1004 PeerConnection::AddTransceiver(cricket::MediaType media_type,
1005                                const RtpTransceiverInit& init) {
1006   RTC_DCHECK_RUN_ON(signaling_thread());
1007   if (!ConfiguredForMedia()) {
1008     LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1009                          "Not configured for media");
1010   }
1011   RTC_CHECK(IsUnifiedPlan())
1012       << "AddTransceiver is only available with Unified Plan SdpSemantics";
1013   if (!(media_type == cricket::MEDIA_TYPE_AUDIO ||
1014         media_type == cricket::MEDIA_TYPE_VIDEO)) {
1015     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1016                          "media type is not audio or video");
1017   }
1018   return AddTransceiver(media_type, nullptr, init);
1019 }
1020 
1021 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type,rtc::scoped_refptr<MediaStreamTrackInterface> track,const RtpTransceiverInit & init,bool update_negotiation_needed)1022 PeerConnection::AddTransceiver(
1023     cricket::MediaType media_type,
1024     rtc::scoped_refptr<MediaStreamTrackInterface> track,
1025     const RtpTransceiverInit& init,
1026     bool update_negotiation_needed) {
1027   RTC_DCHECK_RUN_ON(signaling_thread());
1028   if (!ConfiguredForMedia()) {
1029     LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1030                          "Not configured for media");
1031   }
1032   RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
1033               media_type == cricket::MEDIA_TYPE_VIDEO));
1034   if (track) {
1035     RTC_DCHECK_EQ(media_type,
1036                   (track->kind() == MediaStreamTrackInterface::kAudioKind
1037                        ? cricket::MEDIA_TYPE_AUDIO
1038                        : cricket::MEDIA_TYPE_VIDEO));
1039   }
1040 
1041   RTC_HISTOGRAM_COUNTS_LINEAR(kSimulcastNumberOfEncodings,
1042                               init.send_encodings.size(), 0, 7, 8);
1043 
1044   size_t num_rids = absl::c_count_if(init.send_encodings,
1045                                      [](const RtpEncodingParameters& encoding) {
1046                                        return !encoding.rid.empty();
1047                                      });
1048   if (num_rids > 0 && num_rids != init.send_encodings.size()) {
1049     LOG_AND_RETURN_ERROR(
1050         RTCErrorType::INVALID_PARAMETER,
1051         "RIDs must be provided for either all or none of the send encodings.");
1052   }
1053 
1054   if (num_rids > 0 && absl::c_any_of(init.send_encodings,
1055                                      [](const RtpEncodingParameters& encoding) {
1056                                        return !IsLegalRsidName(encoding.rid);
1057                                      })) {
1058     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1059                          "Invalid RID value provided.");
1060   }
1061 
1062   if (absl::c_any_of(init.send_encodings,
1063                      [](const RtpEncodingParameters& encoding) {
1064                        return encoding.ssrc.has_value();
1065                      })) {
1066     LOG_AND_RETURN_ERROR(
1067         RTCErrorType::UNSUPPORTED_PARAMETER,
1068         "Attempted to set an unimplemented parameter of RtpParameters.");
1069   }
1070 
1071   RtpParameters parameters;
1072   parameters.encodings = init.send_encodings;
1073 
1074   // Encodings are dropped from the tail if too many are provided.
1075   size_t max_simulcast_streams =
1076       media_type == cricket::MEDIA_TYPE_VIDEO ? kMaxSimulcastStreams : 1u;
1077   if (parameters.encodings.size() > max_simulcast_streams) {
1078     parameters.encodings.erase(
1079         parameters.encodings.begin() + max_simulcast_streams,
1080         parameters.encodings.end());
1081   }
1082 
1083   // Single RID should be removed.
1084   if (parameters.encodings.size() == 1 &&
1085       !parameters.encodings[0].rid.empty()) {
1086     RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
1087     parameters.encodings[0].rid.clear();
1088   }
1089 
1090   // If RIDs were not provided, they are generated for simulcast scenario.
1091   if (parameters.encodings.size() > 1 && num_rids == 0) {
1092     rtc::UniqueStringGenerator rid_generator;
1093     for (RtpEncodingParameters& encoding : parameters.encodings) {
1094       encoding.rid = rid_generator();
1095     }
1096   }
1097 
1098   if (UnimplementedRtpParameterHasValue(parameters)) {
1099     LOG_AND_RETURN_ERROR(
1100         RTCErrorType::UNSUPPORTED_PARAMETER,
1101         "Attempted to set an unimplemented parameter of RtpParameters.");
1102   }
1103 
1104   std::vector<cricket::VideoCodec> codecs;
1105   if (media_type == cricket::MEDIA_TYPE_VIDEO) {
1106     // Gather the current codec capabilities to allow checking scalabilityMode
1107     // against supported values.
1108     codecs = context_->media_engine()->video().send_codecs(false);
1109   }
1110 
1111   auto result = cricket::CheckRtpParametersValues(parameters, codecs);
1112   if (!result.ok()) {
1113     LOG_AND_RETURN_ERROR(result.type(), result.message());
1114   }
1115 
1116   RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
1117                    << " transceiver in response to a call to AddTransceiver.";
1118   // Set the sender ID equal to the track ID if the track is specified unless
1119   // that sender ID is already in use.
1120   std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
1121                                ? track->id()
1122                                : rtc::CreateRandomUuid());
1123   auto sender = rtp_manager()->CreateSender(
1124       media_type, sender_id, track, init.stream_ids, parameters.encodings);
1125   auto receiver =
1126       rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
1127   auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
1128   transceiver->internal()->set_direction(init.direction);
1129 
1130   if (update_negotiation_needed) {
1131     sdp_handler_->UpdateNegotiationNeeded();
1132   }
1133 
1134   return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
1135 }
1136 
OnNegotiationNeeded()1137 void PeerConnection::OnNegotiationNeeded() {
1138   RTC_DCHECK_RUN_ON(signaling_thread());
1139   RTC_DCHECK(!IsClosed());
1140   sdp_handler_->UpdateNegotiationNeeded();
1141 }
1142 
CreateSender(const std::string & kind,const std::string & stream_id)1143 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
1144     const std::string& kind,
1145     const std::string& stream_id) {
1146   RTC_DCHECK_RUN_ON(signaling_thread());
1147   if (!ConfiguredForMedia()) {
1148     RTC_LOG(LS_ERROR) << "Not configured for media";
1149     return nullptr;
1150   }
1151   RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified "
1152                                  "Plan SdpSemantics. Please use AddTransceiver "
1153                                  "instead.";
1154   TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
1155   if (IsClosed()) {
1156     return nullptr;
1157   }
1158 
1159   // Internally we need to have one stream with Plan B semantics, so we
1160   // generate a random stream ID if not specified.
1161   std::vector<std::string> stream_ids;
1162   if (stream_id.empty()) {
1163     stream_ids.push_back(rtc::CreateRandomUuid());
1164     RTC_LOG(LS_INFO)
1165         << "No stream_id specified for sender. Generated stream ID: "
1166         << stream_ids[0];
1167   } else {
1168     stream_ids.push_back(stream_id);
1169   }
1170 
1171   // TODO(steveanton): Move construction of the RtpSenders to RtpTransceiver.
1172   rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
1173   if (kind == MediaStreamTrackInterface::kAudioKind) {
1174     auto audio_sender =
1175         AudioRtpSender::Create(worker_thread(), rtc::CreateRandomUuid(),
1176                                legacy_stats_.get(), rtp_manager());
1177     audio_sender->SetMediaChannel(rtp_manager()->voice_media_channel());
1178     new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
1179         signaling_thread(), audio_sender);
1180     rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
1181   } else if (kind == MediaStreamTrackInterface::kVideoKind) {
1182     auto video_sender = VideoRtpSender::Create(
1183         worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
1184     video_sender->SetMediaChannel(rtp_manager()->video_media_channel());
1185     new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
1186         signaling_thread(), video_sender);
1187     rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender);
1188   } else {
1189     RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
1190     return nullptr;
1191   }
1192   new_sender->internal()->set_stream_ids(stream_ids);
1193 
1194   return new_sender;
1195 }
1196 
GetSenders() const1197 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
1198     const {
1199   RTC_DCHECK_RUN_ON(signaling_thread());
1200   std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
1201   if (ConfiguredForMedia()) {
1202     for (const auto& sender : rtp_manager()->GetSendersInternal()) {
1203       ret.push_back(sender);
1204     }
1205   }
1206   return ret;
1207 }
1208 
1209 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
GetReceivers() const1210 PeerConnection::GetReceivers() const {
1211   RTC_DCHECK_RUN_ON(signaling_thread());
1212   std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
1213   if (ConfiguredForMedia()) {
1214     for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
1215       ret.push_back(receiver);
1216     }
1217   }
1218   return ret;
1219 }
1220 
1221 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
GetTransceivers() const1222 PeerConnection::GetTransceivers() const {
1223   RTC_DCHECK_RUN_ON(signaling_thread());
1224   RTC_CHECK(IsUnifiedPlan())
1225       << "GetTransceivers is only supported with Unified Plan SdpSemantics.";
1226   std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
1227   if (ConfiguredForMedia()) {
1228     for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1229       all_transceivers.push_back(transceiver);
1230     }
1231   }
1232   return all_transceivers;
1233 }
1234 
GetStats(StatsObserver * observer,MediaStreamTrackInterface * track,StatsOutputLevel level)1235 bool PeerConnection::GetStats(StatsObserver* observer,
1236                               MediaStreamTrackInterface* track,
1237                               StatsOutputLevel level) {
1238   TRACE_EVENT0("webrtc", "PeerConnection::GetStats (legacy)");
1239   RTC_DCHECK_RUN_ON(signaling_thread());
1240   if (!observer) {
1241     RTC_LOG(LS_ERROR) << "Legacy GetStats - observer is NULL.";
1242     return false;
1243   }
1244 
1245   RTC_LOG_THREAD_BLOCK_COUNT();
1246 
1247   legacy_stats_->UpdateStats(level);
1248 
1249   RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(4);
1250 
1251   // The LegacyStatsCollector is used to tell if a track is valid because it may
1252   // remember tracks that the PeerConnection previously removed.
1253   if (track && !legacy_stats_->IsValidTrack(track->id())) {
1254     RTC_LOG(LS_WARNING) << "Legacy GetStats is called with an invalid track: "
1255                         << track->id();
1256     return false;
1257   }
1258   message_handler_.PostGetStats(observer, legacy_stats_.get(), track);
1259 
1260   return true;
1261 }
1262 
GetStats(RTCStatsCollectorCallback * callback)1263 void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
1264   TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1265   RTC_DCHECK_RUN_ON(signaling_thread());
1266   RTC_DCHECK(stats_collector_);
1267   RTC_DCHECK(callback);
1268   RTC_LOG_THREAD_BLOCK_COUNT();
1269   stats_collector_->GetStatsReport(
1270       rtc::scoped_refptr<RTCStatsCollectorCallback>(callback));
1271   RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
1272 }
1273 
GetStats(rtc::scoped_refptr<RtpSenderInterface> selector,rtc::scoped_refptr<RTCStatsCollectorCallback> callback)1274 void PeerConnection::GetStats(
1275     rtc::scoped_refptr<RtpSenderInterface> selector,
1276     rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1277   TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1278   RTC_DCHECK_RUN_ON(signaling_thread());
1279   RTC_DCHECK(callback);
1280   RTC_DCHECK(stats_collector_);
1281   RTC_LOG_THREAD_BLOCK_COUNT();
1282   rtc::scoped_refptr<RtpSenderInternal> internal_sender;
1283   if (selector) {
1284     for (const auto& proxy_transceiver :
1285          rtp_manager()->transceivers()->List()) {
1286       for (const auto& proxy_sender :
1287            proxy_transceiver->internal()->senders()) {
1288         if (proxy_sender == selector) {
1289           internal_sender = proxy_sender->internal();
1290           break;
1291         }
1292       }
1293       if (internal_sender)
1294         break;
1295     }
1296   }
1297   // If there is no `internal_sender` then `selector` is either null or does not
1298   // belong to the PeerConnection (in Plan B, senders can be removed from the
1299   // PeerConnection). This means that "all the stats objects representing the
1300   // selector" is an empty set. Invoking GetStatsReport() with a null selector
1301   // produces an empty stats report.
1302   stats_collector_->GetStatsReport(internal_sender, callback);
1303   RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
1304 }
1305 
GetStats(rtc::scoped_refptr<RtpReceiverInterface> selector,rtc::scoped_refptr<RTCStatsCollectorCallback> callback)1306 void PeerConnection::GetStats(
1307     rtc::scoped_refptr<RtpReceiverInterface> selector,
1308     rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1309   TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1310   RTC_DCHECK_RUN_ON(signaling_thread());
1311   RTC_DCHECK(callback);
1312   RTC_DCHECK(stats_collector_);
1313   RTC_LOG_THREAD_BLOCK_COUNT();
1314   rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
1315   if (selector) {
1316     for (const auto& proxy_transceiver :
1317          rtp_manager()->transceivers()->List()) {
1318       for (const auto& proxy_receiver :
1319            proxy_transceiver->internal()->receivers()) {
1320         if (proxy_receiver == selector) {
1321           internal_receiver = proxy_receiver->internal();
1322           break;
1323         }
1324       }
1325       if (internal_receiver)
1326         break;
1327     }
1328   }
1329   // If there is no `internal_receiver` then `selector` is either null or does
1330   // not belong to the PeerConnection (in Plan B, receivers can be removed from
1331   // the PeerConnection). This means that "all the stats objects representing
1332   // the selector" is an empty set. Invoking GetStatsReport() with a null
1333   // selector produces an empty stats report.
1334   stats_collector_->GetStatsReport(internal_receiver, callback);
1335   RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
1336 }
1337 
signaling_state()1338 PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
1339   RTC_DCHECK_RUN_ON(signaling_thread());
1340   return sdp_handler_->signaling_state();
1341 }
1342 
1343 PeerConnectionInterface::IceConnectionState
ice_connection_state()1344 PeerConnection::ice_connection_state() {
1345   RTC_DCHECK_RUN_ON(signaling_thread());
1346   return ice_connection_state_;
1347 }
1348 
1349 PeerConnectionInterface::IceConnectionState
standardized_ice_connection_state()1350 PeerConnection::standardized_ice_connection_state() {
1351   RTC_DCHECK_RUN_ON(signaling_thread());
1352   return standardized_ice_connection_state_;
1353 }
1354 
1355 PeerConnectionInterface::PeerConnectionState
peer_connection_state()1356 PeerConnection::peer_connection_state() {
1357   RTC_DCHECK_RUN_ON(signaling_thread());
1358   return connection_state_;
1359 }
1360 
1361 PeerConnectionInterface::IceGatheringState
ice_gathering_state()1362 PeerConnection::ice_gathering_state() {
1363   RTC_DCHECK_RUN_ON(signaling_thread());
1364   return ice_gathering_state_;
1365 }
1366 
can_trickle_ice_candidates()1367 absl::optional<bool> PeerConnection::can_trickle_ice_candidates() {
1368   RTC_DCHECK_RUN_ON(signaling_thread());
1369   const SessionDescriptionInterface* description = current_remote_description();
1370   if (!description) {
1371     description = pending_remote_description();
1372   }
1373   if (!description) {
1374     return absl::nullopt;
1375   }
1376   // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
1377   if (description->description()->transport_infos().size() < 1) {
1378     return absl::nullopt;
1379   }
1380   return description->description()->transport_infos()[0].description.HasOption(
1381       "trickle");
1382 }
1383 
1384 RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>
CreateDataChannelOrError(const std::string & label,const DataChannelInit * config)1385 PeerConnection::CreateDataChannelOrError(const std::string& label,
1386                                          const DataChannelInit* config) {
1387   RTC_DCHECK_RUN_ON(signaling_thread());
1388   TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
1389 
1390   bool first_datachannel = !data_channel_controller_.HasDataChannels();
1391 
1392   std::unique_ptr<InternalDataChannelInit> internal_config;
1393   if (config) {
1394     internal_config.reset(new InternalDataChannelInit(*config));
1395   }
1396   // TODO(bugs.webrtc.org/12796): Return a more specific error.
1397   rtc::scoped_refptr<DataChannelInterface> channel(
1398       data_channel_controller_.InternalCreateDataChannelWithProxy(
1399           label, internal_config.get()));
1400   if (!channel.get()) {
1401     return RTCError(RTCErrorType::INTERNAL_ERROR,
1402                     "Data channel creation failed");
1403   }
1404 
1405   // Trigger the onRenegotiationNeeded event for
1406   // the first SCTP DataChannel.
1407   if (first_datachannel) {
1408     sdp_handler_->UpdateNegotiationNeeded();
1409   }
1410   NoteUsageEvent(UsageEvent::DATA_ADDED);
1411   return channel;
1412 }
1413 
RestartIce()1414 void PeerConnection::RestartIce() {
1415   RTC_DCHECK_RUN_ON(signaling_thread());
1416   sdp_handler_->RestartIce();
1417 }
1418 
CreateOffer(CreateSessionDescriptionObserver * observer,const RTCOfferAnswerOptions & options)1419 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
1420                                  const RTCOfferAnswerOptions& options) {
1421   RTC_DCHECK_RUN_ON(signaling_thread());
1422   sdp_handler_->CreateOffer(observer, options);
1423 }
1424 
CreateAnswer(CreateSessionDescriptionObserver * observer,const RTCOfferAnswerOptions & options)1425 void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
1426                                   const RTCOfferAnswerOptions& options) {
1427   RTC_DCHECK_RUN_ON(signaling_thread());
1428   sdp_handler_->CreateAnswer(observer, options);
1429 }
1430 
SetLocalDescription(SetSessionDescriptionObserver * observer,SessionDescriptionInterface * desc_ptr)1431 void PeerConnection::SetLocalDescription(
1432     SetSessionDescriptionObserver* observer,
1433     SessionDescriptionInterface* desc_ptr) {
1434   RTC_DCHECK_RUN_ON(signaling_thread());
1435   sdp_handler_->SetLocalDescription(observer, desc_ptr);
1436 }
1437 
SetLocalDescription(std::unique_ptr<SessionDescriptionInterface> desc,rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer)1438 void PeerConnection::SetLocalDescription(
1439     std::unique_ptr<SessionDescriptionInterface> desc,
1440     rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1441   RTC_DCHECK_RUN_ON(signaling_thread());
1442   sdp_handler_->SetLocalDescription(std::move(desc), observer);
1443 }
1444 
SetLocalDescription(SetSessionDescriptionObserver * observer)1445 void PeerConnection::SetLocalDescription(
1446     SetSessionDescriptionObserver* observer) {
1447   RTC_DCHECK_RUN_ON(signaling_thread());
1448   sdp_handler_->SetLocalDescription(observer);
1449 }
1450 
SetLocalDescription(rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer)1451 void PeerConnection::SetLocalDescription(
1452     rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1453   RTC_DCHECK_RUN_ON(signaling_thread());
1454   sdp_handler_->SetLocalDescription(observer);
1455 }
1456 
SetRemoteDescription(SetSessionDescriptionObserver * observer,SessionDescriptionInterface * desc_ptr)1457 void PeerConnection::SetRemoteDescription(
1458     SetSessionDescriptionObserver* observer,
1459     SessionDescriptionInterface* desc_ptr) {
1460   RTC_DCHECK_RUN_ON(signaling_thread());
1461   sdp_handler_->SetRemoteDescription(observer, desc_ptr);
1462 }
1463 
SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer)1464 void PeerConnection::SetRemoteDescription(
1465     std::unique_ptr<SessionDescriptionInterface> desc,
1466     rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
1467   RTC_DCHECK_RUN_ON(signaling_thread());
1468   sdp_handler_->SetRemoteDescription(std::move(desc), observer);
1469 }
1470 
GetConfiguration()1471 PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
1472   RTC_DCHECK_RUN_ON(signaling_thread());
1473   return configuration_;
1474 }
1475 
SetConfiguration(const RTCConfiguration & configuration)1476 RTCError PeerConnection::SetConfiguration(
1477     const RTCConfiguration& configuration) {
1478   RTC_DCHECK_RUN_ON(signaling_thread());
1479   TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
1480   if (IsClosed()) {
1481     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1482                          "SetConfiguration: PeerConnection is closed.");
1483   }
1484 
1485   // According to JSEP, after setLocalDescription, changing the candidate pool
1486   // size is not allowed, and changing the set of ICE servers will not result
1487   // in new candidates being gathered.
1488   if (local_description() && configuration.ice_candidate_pool_size !=
1489                                  configuration_.ice_candidate_pool_size) {
1490     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1491                          "Can't change candidate pool size after calling "
1492                          "SetLocalDescription.");
1493   }
1494 
1495   if (local_description() &&
1496       configuration.crypto_options != configuration_.crypto_options) {
1497     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1498                          "Can't change crypto_options after calling "
1499                          "SetLocalDescription.");
1500   }
1501 
1502   // The simplest (and most future-compatible) way to tell if the config was
1503   // modified in an invalid way is to copy each property we do support
1504   // modifying, then use operator==. There are far more properties we don't
1505   // support modifying than those we do, and more could be added.
1506   RTCConfiguration modified_config = configuration_;
1507   modified_config.servers = configuration.servers;
1508   modified_config.type = configuration.type;
1509   modified_config.ice_candidate_pool_size =
1510       configuration.ice_candidate_pool_size;
1511   modified_config.prune_turn_ports = configuration.prune_turn_ports;
1512   modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy;
1513   modified_config.surface_ice_candidates_on_ice_transport_type_changed =
1514       configuration.surface_ice_candidates_on_ice_transport_type_changed;
1515   modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
1516   modified_config.ice_check_interval_strong_connectivity =
1517       configuration.ice_check_interval_strong_connectivity;
1518   modified_config.ice_check_interval_weak_connectivity =
1519       configuration.ice_check_interval_weak_connectivity;
1520   modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
1521   modified_config.ice_unwritable_min_checks =
1522       configuration.ice_unwritable_min_checks;
1523   modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
1524   modified_config.stun_candidate_keepalive_interval =
1525       configuration.stun_candidate_keepalive_interval;
1526   modified_config.turn_customizer = configuration.turn_customizer;
1527   modified_config.network_preference = configuration.network_preference;
1528   modified_config.active_reset_srtp_params =
1529       configuration.active_reset_srtp_params;
1530   modified_config.turn_logging_id = configuration.turn_logging_id;
1531   modified_config.allow_codec_switching = configuration.allow_codec_switching;
1532   modified_config.stable_writable_connection_ping_interval_ms =
1533       configuration.stable_writable_connection_ping_interval_ms;
1534   if (configuration != modified_config) {
1535     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1536                          "Modifying the configuration in an unsupported way.");
1537   }
1538 
1539   // Validate the modified configuration.
1540   RTCError validate_error = ValidateConfiguration(modified_config);
1541   if (!validate_error.ok()) {
1542     return validate_error;
1543   }
1544 
1545   // Note that this isn't possible through chromium, since it's an unsigned
1546   // short in WebIDL.
1547   if (configuration.ice_candidate_pool_size < 0 ||
1548       configuration.ice_candidate_pool_size > static_cast<int>(UINT16_MAX)) {
1549     return RTCError(RTCErrorType::INVALID_RANGE);
1550   }
1551 
1552   // Parse ICE servers before hopping to network thread.
1553   cricket::ServerAddresses stun_servers;
1554   std::vector<cricket::RelayServerConfig> turn_servers;
1555   RTCError parse_error = ParseIceServersOrError(configuration.servers,
1556                                                 &stun_servers, &turn_servers);
1557   if (!parse_error.ok()) {
1558     return parse_error;
1559   }
1560 
1561   // Restrict number of TURN servers.
1562   if (!trials().IsDisabled("WebRTC-LimitTurnServers") &&
1563       turn_servers.size() > cricket::kMaxTurnServers) {
1564     RTC_LOG(LS_WARNING) << "Number of configured TURN servers is "
1565                         << turn_servers.size()
1566                         << " which exceeds the maximum allowed number of "
1567                         << cricket::kMaxTurnServers;
1568     turn_servers.resize(cricket::kMaxTurnServers);
1569   }
1570 
1571   // Add the turn logging id to all turn servers
1572   for (cricket::RelayServerConfig& turn_server : turn_servers) {
1573     turn_server.turn_logging_id = configuration.turn_logging_id;
1574   }
1575 
1576   // Note if STUN or TURN servers were supplied.
1577   if (!stun_servers.empty()) {
1578     NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
1579   }
1580   if (!turn_servers.empty()) {
1581     NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
1582   }
1583 
1584   const bool has_local_description = local_description() != nullptr;
1585 
1586   const bool needs_ice_restart =
1587       modified_config.servers != configuration_.servers ||
1588       NeedIceRestart(
1589           configuration_.surface_ice_candidates_on_ice_transport_type_changed,
1590           configuration_.type, modified_config.type) ||
1591       modified_config.GetTurnPortPrunePolicy() !=
1592           configuration_.GetTurnPortPrunePolicy();
1593   cricket::IceConfig ice_config = ParseIceConfig(modified_config);
1594 
1595   // Apply part of the configuration on the network thread.  In theory this
1596   // shouldn't fail.
1597   if (!network_thread()->BlockingCall(
1598           [this, needs_ice_restart, &ice_config, &stun_servers, &turn_servers,
1599            &modified_config, has_local_description] {
1600             RTC_DCHECK_RUN_ON(network_thread());
1601             // As described in JSEP, calling setConfiguration with new ICE
1602             // servers or candidate policy must set a "needs-ice-restart" bit so
1603             // that the next offer triggers an ICE restart which will pick up
1604             // the changes.
1605             if (needs_ice_restart)
1606               transport_controller_->SetNeedsIceRestartFlag();
1607 
1608             transport_controller_->SetIceConfig(ice_config);
1609             return ReconfigurePortAllocator_n(
1610                 stun_servers, turn_servers, modified_config.type,
1611                 modified_config.ice_candidate_pool_size,
1612                 modified_config.GetTurnPortPrunePolicy(),
1613                 modified_config.turn_customizer,
1614                 modified_config.stun_candidate_keepalive_interval,
1615                 has_local_description);
1616           })) {
1617     LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
1618                          "Failed to apply configuration to PortAllocator.");
1619   }
1620 
1621   if (configuration_.active_reset_srtp_params !=
1622       modified_config.active_reset_srtp_params) {
1623     // TODO(tommi): merge BlockingCalls
1624     network_thread()->BlockingCall([this, &modified_config] {
1625       RTC_DCHECK_RUN_ON(network_thread());
1626       transport_controller_->SetActiveResetSrtpParams(
1627           modified_config.active_reset_srtp_params);
1628     });
1629   }
1630 
1631   if (modified_config.allow_codec_switching.has_value()) {
1632     std::vector<cricket::VideoMediaChannel*> channels;
1633     for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1634       if (transceiver->media_type() != cricket::MEDIA_TYPE_VIDEO)
1635         continue;
1636 
1637       auto* video_channel = transceiver->internal()->channel();
1638       if (video_channel)
1639         channels.push_back(static_cast<cricket::VideoMediaChannel*>(
1640             video_channel->media_channel()));
1641     }
1642 
1643     worker_thread()->BlockingCall(
1644         [channels = std::move(channels),
1645          allow_codec_switching = *modified_config.allow_codec_switching]() {
1646           for (auto* ch : channels)
1647             ch->SetVideoCodecSwitchingEnabled(allow_codec_switching);
1648         });
1649   }
1650 
1651   configuration_ = modified_config;
1652   return RTCError::OK();
1653 }
1654 
AddIceCandidate(const IceCandidateInterface * ice_candidate)1655 bool PeerConnection::AddIceCandidate(
1656     const IceCandidateInterface* ice_candidate) {
1657   RTC_DCHECK_RUN_ON(signaling_thread());
1658   ClearStatsCache();
1659   return sdp_handler_->AddIceCandidate(ice_candidate);
1660 }
1661 
AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate,std::function<void (RTCError)> callback)1662 void PeerConnection::AddIceCandidate(
1663     std::unique_ptr<IceCandidateInterface> candidate,
1664     std::function<void(RTCError)> callback) {
1665   RTC_DCHECK_RUN_ON(signaling_thread());
1666   sdp_handler_->AddIceCandidate(std::move(candidate),
1667                                 [this, callback](webrtc::RTCError result) {
1668                                   ClearStatsCache();
1669                                   callback(result);
1670                                 });
1671 }
1672 
RemoveIceCandidates(const std::vector<cricket::Candidate> & candidates)1673 bool PeerConnection::RemoveIceCandidates(
1674     const std::vector<cricket::Candidate>& candidates) {
1675   TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
1676   RTC_DCHECK_RUN_ON(signaling_thread());
1677   return sdp_handler_->RemoveIceCandidates(candidates);
1678 }
1679 
SetBitrate(const BitrateSettings & bitrate)1680 RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
1681   if (!worker_thread()->IsCurrent()) {
1682     return worker_thread()->BlockingCall([&]() { return SetBitrate(bitrate); });
1683   }
1684   RTC_DCHECK_RUN_ON(worker_thread());
1685 
1686   const bool has_min = bitrate.min_bitrate_bps.has_value();
1687   const bool has_start = bitrate.start_bitrate_bps.has_value();
1688   const bool has_max = bitrate.max_bitrate_bps.has_value();
1689   if (has_min && *bitrate.min_bitrate_bps < 0) {
1690     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1691                          "min_bitrate_bps <= 0");
1692   }
1693   if (has_start) {
1694     if (has_min && *bitrate.start_bitrate_bps < *bitrate.min_bitrate_bps) {
1695       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1696                            "start_bitrate_bps < min_bitrate_bps");
1697     } else if (*bitrate.start_bitrate_bps < 0) {
1698       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1699                            "curent_bitrate_bps < 0");
1700     }
1701   }
1702   if (has_max) {
1703     if (has_start && *bitrate.max_bitrate_bps < *bitrate.start_bitrate_bps) {
1704       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1705                            "max_bitrate_bps < start_bitrate_bps");
1706     } else if (has_min && *bitrate.max_bitrate_bps < *bitrate.min_bitrate_bps) {
1707       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1708                            "max_bitrate_bps < min_bitrate_bps");
1709     } else if (*bitrate.max_bitrate_bps < 0) {
1710       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1711                            "max_bitrate_bps < 0");
1712     }
1713   }
1714 
1715   RTC_DCHECK(call_.get());
1716   call_->SetClientBitratePreferences(bitrate);
1717 
1718   return RTCError::OK();
1719 }
1720 
SetAudioPlayout(bool playout)1721 void PeerConnection::SetAudioPlayout(bool playout) {
1722   if (!worker_thread()->IsCurrent()) {
1723     worker_thread()->BlockingCall(
1724         [this, playout] { SetAudioPlayout(playout); });
1725     return;
1726   }
1727   auto audio_state = context_->media_engine()->voice().GetAudioState();
1728   audio_state->SetPlayout(playout);
1729 }
1730 
SetAudioRecording(bool recording)1731 void PeerConnection::SetAudioRecording(bool recording) {
1732   if (!worker_thread()->IsCurrent()) {
1733     worker_thread()->BlockingCall(
1734         [this, recording] { SetAudioRecording(recording); });
1735     return;
1736   }
1737   auto audio_state = context_->media_engine()->voice().GetAudioState();
1738   audio_state->SetRecording(recording);
1739 }
1740 
AddAdaptationResource(rtc::scoped_refptr<Resource> resource)1741 void PeerConnection::AddAdaptationResource(
1742     rtc::scoped_refptr<Resource> resource) {
1743   if (!worker_thread()->IsCurrent()) {
1744     return worker_thread()->BlockingCall(
1745         [this, resource]() { return AddAdaptationResource(resource); });
1746   }
1747   RTC_DCHECK_RUN_ON(worker_thread());
1748   if (!call_) {
1749     // The PeerConnection has been closed.
1750     return;
1751   }
1752   call_->AddAdaptationResource(resource);
1753 }
1754 
ConfiguredForMedia() const1755 bool PeerConnection::ConfiguredForMedia() const {
1756   return context_->media_engine();
1757 }
1758 
StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,int64_t output_period_ms)1759 bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
1760                                       int64_t output_period_ms) {
1761   return worker_thread()->BlockingCall(
1762       [this, output = std::move(output), output_period_ms]() mutable {
1763         return StartRtcEventLog_w(std::move(output), output_period_ms);
1764       });
1765 }
1766 
StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output)1767 bool PeerConnection::StartRtcEventLog(
1768     std::unique_ptr<RtcEventLogOutput> output) {
1769   int64_t output_period_ms = webrtc::RtcEventLog::kImmediateOutput;
1770   if (trials().IsEnabled("WebRTC-RtcEventLogNewFormat")) {
1771     output_period_ms = 5000;
1772   }
1773   return StartRtcEventLog(std::move(output), output_period_ms);
1774 }
1775 
StopRtcEventLog()1776 void PeerConnection::StopRtcEventLog() {
1777   worker_thread()->BlockingCall([this] { StopRtcEventLog_w(); });
1778 }
1779 
1780 rtc::scoped_refptr<DtlsTransportInterface>
LookupDtlsTransportByMid(const std::string & mid)1781 PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
1782   RTC_DCHECK_RUN_ON(network_thread());
1783   return transport_controller_->LookupDtlsTransportByMid(mid);
1784 }
1785 
1786 rtc::scoped_refptr<DtlsTransport>
LookupDtlsTransportByMidInternal(const std::string & mid)1787 PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
1788   RTC_DCHECK_RUN_ON(signaling_thread());
1789   // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
1790   // This might be done by caching the value on the signaling thread.
1791   return network_thread()->BlockingCall([this, mid]() {
1792     RTC_DCHECK_RUN_ON(network_thread());
1793     return transport_controller_->LookupDtlsTransportByMid(mid);
1794   });
1795 }
1796 
GetSctpTransport() const1797 rtc::scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport()
1798     const {
1799   RTC_DCHECK_RUN_ON(network_thread());
1800   if (!sctp_mid_n_)
1801     return nullptr;
1802 
1803   return transport_controller_->GetSctpTransport(*sctp_mid_n_);
1804 }
1805 
local_description() const1806 const SessionDescriptionInterface* PeerConnection::local_description() const {
1807   RTC_DCHECK_RUN_ON(signaling_thread());
1808   return sdp_handler_->local_description();
1809 }
1810 
remote_description() const1811 const SessionDescriptionInterface* PeerConnection::remote_description() const {
1812   RTC_DCHECK_RUN_ON(signaling_thread());
1813   return sdp_handler_->remote_description();
1814 }
1815 
current_local_description() const1816 const SessionDescriptionInterface* PeerConnection::current_local_description()
1817     const {
1818   RTC_DCHECK_RUN_ON(signaling_thread());
1819   return sdp_handler_->current_local_description();
1820 }
1821 
current_remote_description() const1822 const SessionDescriptionInterface* PeerConnection::current_remote_description()
1823     const {
1824   RTC_DCHECK_RUN_ON(signaling_thread());
1825   return sdp_handler_->current_remote_description();
1826 }
1827 
pending_local_description() const1828 const SessionDescriptionInterface* PeerConnection::pending_local_description()
1829     const {
1830   RTC_DCHECK_RUN_ON(signaling_thread());
1831   return sdp_handler_->pending_local_description();
1832 }
1833 
pending_remote_description() const1834 const SessionDescriptionInterface* PeerConnection::pending_remote_description()
1835     const {
1836   RTC_DCHECK_RUN_ON(signaling_thread());
1837   return sdp_handler_->pending_remote_description();
1838 }
1839 
Close()1840 void PeerConnection::Close() {
1841   RTC_DCHECK_RUN_ON(signaling_thread());
1842   TRACE_EVENT0("webrtc", "PeerConnection::Close");
1843 
1844   RTC_LOG_THREAD_BLOCK_COUNT();
1845 
1846   if (IsClosed()) {
1847     return;
1848   }
1849   // Update stats here so that we have the most recent stats for tracks and
1850   // streams before the channels are closed.
1851   legacy_stats_->UpdateStats(kStatsOutputLevelStandard);
1852 
1853   ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed;
1854   Observer()->OnIceConnectionChange(ice_connection_state_);
1855   standardized_ice_connection_state_ =
1856       PeerConnectionInterface::IceConnectionState::kIceConnectionClosed;
1857   connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
1858   Observer()->OnConnectionChange(connection_state_);
1859 
1860   sdp_handler_->Close();
1861 
1862   NoteUsageEvent(UsageEvent::CLOSE_CALLED);
1863 
1864   if (ConfiguredForMedia()) {
1865     for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1866       transceiver->internal()->SetPeerConnectionClosed();
1867       if (!transceiver->stopped())
1868         transceiver->StopInternal();
1869     }
1870   }
1871   // Ensure that all asynchronous stats requests are completed before destroying
1872   // the transport controller below.
1873   if (stats_collector_) {
1874     stats_collector_->WaitForPendingRequest();
1875   }
1876 
1877   // Don't destroy BaseChannels until after stats has been cleaned up so that
1878   // the last stats request can still read from the channels.
1879   sdp_handler_->DestroyAllChannels();
1880 
1881   // The event log is used in the transport controller, which must be outlived
1882   // by the former. CreateOffer by the peer connection is implemented
1883   // asynchronously and if the peer connection is closed without resetting the
1884   // WebRTC session description factory, the session description factory would
1885   // call the transport controller.
1886   sdp_handler_->ResetSessionDescFactory();
1887   if (ConfiguredForMedia()) {
1888     rtp_manager_->Close();
1889   }
1890 
1891   network_thread()->BlockingCall([this] {
1892     // Data channels will already have been unset via the DestroyAllChannels()
1893     // call above, which triggers a call to TeardownDataChannelTransport_n().
1894     // TODO(tommi): ^^ That's not exactly optimal since this is yet another
1895     // blocking hop to the network thread during Close(). Further still, the
1896     // voice/video/data channels will be cleared on the worker thread.
1897     RTC_DCHECK_RUN_ON(network_thread());
1898     transport_controller_.reset();
1899     port_allocator_->DiscardCandidatePool();
1900     if (network_thread_safety_) {
1901       network_thread_safety_->SetNotAlive();
1902     }
1903   });
1904 
1905   worker_thread()->BlockingCall([this] {
1906     RTC_DCHECK_RUN_ON(worker_thread());
1907     worker_thread_safety_->SetNotAlive();
1908     call_.reset();
1909     // The event log must outlive call (and any other object that uses it).
1910     event_log_.reset();
1911   });
1912   ReportUsagePattern();
1913   // The .h file says that observer can be discarded after close() returns.
1914   // Make sure this is true.
1915   observer_ = nullptr;
1916 
1917   // Signal shutdown to the sdp handler. This invalidates weak pointers for
1918   // internal pending callbacks.
1919   sdp_handler_->PrepareForShutdown();
1920 }
1921 
SetIceConnectionState(IceConnectionState new_state)1922 void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
1923   RTC_DCHECK_RUN_ON(signaling_thread());
1924   if (ice_connection_state_ == new_state) {
1925     return;
1926   }
1927 
1928   // After transitioning to "closed", ignore any additional states from
1929   // TransportController (such as "disconnected").
1930   if (IsClosed()) {
1931     return;
1932   }
1933 
1934   RTC_LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1935                    << " => " << new_state;
1936   RTC_DCHECK(ice_connection_state_ !=
1937              PeerConnectionInterface::kIceConnectionClosed);
1938 
1939   ice_connection_state_ = new_state;
1940   Observer()->OnIceConnectionChange(ice_connection_state_);
1941 }
1942 
SetStandardizedIceConnectionState(PeerConnectionInterface::IceConnectionState new_state)1943 void PeerConnection::SetStandardizedIceConnectionState(
1944     PeerConnectionInterface::IceConnectionState new_state) {
1945   if (standardized_ice_connection_state_ == new_state) {
1946     return;
1947   }
1948 
1949   if (IsClosed()) {
1950     return;
1951   }
1952 
1953   RTC_LOG(LS_INFO) << "Changing standardized IceConnectionState "
1954                    << standardized_ice_connection_state_ << " => " << new_state;
1955 
1956   standardized_ice_connection_state_ = new_state;
1957   Observer()->OnStandardizedIceConnectionChange(new_state);
1958 }
1959 
SetConnectionState(PeerConnectionInterface::PeerConnectionState new_state)1960 void PeerConnection::SetConnectionState(
1961     PeerConnectionInterface::PeerConnectionState new_state) {
1962   if (connection_state_ == new_state)
1963     return;
1964   if (IsClosed())
1965     return;
1966   connection_state_ = new_state;
1967   Observer()->OnConnectionChange(new_state);
1968 
1969   // The first connection state change to connected happens once per
1970   // connection which makes it a good point to report metrics.
1971   if (new_state == PeerConnectionState::kConnected && !was_ever_connected_) {
1972     was_ever_connected_ = true;
1973     ReportFirstConnectUsageMetrics();
1974   }
1975 }
1976 
ReportFirstConnectUsageMetrics()1977 void PeerConnection::ReportFirstConnectUsageMetrics() {
1978   // Record bundle-policy from configuration. Done here from
1979   // connectionStateChange to limit to actually established connections.
1980   BundlePolicyUsage policy = kBundlePolicyUsageMax;
1981   switch (configuration_.bundle_policy) {
1982     case kBundlePolicyBalanced:
1983       policy = kBundlePolicyUsageBalanced;
1984       break;
1985     case kBundlePolicyMaxBundle:
1986       policy = kBundlePolicyUsageMaxBundle;
1987       break;
1988     case kBundlePolicyMaxCompat:
1989       policy = kBundlePolicyUsageMaxCompat;
1990       break;
1991   }
1992   RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundlePolicy", policy,
1993                             kBundlePolicyUsageMax);
1994 
1995   // Record whether there was a local or remote provisional answer.
1996   ProvisionalAnswerUsage pranswer = kProvisionalAnswerNotUsed;
1997   if (local_description()->GetType() == SdpType::kPrAnswer) {
1998     pranswer = kProvisionalAnswerLocal;
1999   } else if (remote_description()->GetType() == SdpType::kPrAnswer) {
2000     pranswer = kProvisionalAnswerRemote;
2001   }
2002   RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ProvisionalAnswer", pranswer,
2003                             kProvisionalAnswerMax);
2004 
2005   // Record the number of valid / invalid ice-ufrag. We do allow certain
2006   // non-spec ice-char for backward-compat reasons. At this point we know
2007   // that the ufrag/pwd consists of a valid ice-char or one of the four
2008   // not allowed characters since we have passed the IsIceChar check done
2009   // by the p2p transport description on setRemoteDescription calls.
2010   auto transport_infos = remote_description()->description()->transport_infos();
2011   if (transport_infos.size() > 0) {
2012     auto ice_parameters = transport_infos[0].description.GetIceParameters();
2013     auto is_invalid_char = [](char c) {
2014       return c == '-' || c == '=' || c == '#' || c == '_';
2015     };
2016     bool isUsingInvalidIceCharInUfrag =
2017         absl::c_any_of(ice_parameters.ufrag, is_invalid_char);
2018     bool isUsingInvalidIceCharInPwd =
2019         absl::c_any_of(ice_parameters.pwd, is_invalid_char);
2020     RTC_HISTOGRAM_BOOLEAN(
2021         "WebRTC.PeerConnection.ValidIceChars",
2022         !(isUsingInvalidIceCharInUfrag || isUsingInvalidIceCharInPwd));
2023   }
2024 }
2025 
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)2026 void PeerConnection::OnIceGatheringChange(
2027     PeerConnectionInterface::IceGatheringState new_state) {
2028   if (IsClosed()) {
2029     return;
2030   }
2031   ice_gathering_state_ = new_state;
2032   Observer()->OnIceGatheringChange(ice_gathering_state_);
2033 }
2034 
OnIceCandidate(std::unique_ptr<IceCandidateInterface> candidate)2035 void PeerConnection::OnIceCandidate(
2036     std::unique_ptr<IceCandidateInterface> candidate) {
2037   if (IsClosed()) {
2038     return;
2039   }
2040   ReportIceCandidateCollected(candidate->candidate());
2041   ClearStatsCache();
2042   Observer()->OnIceCandidate(candidate.get());
2043 }
2044 
OnIceCandidateError(const std::string & address,int port,const std::string & url,int error_code,const std::string & error_text)2045 void PeerConnection::OnIceCandidateError(const std::string& address,
2046                                          int port,
2047                                          const std::string& url,
2048                                          int error_code,
2049                                          const std::string& error_text) {
2050   if (IsClosed()) {
2051     return;
2052   }
2053   Observer()->OnIceCandidateError(address, port, url, error_code, error_text);
2054 }
2055 
OnIceCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)2056 void PeerConnection::OnIceCandidatesRemoved(
2057     const std::vector<cricket::Candidate>& candidates) {
2058   if (IsClosed()) {
2059     return;
2060   }
2061   Observer()->OnIceCandidatesRemoved(candidates);
2062 }
2063 
OnSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent & event)2064 void PeerConnection::OnSelectedCandidatePairChanged(
2065     const cricket::CandidatePairChangeEvent& event) {
2066   if (IsClosed()) {
2067     return;
2068   }
2069 
2070   if (event.selected_candidate_pair.local_candidate().type() ==
2071           LOCAL_PORT_TYPE &&
2072       event.selected_candidate_pair.remote_candidate().type() ==
2073           LOCAL_PORT_TYPE) {
2074     NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
2075   }
2076 
2077   Observer()->OnIceSelectedCandidatePairChanged(event);
2078 }
2079 
GetDataMid() const2080 absl::optional<std::string> PeerConnection::GetDataMid() const {
2081   RTC_DCHECK_RUN_ON(signaling_thread());
2082   return sctp_mid_s_;
2083 }
2084 
SetSctpDataMid(const std::string & mid)2085 void PeerConnection::SetSctpDataMid(const std::string& mid) {
2086   RTC_DCHECK_RUN_ON(signaling_thread());
2087   sctp_mid_s_ = mid;
2088 }
2089 
ResetSctpDataMid()2090 void PeerConnection::ResetSctpDataMid() {
2091   RTC_DCHECK_RUN_ON(signaling_thread());
2092   sctp_mid_s_.reset();
2093   sctp_transport_name_s_.clear();
2094 }
2095 
OnSctpDataChannelClosed(DataChannelInterface * channel)2096 void PeerConnection::OnSctpDataChannelClosed(DataChannelInterface* channel) {
2097   // Since data_channel_controller doesn't do signals, this
2098   // signal is relayed here.
2099   data_channel_controller_.OnSctpDataChannelClosed(
2100       static_cast<SctpDataChannel*>(channel));
2101 }
2102 
2103 PeerConnection::InitializePortAllocatorResult
InitializePortAllocator_n(const cricket::ServerAddresses & stun_servers,const std::vector<cricket::RelayServerConfig> & turn_servers,const RTCConfiguration & configuration)2104 PeerConnection::InitializePortAllocator_n(
2105     const cricket::ServerAddresses& stun_servers,
2106     const std::vector<cricket::RelayServerConfig>& turn_servers,
2107     const RTCConfiguration& configuration) {
2108   RTC_DCHECK_RUN_ON(network_thread());
2109 
2110   port_allocator_->Initialize();
2111   // To handle both internal and externally created port allocator, we will
2112   // enable BUNDLE here.
2113   int port_allocator_flags = port_allocator_->flags();
2114   port_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
2115                           cricket::PORTALLOCATOR_ENABLE_IPV6 |
2116                           cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI;
2117   if (trials().IsDisabled("WebRTC-IPv6Default")) {
2118     port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
2119   }
2120   if (configuration.disable_ipv6_on_wifi) {
2121     port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
2122     RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled.";
2123   }
2124 
2125   if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
2126     port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
2127     RTC_LOG(LS_INFO) << "TCP candidates are disabled.";
2128   }
2129 
2130   if (configuration.candidate_network_policy ==
2131       kCandidateNetworkPolicyLowCost) {
2132     port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
2133     RTC_LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
2134   }
2135 
2136   if (configuration.disable_link_local_networks) {
2137     port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS;
2138     RTC_LOG(LS_INFO) << "Disable candidates on link-local network interfaces.";
2139   }
2140 
2141   port_allocator_->set_flags(port_allocator_flags);
2142   // No step delay is used while allocating ports.
2143   port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
2144   port_allocator_->SetCandidateFilter(
2145       ConvertIceTransportTypeToCandidateFilter(configuration.type));
2146   port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);
2147 
2148   auto turn_servers_copy = turn_servers;
2149   for (auto& turn_server : turn_servers_copy) {
2150     turn_server.tls_cert_verifier = tls_cert_verifier_.get();
2151   }
2152   // Call this last since it may create pooled allocator sessions using the
2153   // properties set above.
2154   port_allocator_->SetConfiguration(
2155       stun_servers, std::move(turn_servers_copy),
2156       configuration.ice_candidate_pool_size,
2157       configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer,
2158       configuration.stun_candidate_keepalive_interval);
2159 
2160   InitializePortAllocatorResult res;
2161   res.enable_ipv6 = port_allocator_flags & cricket::PORTALLOCATOR_ENABLE_IPV6;
2162   return res;
2163 }
2164 
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)2165 bool PeerConnection::ReconfigurePortAllocator_n(
2166     const cricket::ServerAddresses& stun_servers,
2167     const std::vector<cricket::RelayServerConfig>& turn_servers,
2168     IceTransportsType type,
2169     int candidate_pool_size,
2170     PortPrunePolicy turn_port_prune_policy,
2171     webrtc::TurnCustomizer* turn_customizer,
2172     absl::optional<int> stun_candidate_keepalive_interval,
2173     bool have_local_description) {
2174   RTC_DCHECK_RUN_ON(network_thread());
2175   port_allocator_->SetCandidateFilter(
2176       ConvertIceTransportTypeToCandidateFilter(type));
2177   // According to JSEP, after setLocalDescription, changing the candidate pool
2178   // size is not allowed, and changing the set of ICE servers will not result
2179   // in new candidates being gathered.
2180   if (have_local_description) {
2181     port_allocator_->FreezeCandidatePool();
2182   }
2183   // Add the custom tls turn servers if they exist.
2184   auto turn_servers_copy = turn_servers;
2185   for (auto& turn_server : turn_servers_copy) {
2186     turn_server.tls_cert_verifier = tls_cert_verifier_.get();
2187   }
2188   // Call this last since it may create pooled allocator sessions using the
2189   // candidate filter set above.
2190   return port_allocator_->SetConfiguration(
2191       stun_servers, std::move(turn_servers_copy), candidate_pool_size,
2192       turn_port_prune_policy, turn_customizer,
2193       stun_candidate_keepalive_interval);
2194 }
2195 
StartRtcEventLog_w(std::unique_ptr<RtcEventLogOutput> output,int64_t output_period_ms)2196 bool PeerConnection::StartRtcEventLog_w(
2197     std::unique_ptr<RtcEventLogOutput> output,
2198     int64_t output_period_ms) {
2199   RTC_DCHECK_RUN_ON(worker_thread());
2200   if (!event_log_) {
2201     return false;
2202   }
2203   return event_log_->StartLogging(std::move(output), output_period_ms);
2204 }
2205 
StopRtcEventLog_w()2206 void PeerConnection::StopRtcEventLog_w() {
2207   RTC_DCHECK_RUN_ON(worker_thread());
2208   if (event_log_) {
2209     event_log_->StopLogging();
2210   }
2211 }
2212 
GetSctpSslRole(rtc::SSLRole * role)2213 bool PeerConnection::GetSctpSslRole(rtc::SSLRole* role) {
2214   RTC_DCHECK_RUN_ON(signaling_thread());
2215   if (!local_description() || !remote_description()) {
2216     RTC_LOG(LS_VERBOSE)
2217         << "Local and Remote descriptions must be applied to get the "
2218            "SSL Role of the SCTP transport.";
2219     return false;
2220   }
2221   if (!data_channel_controller_.data_channel_transport()) {
2222     RTC_LOG(LS_INFO) << "Non-rejected SCTP m= section is needed to get the "
2223                         "SSL Role of the SCTP transport.";
2224     return false;
2225   }
2226 
2227   absl::optional<rtc::SSLRole> dtls_role;
2228   if (sctp_mid_s_) {
2229     dtls_role = network_thread()->BlockingCall([this] {
2230       RTC_DCHECK_RUN_ON(network_thread());
2231       return transport_controller_->GetDtlsRole(*sctp_mid_n_);
2232     });
2233     if (!dtls_role && sdp_handler_->is_caller().has_value()) {
2234       // This works fine if we are the offerer, but can be a mistake if
2235       // we are the answerer and the remote offer is ACTIVE. In that
2236       // case, we will guess the role wrong.
2237       // TODO(bugs.webrtc.org/13668): Check if this actually happens.
2238       RTC_LOG(LS_ERROR)
2239           << "Possible risk: DTLS role guesser is active, is_caller is "
2240           << *sdp_handler_->is_caller();
2241       dtls_role =
2242           *sdp_handler_->is_caller() ? rtc::SSL_SERVER : rtc::SSL_CLIENT;
2243     }
2244     if (dtls_role) {
2245       *role = *dtls_role;
2246       return true;
2247     }
2248   }
2249   return false;
2250 }
2251 
GetSslRole(const std::string & content_name,rtc::SSLRole * role)2252 bool PeerConnection::GetSslRole(const std::string& content_name,
2253                                 rtc::SSLRole* role) {
2254   RTC_DCHECK_RUN_ON(signaling_thread());
2255   if (!local_description() || !remote_description()) {
2256     RTC_LOG(LS_INFO)
2257         << "Local and Remote descriptions must be applied to get the "
2258            "SSL Role of the session.";
2259     return false;
2260   }
2261 
2262   auto dtls_role = network_thread()->BlockingCall([this, content_name]() {
2263     RTC_DCHECK_RUN_ON(network_thread());
2264     return transport_controller_->GetDtlsRole(content_name);
2265   });
2266   if (dtls_role) {
2267     *role = *dtls_role;
2268     return true;
2269   }
2270   return false;
2271 }
2272 
GetTransportDescription(const SessionDescription * description,const std::string & content_name,cricket::TransportDescription * tdesc)2273 bool PeerConnection::GetTransportDescription(
2274     const SessionDescription* description,
2275     const std::string& content_name,
2276     cricket::TransportDescription* tdesc) {
2277   if (!description || !tdesc) {
2278     return false;
2279   }
2280   const TransportInfo* transport_info =
2281       description->GetTransportInfoByName(content_name);
2282   if (!transport_info) {
2283     return false;
2284   }
2285   *tdesc = transport_info->description;
2286   return true;
2287 }
2288 
GetDataChannelStats() const2289 std::vector<DataChannelStats> PeerConnection::GetDataChannelStats() const {
2290   RTC_DCHECK_RUN_ON(signaling_thread());
2291   return data_channel_controller_.GetDataChannelStats();
2292 }
2293 
sctp_transport_name() const2294 absl::optional<std::string> PeerConnection::sctp_transport_name() const {
2295   RTC_DCHECK_RUN_ON(signaling_thread());
2296   if (sctp_mid_s_ && transport_controller_copy_)
2297     return sctp_transport_name_s_;
2298   return absl::optional<std::string>();
2299 }
2300 
sctp_mid() const2301 absl::optional<std::string> PeerConnection::sctp_mid() const {
2302   RTC_DCHECK_RUN_ON(signaling_thread());
2303   return sctp_mid_s_;
2304 }
2305 
GetPooledCandidateStats() const2306 cricket::CandidateStatsList PeerConnection::GetPooledCandidateStats() const {
2307   RTC_DCHECK_RUN_ON(network_thread());
2308   if (!network_thread_safety_->alive())
2309     return {};
2310   cricket::CandidateStatsList candidate_stats_list;
2311   port_allocator_->GetCandidateStatsFromPooledSessions(&candidate_stats_list);
2312   return candidate_stats_list;
2313 }
2314 
2315 std::map<std::string, cricket::TransportStats>
GetTransportStatsByNames(const std::set<std::string> & transport_names)2316 PeerConnection::GetTransportStatsByNames(
2317     const std::set<std::string>& transport_names) {
2318   TRACE_EVENT0("webrtc", "PeerConnection::GetTransportStatsByNames");
2319   RTC_DCHECK_RUN_ON(network_thread());
2320   if (!network_thread_safety_->alive())
2321     return {};
2322 
2323   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
2324   std::map<std::string, cricket::TransportStats> transport_stats_by_name;
2325   for (const std::string& transport_name : transport_names) {
2326     cricket::TransportStats transport_stats;
2327     bool success =
2328         transport_controller_->GetStats(transport_name, &transport_stats);
2329     if (success) {
2330       transport_stats_by_name[transport_name] = std::move(transport_stats);
2331     } else {
2332       RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
2333                         << transport_name;
2334     }
2335   }
2336   return transport_stats_by_name;
2337 }
2338 
GetLocalCertificate(const std::string & transport_name,rtc::scoped_refptr<rtc::RTCCertificate> * certificate)2339 bool PeerConnection::GetLocalCertificate(
2340     const std::string& transport_name,
2341     rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
2342   RTC_DCHECK_RUN_ON(network_thread());
2343   if (!network_thread_safety_->alive() || !certificate) {
2344     return false;
2345   }
2346   *certificate = transport_controller_->GetLocalCertificate(transport_name);
2347   return *certificate != nullptr;
2348 }
2349 
GetRemoteSSLCertChain(const std::string & transport_name)2350 std::unique_ptr<rtc::SSLCertChain> PeerConnection::GetRemoteSSLCertChain(
2351     const std::string& transport_name) {
2352   RTC_DCHECK_RUN_ON(network_thread());
2353   return transport_controller_->GetRemoteSSLCertChain(transport_name);
2354 }
2355 
IceRestartPending(const std::string & content_name) const2356 bool PeerConnection::IceRestartPending(const std::string& content_name) const {
2357   RTC_DCHECK_RUN_ON(signaling_thread());
2358   return sdp_handler_->IceRestartPending(content_name);
2359 }
2360 
NeedsIceRestart(const std::string & content_name) const2361 bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
2362   return network_thread()->BlockingCall([this, &content_name] {
2363     RTC_DCHECK_RUN_ON(network_thread());
2364     return transport_controller_->NeedsIceRestart(content_name);
2365   });
2366 }
2367 
OnTransportControllerConnectionState(cricket::IceConnectionState state)2368 void PeerConnection::OnTransportControllerConnectionState(
2369     cricket::IceConnectionState state) {
2370   switch (state) {
2371     case cricket::kIceConnectionConnecting:
2372       // If the current state is Connected or Completed, then there were
2373       // writable channels but now there are not, so the next state must
2374       // be Disconnected.
2375       // kIceConnectionConnecting is currently used as the default,
2376       // un-connected state by the TransportController, so its only use is
2377       // detecting disconnections.
2378       if (ice_connection_state_ ==
2379               PeerConnectionInterface::kIceConnectionConnected ||
2380           ice_connection_state_ ==
2381               PeerConnectionInterface::kIceConnectionCompleted) {
2382         SetIceConnectionState(
2383             PeerConnectionInterface::kIceConnectionDisconnected);
2384       }
2385       break;
2386     case cricket::kIceConnectionFailed:
2387       SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
2388       break;
2389     case cricket::kIceConnectionConnected:
2390       RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
2391                           "all transports are writable.";
2392       SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2393       NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2394       break;
2395     case cricket::kIceConnectionCompleted:
2396       RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
2397                           "all transports are complete.";
2398       if (ice_connection_state_ !=
2399           PeerConnectionInterface::kIceConnectionConnected) {
2400         // If jumping directly from "checking" to "connected",
2401         // signal "connected" first.
2402         SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2403       }
2404       SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
2405 
2406       NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2407       break;
2408     default:
2409       RTC_DCHECK_NOTREACHED();
2410   }
2411 }
2412 
OnTransportControllerCandidatesGathered(const std::string & transport_name,const cricket::Candidates & candidates)2413 void PeerConnection::OnTransportControllerCandidatesGathered(
2414     const std::string& transport_name,
2415     const cricket::Candidates& candidates) {
2416   // TODO(bugs.webrtc.org/12427): Expect this to come in on the network thread
2417   // (not signaling as it currently does), handle appropriately.
2418   int sdp_mline_index;
2419   if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
2420     RTC_LOG(LS_ERROR)
2421         << "OnTransportControllerCandidatesGathered: content name "
2422         << transport_name << " not found";
2423     return;
2424   }
2425 
2426   for (cricket::Candidates::const_iterator citer = candidates.begin();
2427        citer != candidates.end(); ++citer) {
2428     // Use transport_name as the candidate media id.
2429     std::unique_ptr<JsepIceCandidate> candidate(
2430         new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
2431     sdp_handler_->AddLocalIceCandidate(candidate.get());
2432     OnIceCandidate(std::move(candidate));
2433   }
2434 }
2435 
OnTransportControllerCandidateError(const cricket::IceCandidateErrorEvent & event)2436 void PeerConnection::OnTransportControllerCandidateError(
2437     const cricket::IceCandidateErrorEvent& event) {
2438   OnIceCandidateError(event.address, event.port, event.url, event.error_code,
2439                       event.error_text);
2440 }
2441 
OnTransportControllerCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)2442 void PeerConnection::OnTransportControllerCandidatesRemoved(
2443     const std::vector<cricket::Candidate>& candidates) {
2444   // Sanity check.
2445   for (const cricket::Candidate& candidate : candidates) {
2446     if (candidate.transport_name().empty()) {
2447       RTC_LOG(LS_ERROR) << "OnTransportControllerCandidatesRemoved: "
2448                            "empty content name in candidate "
2449                         << candidate.ToString();
2450       return;
2451     }
2452   }
2453   sdp_handler_->RemoveLocalIceCandidates(candidates);
2454   OnIceCandidatesRemoved(candidates);
2455 }
2456 
OnTransportControllerCandidateChanged(const cricket::CandidatePairChangeEvent & event)2457 void PeerConnection::OnTransportControllerCandidateChanged(
2458     const cricket::CandidatePairChangeEvent& event) {
2459   OnSelectedCandidatePairChanged(event);
2460 }
2461 
OnTransportControllerDtlsHandshakeError(rtc::SSLHandshakeError error)2462 void PeerConnection::OnTransportControllerDtlsHandshakeError(
2463     rtc::SSLHandshakeError error) {
2464   RTC_HISTOGRAM_ENUMERATION(
2465       "WebRTC.PeerConnection.DtlsHandshakeError", static_cast<int>(error),
2466       static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
2467 }
2468 
2469 // Returns the media index for a local ice candidate given the content name.
GetLocalCandidateMediaIndex(const std::string & content_name,int * sdp_mline_index)2470 bool PeerConnection::GetLocalCandidateMediaIndex(
2471     const std::string& content_name,
2472     int* sdp_mline_index) {
2473   if (!local_description() || !sdp_mline_index) {
2474     return false;
2475   }
2476 
2477   bool content_found = false;
2478   const ContentInfos& contents = local_description()->description()->contents();
2479   for (size_t index = 0; index < contents.size(); ++index) {
2480     if (contents[index].name == content_name) {
2481       *sdp_mline_index = static_cast<int>(index);
2482       content_found = true;
2483       break;
2484     }
2485   }
2486   return content_found;
2487 }
2488 
GetCallStats()2489 Call::Stats PeerConnection::GetCallStats() {
2490   if (!worker_thread()->IsCurrent()) {
2491     return worker_thread()->BlockingCall([this] { return GetCallStats(); });
2492   }
2493   RTC_DCHECK_RUN_ON(worker_thread());
2494   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
2495   if (call_) {
2496     return call_->GetStats();
2497   } else {
2498     return Call::Stats();
2499   }
2500 }
2501 
SetupDataChannelTransport_n(const std::string & mid)2502 bool PeerConnection::SetupDataChannelTransport_n(const std::string& mid) {
2503   DataChannelTransportInterface* transport =
2504       transport_controller_->GetDataChannelTransport(mid);
2505   if (!transport) {
2506     RTC_LOG(LS_ERROR)
2507         << "Data channel transport is not available for data channels, mid="
2508         << mid;
2509     return false;
2510   }
2511   RTC_LOG(LS_INFO) << "Setting up data channel transport for mid=" << mid;
2512 
2513   data_channel_controller_.set_data_channel_transport(transport);
2514   data_channel_controller_.SetupDataChannelTransport_n();
2515   sctp_mid_n_ = mid;
2516   cricket::DtlsTransportInternal* dtls_transport =
2517       transport_controller_->GetDtlsTransport(mid);
2518   if (dtls_transport) {
2519     signaling_thread()->PostTask(
2520         SafeTask(signaling_thread_safety_.flag(),
2521                  [this, name = dtls_transport->transport_name()] {
2522                    RTC_DCHECK_RUN_ON(signaling_thread());
2523                    sctp_transport_name_s_ = std::move(name);
2524                  }));
2525   }
2526 
2527   // Note: setting the data sink and checking initial state must be done last,
2528   // after setting up the data channel.  Setting the data sink may trigger
2529   // callbacks to PeerConnection which require the transport to be completely
2530   // set up (eg. OnReadyToSend()).
2531   transport->SetDataSink(&data_channel_controller_);
2532   return true;
2533 }
2534 
TeardownDataChannelTransport_n()2535 void PeerConnection::TeardownDataChannelTransport_n() {
2536   if (sctp_mid_n_) {
2537     // `sctp_mid_` may still be active through an SCTP transport.  If not, unset
2538     // it.
2539     RTC_LOG(LS_INFO) << "Tearing down data channel transport for mid="
2540                      << *sctp_mid_n_;
2541     sctp_mid_n_.reset();
2542   }
2543 
2544   data_channel_controller_.TeardownDataChannelTransport_n();
2545 }
2546 
2547 // Returns false if bundle is enabled and rtcp_mux is disabled.
ValidateBundleSettings(const SessionDescription * desc,const std::map<std::string,const cricket::ContentGroup * > & bundle_groups_by_mid)2548 bool PeerConnection::ValidateBundleSettings(
2549     const SessionDescription* desc,
2550     const std::map<std::string, const cricket::ContentGroup*>&
2551         bundle_groups_by_mid) {
2552   if (bundle_groups_by_mid.empty())
2553     return true;
2554 
2555   const cricket::ContentInfos& contents = desc->contents();
2556   for (cricket::ContentInfos::const_iterator citer = contents.begin();
2557        citer != contents.end(); ++citer) {
2558     const cricket::ContentInfo* content = (&*citer);
2559     RTC_DCHECK(content != NULL);
2560     auto it = bundle_groups_by_mid.find(content->name);
2561     if (it != bundle_groups_by_mid.end() && !content->rejected &&
2562         content->type == MediaProtocolType::kRtp) {
2563       if (!HasRtcpMuxEnabled(content))
2564         return false;
2565     }
2566   }
2567   // RTCP-MUX is enabled in all the contents.
2568   return true;
2569 }
2570 
ReportSdpBundleUsage(const SessionDescriptionInterface & remote_description)2571 void PeerConnection::ReportSdpBundleUsage(
2572     const SessionDescriptionInterface& remote_description) {
2573   RTC_DCHECK_RUN_ON(signaling_thread());
2574 
2575   bool using_bundle =
2576       remote_description.description()->HasGroup(cricket::GROUP_TYPE_BUNDLE);
2577   int num_audio_mlines = 0;
2578   int num_video_mlines = 0;
2579   int num_data_mlines = 0;
2580   for (const ContentInfo& content :
2581        remote_description.description()->contents()) {
2582     cricket::MediaType media_type = content.media_description()->type();
2583     if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2584       num_audio_mlines += 1;
2585     } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2586       num_video_mlines += 1;
2587     } else if (media_type == cricket::MEDIA_TYPE_DATA) {
2588       num_data_mlines += 1;
2589     }
2590   }
2591   bool simple = num_audio_mlines <= 1 && num_video_mlines <= 1;
2592   BundleUsage usage = kBundleUsageMax;
2593   if (num_audio_mlines == 0 && num_video_mlines == 0) {
2594     if (num_data_mlines > 0) {
2595       usage = using_bundle ? kBundleUsageBundleDatachannelOnly
2596                            : kBundleUsageNoBundleDatachannelOnly;
2597     } else {
2598       usage = kBundleUsageEmpty;
2599     }
2600   } else if (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
2601     // In plan-b, simple/complex usage will not show up in the number of
2602     // m-lines or BUNDLE.
2603     usage = using_bundle ? kBundleUsageBundlePlanB : kBundleUsageNoBundlePlanB;
2604   } else {
2605     if (simple) {
2606       usage =
2607           using_bundle ? kBundleUsageBundleSimple : kBundleUsageNoBundleSimple;
2608     } else {
2609       usage = using_bundle ? kBundleUsageBundleComplex
2610                            : kBundleUsageNoBundleComplex;
2611     }
2612   }
2613   RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundleUsage", usage,
2614                             kBundleUsageMax);
2615 }
2616 
ReportIceCandidateCollected(const cricket::Candidate & candidate)2617 void PeerConnection::ReportIceCandidateCollected(
2618     const cricket::Candidate& candidate) {
2619   NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
2620   if (candidate.address().IsPrivateIP()) {
2621     NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
2622   }
2623   if (candidate.address().IsUnresolvedIP()) {
2624     NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
2625   }
2626   if (candidate.address().family() == AF_INET6) {
2627     NoteUsageEvent(UsageEvent::IPV6_CANDIDATE_COLLECTED);
2628   }
2629 }
2630 
NoteUsageEvent(UsageEvent event)2631 void PeerConnection::NoteUsageEvent(UsageEvent event) {
2632   RTC_DCHECK_RUN_ON(signaling_thread());
2633   usage_pattern_.NoteUsageEvent(event);
2634 }
2635 
2636 // Asynchronously adds remote candidates on the network thread.
AddRemoteCandidate(const std::string & mid,const cricket::Candidate & candidate)2637 void PeerConnection::AddRemoteCandidate(const std::string& mid,
2638                                         const cricket::Candidate& candidate) {
2639   RTC_DCHECK_RUN_ON(signaling_thread());
2640 
2641   if (candidate.network_type() != rtc::ADAPTER_TYPE_UNKNOWN) {
2642     RTC_DLOG(LS_WARNING) << "Using candidate with adapter type set - this "
2643                             "should only happen in test";
2644   }
2645 
2646   // Clear fields that do not make sense as remote candidates.
2647   cricket::Candidate new_candidate(candidate);
2648   new_candidate.set_network_type(rtc::ADAPTER_TYPE_UNKNOWN);
2649   new_candidate.set_relay_protocol("");
2650   new_candidate.set_underlying_type_for_vpn(rtc::ADAPTER_TYPE_UNKNOWN);
2651 
2652   network_thread()->PostTask(SafeTask(
2653       network_thread_safety_, [this, mid = mid, candidate = new_candidate] {
2654         RTC_DCHECK_RUN_ON(network_thread());
2655         std::vector<cricket::Candidate> candidates = {candidate};
2656         RTCError error =
2657             transport_controller_->AddRemoteCandidates(mid, candidates);
2658         if (error.ok()) {
2659           signaling_thread()->PostTask(SafeTask(
2660               signaling_thread_safety_.flag(),
2661               [this, candidate = std::move(candidate)] {
2662                 ReportRemoteIceCandidateAdded(candidate);
2663                 // Candidates successfully submitted for checking.
2664                 if (ice_connection_state() ==
2665                         PeerConnectionInterface::kIceConnectionNew ||
2666                     ice_connection_state() ==
2667                         PeerConnectionInterface::kIceConnectionDisconnected) {
2668                   // If state is New, then the session has just gotten its first
2669                   // remote ICE candidates, so go to Checking. If state is
2670                   // Disconnected, the session is re-using old candidates or
2671                   // receiving additional ones, so go to Checking. If state is
2672                   // Connected, stay Connected.
2673                   // TODO(bemasc): If state is Connected, and the new candidates
2674                   // are for a newly added transport, then the state actually
2675                   // _should_ move to checking.  Add a way to distinguish that
2676                   // case.
2677                   SetIceConnectionState(
2678                       PeerConnectionInterface::kIceConnectionChecking);
2679                 }
2680                 // TODO(bemasc): If state is Completed, go back to Connected.
2681               }));
2682         } else {
2683           RTC_LOG(LS_WARNING) << error.message();
2684         }
2685       }));
2686 }
2687 
ReportUsagePattern() const2688 void PeerConnection::ReportUsagePattern() const {
2689   usage_pattern_.ReportUsagePattern(observer_);
2690 }
2691 
ReportRemoteIceCandidateAdded(const cricket::Candidate & candidate)2692 void PeerConnection::ReportRemoteIceCandidateAdded(
2693     const cricket::Candidate& candidate) {
2694   RTC_DCHECK_RUN_ON(signaling_thread());
2695 
2696   NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED);
2697 
2698   if (candidate.address().IsPrivateIP()) {
2699     NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED);
2700   }
2701   if (candidate.address().IsUnresolvedIP()) {
2702     NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED);
2703   }
2704   if (candidate.address().family() == AF_INET6) {
2705     NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED);
2706   }
2707 }
2708 
SrtpRequired() const2709 bool PeerConnection::SrtpRequired() const {
2710   RTC_DCHECK_RUN_ON(signaling_thread());
2711   return (dtls_enabled_ ||
2712           sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() ==
2713               cricket::SEC_REQUIRED);
2714 }
2715 
OnTransportControllerGatheringState(cricket::IceGatheringState state)2716 void PeerConnection::OnTransportControllerGatheringState(
2717     cricket::IceGatheringState state) {
2718   RTC_DCHECK(signaling_thread()->IsCurrent());
2719   if (state == cricket::kIceGatheringGathering) {
2720     OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
2721   } else if (state == cricket::kIceGatheringComplete) {
2722     OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
2723   } else if (state == cricket::kIceGatheringNew) {
2724     OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew);
2725   } else {
2726     RTC_LOG(LS_ERROR) << "Unknown state received: " << state;
2727     RTC_DCHECK_NOTREACHED();
2728   }
2729 }
2730 
2731 // Runs on network_thread().
ReportTransportStats()2732 void PeerConnection::ReportTransportStats() {
2733   TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
2734   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
2735   std::map<std::string, std::set<cricket::MediaType>>
2736       media_types_by_transport_name;
2737   if (ConfiguredForMedia()) {
2738     for (const auto& transceiver :
2739          rtp_manager()->transceivers()->UnsafeList()) {
2740       if (transceiver->internal()->channel()) {
2741         std::string transport_name(
2742             transceiver->internal()->channel()->transport_name());
2743         media_types_by_transport_name[transport_name].insert(
2744             transceiver->media_type());
2745       }
2746     }
2747   }
2748 
2749   if (sctp_mid_n_) {
2750     cricket::DtlsTransportInternal* dtls_transport =
2751         transport_controller_->GetDtlsTransport(*sctp_mid_n_);
2752     if (dtls_transport) {
2753       media_types_by_transport_name[dtls_transport->transport_name()].insert(
2754           cricket::MEDIA_TYPE_DATA);
2755     }
2756   }
2757 
2758   for (const auto& entry : media_types_by_transport_name) {
2759     const std::string& transport_name = entry.first;
2760     const std::set<cricket::MediaType> media_types = entry.second;
2761     cricket::TransportStats stats;
2762     if (transport_controller_->GetStats(transport_name, &stats)) {
2763       ReportBestConnectionState(stats);
2764       ReportNegotiatedCiphers(dtls_enabled_, stats, media_types);
2765     }
2766   }
2767 }
2768 
2769 // Walk through the ConnectionInfos to gather best connection usage
2770 // for IPv4 and IPv6.
2771 // static (no member state required)
ReportBestConnectionState(const cricket::TransportStats & stats)2772 void PeerConnection::ReportBestConnectionState(
2773     const cricket::TransportStats& stats) {
2774   for (const cricket::TransportChannelStats& channel_stats :
2775        stats.channel_stats) {
2776     for (const cricket::ConnectionInfo& connection_info :
2777          channel_stats.ice_transport_stats.connection_infos) {
2778       if (!connection_info.best_connection) {
2779         continue;
2780       }
2781 
2782       const cricket::Candidate& local = connection_info.local_candidate;
2783       const cricket::Candidate& remote = connection_info.remote_candidate;
2784 
2785       // Increment the counter for IceCandidatePairType.
2786       if (local.protocol() == cricket::TCP_PROTOCOL_NAME ||
2787           (local.type() == RELAY_PORT_TYPE &&
2788            local.relay_protocol() == cricket::TCP_PROTOCOL_NAME)) {
2789         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_TCP",
2790                                   GetIceCandidatePairCounter(local, remote),
2791                                   kIceCandidatePairMax);
2792       } else if (local.protocol() == cricket::UDP_PROTOCOL_NAME) {
2793         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_UDP",
2794                                   GetIceCandidatePairCounter(local, remote),
2795                                   kIceCandidatePairMax);
2796       } else {
2797         RTC_CHECK_NOTREACHED();
2798       }
2799 
2800       // Increment the counter for IP type.
2801       if (local.address().family() == AF_INET) {
2802         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2803                                   kBestConnections_IPv4,
2804                                   kPeerConnectionAddressFamilyCounter_Max);
2805       } else if (local.address().family() == AF_INET6) {
2806         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2807                                   kBestConnections_IPv6,
2808                                   kPeerConnectionAddressFamilyCounter_Max);
2809       } else {
2810         RTC_CHECK(!local.address().hostname().empty() &&
2811                   local.address().IsUnresolvedIP());
2812       }
2813 
2814       return;
2815     }
2816   }
2817 }
2818 
2819 // static
ReportNegotiatedCiphers(bool dtls_enabled,const cricket::TransportStats & stats,const std::set<cricket::MediaType> & media_types)2820 void PeerConnection::ReportNegotiatedCiphers(
2821     bool dtls_enabled,
2822     const cricket::TransportStats& stats,
2823     const std::set<cricket::MediaType>& media_types) {
2824   if (!dtls_enabled || stats.channel_stats.empty()) {
2825     return;
2826   }
2827 
2828   int srtp_crypto_suite = stats.channel_stats[0].srtp_crypto_suite;
2829   int ssl_cipher_suite = stats.channel_stats[0].ssl_cipher_suite;
2830   if (srtp_crypto_suite == rtc::kSrtpInvalidCryptoSuite &&
2831       ssl_cipher_suite == rtc::kTlsNullWithNullNull) {
2832     return;
2833   }
2834 
2835   if (srtp_crypto_suite != rtc::kSrtpInvalidCryptoSuite) {
2836     for (cricket::MediaType media_type : media_types) {
2837       switch (media_type) {
2838         case cricket::MEDIA_TYPE_AUDIO:
2839           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2840               "WebRTC.PeerConnection.SrtpCryptoSuite.Audio", srtp_crypto_suite,
2841               rtc::kSrtpCryptoSuiteMaxValue);
2842           break;
2843         case cricket::MEDIA_TYPE_VIDEO:
2844           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2845               "WebRTC.PeerConnection.SrtpCryptoSuite.Video", srtp_crypto_suite,
2846               rtc::kSrtpCryptoSuiteMaxValue);
2847           break;
2848         case cricket::MEDIA_TYPE_DATA:
2849           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2850               "WebRTC.PeerConnection.SrtpCryptoSuite.Data", srtp_crypto_suite,
2851               rtc::kSrtpCryptoSuiteMaxValue);
2852           break;
2853         default:
2854           RTC_DCHECK_NOTREACHED();
2855           continue;
2856       }
2857     }
2858   }
2859 
2860   if (ssl_cipher_suite != rtc::kTlsNullWithNullNull) {
2861     for (cricket::MediaType media_type : media_types) {
2862       switch (media_type) {
2863         case cricket::MEDIA_TYPE_AUDIO:
2864           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2865               "WebRTC.PeerConnection.SslCipherSuite.Audio", ssl_cipher_suite,
2866               rtc::kSslCipherSuiteMaxValue);
2867           break;
2868         case cricket::MEDIA_TYPE_VIDEO:
2869           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2870               "WebRTC.PeerConnection.SslCipherSuite.Video", ssl_cipher_suite,
2871               rtc::kSslCipherSuiteMaxValue);
2872           break;
2873         case cricket::MEDIA_TYPE_DATA:
2874           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2875               "WebRTC.PeerConnection.SslCipherSuite.Data", ssl_cipher_suite,
2876               rtc::kSslCipherSuiteMaxValue);
2877           break;
2878         default:
2879           RTC_DCHECK_NOTREACHED();
2880           continue;
2881       }
2882     }
2883   }
2884 }
2885 
OnTransportChanged(const std::string & mid,RtpTransportInternal * rtp_transport,rtc::scoped_refptr<DtlsTransport> dtls_transport,DataChannelTransportInterface * data_channel_transport)2886 bool PeerConnection::OnTransportChanged(
2887     const std::string& mid,
2888     RtpTransportInternal* rtp_transport,
2889     rtc::scoped_refptr<DtlsTransport> dtls_transport,
2890     DataChannelTransportInterface* data_channel_transport) {
2891   RTC_DCHECK_RUN_ON(network_thread());
2892   bool ret = true;
2893   if (ConfiguredForMedia()) {
2894     for (const auto& transceiver :
2895          rtp_manager()->transceivers()->UnsafeList()) {
2896       cricket::ChannelInterface* channel = transceiver->internal()->channel();
2897       if (channel && channel->mid() == mid) {
2898         ret = channel->SetRtpTransport(rtp_transport);
2899       }
2900     }
2901   }
2902 
2903   if (mid == sctp_mid_n_) {
2904     data_channel_controller_.OnTransportChanged(data_channel_transport);
2905     if (dtls_transport) {
2906       signaling_thread()->PostTask(SafeTask(
2907           signaling_thread_safety_.flag(),
2908           [this,
2909            name = std::string(dtls_transport->internal()->transport_name())] {
2910             RTC_DCHECK_RUN_ON(signaling_thread());
2911             sctp_transport_name_s_ = std::move(name);
2912           }));
2913     }
2914   }
2915 
2916   return ret;
2917 }
2918 
Observer() const2919 PeerConnectionObserver* PeerConnection::Observer() const {
2920   RTC_DCHECK_RUN_ON(signaling_thread());
2921   RTC_DCHECK(observer_);
2922   return observer_;
2923 }
2924 
StartSctpTransport(int local_port,int remote_port,int max_message_size)2925 void PeerConnection::StartSctpTransport(int local_port,
2926                                         int remote_port,
2927                                         int max_message_size) {
2928   RTC_DCHECK_RUN_ON(signaling_thread());
2929   if (!sctp_mid_s_)
2930     return;
2931 
2932   network_thread()->PostTask(SafeTask(
2933       network_thread_safety_,
2934       [this, mid = *sctp_mid_s_, local_port, remote_port, max_message_size] {
2935         rtc::scoped_refptr<SctpTransport> sctp_transport =
2936             transport_controller_n()->GetSctpTransport(mid);
2937         if (sctp_transport)
2938           sctp_transport->Start(local_port, remote_port, max_message_size);
2939       }));
2940 }
2941 
GetCryptoOptions()2942 CryptoOptions PeerConnection::GetCryptoOptions() {
2943   RTC_DCHECK_RUN_ON(signaling_thread());
2944   // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions
2945   // after it has been removed.
2946   return configuration_.crypto_options.has_value()
2947              ? *configuration_.crypto_options
2948              : options_.crypto_options;
2949 }
2950 
ClearStatsCache()2951 void PeerConnection::ClearStatsCache() {
2952   RTC_DCHECK_RUN_ON(signaling_thread());
2953   if (legacy_stats_) {
2954     legacy_stats_->InvalidateCache();
2955   }
2956   if (stats_collector_) {
2957     stats_collector_->ClearCachedStatsReport();
2958   }
2959 }
2960 
ShouldFireNegotiationNeededEvent(uint32_t event_id)2961 bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
2962   RTC_DCHECK_RUN_ON(signaling_thread());
2963   return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
2964 }
2965 
RequestUsagePatternReportForTesting()2966 void PeerConnection::RequestUsagePatternReportForTesting() {
2967   RTC_DCHECK_RUN_ON(signaling_thread());
2968   message_handler_.RequestUsagePatternReport(
2969       [this]() {
2970         RTC_DCHECK_RUN_ON(signaling_thread());
2971         ReportUsagePattern();
2972       },
2973       /* delay_ms= */ 0);
2974 }
2975 
2976 std::function<void(const rtc::CopyOnWriteBuffer& packet,
2977                    int64_t packet_time_us)>
InitializeRtcpCallback()2978 PeerConnection::InitializeRtcpCallback() {
2979   RTC_DCHECK_RUN_ON(network_thread());
2980   return [this](const rtc::CopyOnWriteBuffer& packet, int64_t packet_time_us) {
2981     RTC_DCHECK_RUN_ON(network_thread());
2982     call_ptr_->Receiver()->DeliverPacket(MediaType::ANY, packet,
2983                                          packet_time_us);
2984   };
2985 }
2986 
2987 }  // namespace webrtc
2988