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