tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PeerConnectionImpl.h (34062B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef _PEER_CONNECTION_IMPL_H_
      6 #define _PEER_CONNECTION_IMPL_H_
      7 
      8 #include <cmath>
      9 #include <map>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "mozilla/Attributes.h"
     14 #include "mozilla/Mutex.h"
     15 #include "mozilla/RefPtr.h"
     16 #include "nsComponentManagerUtils.h"
     17 #include "nsIThread.h"
     18 #include "nsIUUIDGenerator.h"
     19 #include "nsPIDOMWindow.h"
     20 #include "nsTHashSet.h"
     21 #include "prlock.h"
     22 
     23 // Work around nasty macro in webrtc/voice_engine/voice_engine_defines.h
     24 #ifdef GetLastError
     25 #  undef GetLastError
     26 #endif
     27 
     28 #include "DefaultCodecPreferences.h"
     29 #include "MediaEventSource.h"
     30 #include "MediaTransportHandler.h"
     31 #include "PrincipalChangeObserver.h"
     32 #include "RTCDtlsTransport.h"
     33 #include "RTCRtpTransceiver.h"
     34 #include "RTCStatsIdGenerator.h"
     35 #include "RTCStatsReport.h"
     36 #include "VideoSegment.h"
     37 #include "VideoUtils.h"
     38 #include "jsapi/PacketDumper.h"
     39 #include "jsep/JsepSession.h"
     40 #include "jsep/JsepSessionImpl.h"
     41 #include "mozilla/ErrorResult.h"
     42 #include "mozilla/PeerIdentity.h"
     43 #include "mozilla/TimeStamp.h"
     44 #include "mozilla/dom/PeerConnectionImplBinding.h"  // ChainedOperation
     45 #include "mozilla/dom/PromiseNativeHandler.h"
     46 #include "mozilla/dom/RTCConfigurationBinding.h"
     47 #include "mozilla/dom/RTCPeerConnectionBinding.h"  // mozPacketDumpType, maybe move?
     48 #include "mozilla/dom/RTCRtpCapabilitiesBinding.h"
     49 #include "mozilla/dom/RTCRtpTransceiverBinding.h"
     50 #include "mozilla/dom/RTCStatsReportBinding.h"
     51 #include "mozilla/net/DataChannel.h"
     52 #include "mozilla/net/StunAddrsRequestChild.h"
     53 #include "nsIHttpChannelInternal.h"
     54 #include "sdp/SdpMediaSection.h"
     55 
     56 namespace test {
     57 #ifdef USE_FAKE_PCOBSERVER
     58 class AFakePCObserver;
     59 #endif
     60 }  // namespace test
     61 
     62 class nsIPrincipal;
     63 
     64 namespace mozilla {
     65 struct CandidateInfo;
     66 class DataChannel;
     67 class DtlsIdentity;
     68 class MediaPipeline;
     69 class MediaPipelineReceive;
     70 class MediaPipelineTransmit;
     71 enum class PrincipalPrivacy : uint8_t;
     72 class SharedWebrtcState;
     73 
     74 namespace dom {
     75 class RTCCertificate;
     76 struct RTCConfiguration;
     77 class RTCDataChannel;
     78 struct RTCRtpSourceEntry;
     79 struct RTCIceServer;
     80 struct RTCOfferOptions;
     81 struct RTCRtpParameters;
     82 class RTCRtpSender;
     83 class MediaStreamTrack;
     84 
     85 #ifdef USE_FAKE_PCOBSERVER
     86 typedef test::AFakePCObserver PeerConnectionObserver;
     87 typedef const char* PCObserverString;
     88 #else
     89 class PeerConnectionObserver;
     90 typedef NS_ConvertUTF8toUTF16 PCObserverString;
     91 #endif
     92 }  // namespace dom
     93 }  // namespace mozilla
     94 
     95 #if defined(__cplusplus) && __cplusplus >= 201103L
     96 typedef struct Timecard Timecard;
     97 #else
     98 #  include "common/time_profiling/timecard.h"
     99 #endif
    100 
    101 // To preserve blame, convert nsresult to ErrorResult with wrappers. These
    102 // macros help declare wrappers w/function being wrapped when there are no
    103 // differences.
    104 
    105 #define NS_IMETHODIMP_TO_ERRORRESULT(func, rv, ...) \
    106  NS_IMETHODIMP func(__VA_ARGS__);                  \
    107  void func(__VA_ARGS__, rv)
    108 
    109 #define NS_IMETHODIMP_TO_ERRORRESULT_RETREF(resulttype, func, rv, ...) \
    110  NS_IMETHODIMP func(__VA_ARGS__, resulttype** result);                \
    111  already_AddRefed<resulttype> func(__VA_ARGS__, rv)
    112 
    113 namespace mozilla {
    114 
    115 using dom::PeerConnectionObserver;
    116 using dom::RTCConfiguration;
    117 using dom::RTCDataChannel;
    118 using dom::RTCIceServer;
    119 using dom::RTCOfferOptions;
    120 
    121 class PeerConnectionWrapper;
    122 class RemoteSourceStreamInfo;
    123 
    124 // Uuid Generator
    125 class PCUuidGenerator : public JsepUuidGenerator {
    126 public:
    127  virtual bool Generate(std::string* idp) override;
    128  virtual JsepUuidGenerator* Clone() const override {
    129    return new PCUuidGenerator(*this);
    130  }
    131 
    132 private:
    133  nsCOMPtr<nsIUUIDGenerator> mGenerator;
    134 };
    135 
    136 // This is a variation of Telemetry::AutoTimer that keeps a reference
    137 // count and records the elapsed time when the count falls to zero. The
    138 // elapsed time is recorded in seconds.
    139 struct PeerConnectionAutoTimer {
    140  PeerConnectionAutoTimer()
    141      : mRefCnt(0), mStart(TimeStamp::Now()), mUsedAV(false) {};
    142  void RegisterConnection();
    143  void UnregisterConnection(bool aContainedAV);
    144  bool IsStopped();
    145 
    146 private:
    147  int64_t mRefCnt;
    148  TimeStamp mStart;
    149  bool mUsedAV;
    150 };
    151 
    152 // Enter an API call and check that the state is OK,
    153 // the PC isn't closed, etc.
    154 #define PC_AUTO_ENTER_API_CALL(assert_ice_ready)             \
    155  do {                                                       \
    156    /* do/while prevents res from conflicting with locals */ \
    157    nsresult res = CheckApiState(assert_ice_ready);          \
    158    if (NS_FAILED(res)) return res;                          \
    159  } while (0)
    160 #define PC_AUTO_ENTER_API_CALL_VOID_RETURN(assert_ice_ready) \
    161  do {                                                       \
    162    /* do/while prevents res from conflicting with locals */ \
    163    nsresult res = CheckApiState(assert_ice_ready);          \
    164    if (NS_FAILED(res)) return;                              \
    165  } while (0)
    166 #define PC_AUTO_ENTER_API_CALL_NO_CHECK() CheckThread()
    167 
    168 class PeerConnectionImpl final
    169    : public nsISupports,
    170      public nsWrapperCache,
    171      public DataChannelConnection::DataConnectionListener {
    172  struct Internal;  // Avoid exposing c includes to bindings
    173 
    174 public:
    175  explicit PeerConnectionImpl(const dom::GlobalObject* aGlobal = nullptr);
    176 
    177  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    178  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(PeerConnectionImpl)
    179 
    180  struct RtpExtensionHeader {
    181    JsepMediaType mMediaType;
    182    SdpDirectionAttribute::Direction direction;
    183    std::string extensionname;
    184  };
    185 
    186  JSObject* WrapObject(JSContext* aCx,
    187                       JS::Handle<JSObject*> aGivenProto) override;
    188  nsPIDOMWindowInner* GetParentObject() const;
    189 
    190  static already_AddRefed<PeerConnectionImpl> Constructor(
    191      const dom::GlobalObject& aGlobal);
    192 
    193  static DefaultCodecPreferences GetDefaultCodecPreferences(
    194      const OverrideRtxPreference aOverrideRtxPreference =
    195          OverrideRtxPreference::NoOverride) {
    196    return DefaultCodecPreferences(aOverrideRtxPreference);
    197  }
    198  // DataConnection observers
    199  void NotifyDataChannel(already_AddRefed<DataChannel> aChannel,
    200                         const nsACString& aLabel, bool aOrdered,
    201                         dom::Nullable<uint16_t> aMaxLifeTime,
    202                         dom::Nullable<uint16_t> aMaxRetransmits,
    203                         const nsACString& aProtocol, bool aNegotiated)
    204      // PeerConnectionImpl only inherits from DataChannelConnection
    205      // inside libxul.
    206      override;
    207 
    208  void NotifyDataChannelOpen(DataChannel*) override;
    209 
    210  void NotifyDataChannelClosed(DataChannel*) override;
    211 
    212  void NotifySctpConnected() override;
    213 
    214  void NotifySctpClosed() override;
    215 
    216  const RefPtr<MediaTransportHandler> GetTransportHandler() const;
    217 
    218  // Handle system to allow weak references to be passed through C code
    219  virtual const std::string& GetHandle();
    220 
    221  // Name suitable for exposing to content
    222  virtual const std::string& GetName();
    223 
    224  // ICE events
    225  void IceConnectionStateChange(const std::string& aTransportId,
    226                                dom::RTCIceTransportState state);
    227  void IceGatheringStateChange(const std::string& aTransportId,
    228                               dom::RTCIceGathererState state);
    229  void OnCandidateFound(const std::string& aTransportId,
    230                        const CandidateInfo& aCandidateInfo);
    231  void UpdateDefaultCandidate(const std::string& defaultAddr,
    232                              uint16_t defaultPort,
    233                              const std::string& defaultRtcpAddr,
    234                              uint16_t defaultRtcpPort,
    235                              const std::string& transportId);
    236 
    237  static void ListenThread(void* aData);
    238  static void ConnectThread(void* aData);
    239 
    240  // Get the STS thread
    241  nsISerialEventTarget* GetSTSThread() {
    242    PC_AUTO_ENTER_API_CALL_NO_CHECK();
    243    return mSTSThread;
    244  }
    245 
    246  nsresult Initialize(PeerConnectionObserver& aObserver,
    247                      nsGlobalWindowInner* aWindow);
    248 
    249  // Initialize PeerConnection from an RTCConfiguration object (JS entrypoint)
    250  void Initialize(PeerConnectionObserver& aObserver,
    251                  nsGlobalWindowInner& aWindow, ErrorResult& rv);
    252 
    253  void SetCertificate(dom::RTCCertificate& aCertificate);
    254  const RefPtr<dom::RTCCertificate>& Certificate() const;
    255  // This is a hack to support external linkage.
    256  RefPtr<DtlsIdentity> Identity() const;
    257 
    258  NS_IMETHODIMP_TO_ERRORRESULT(CreateOffer, ErrorResult& rv,
    259                               const RTCOfferOptions& aOptions) {
    260    rv = CreateOffer(aOptions);
    261  }
    262 
    263  NS_IMETHODIMP CreateAnswer();
    264  void CreateAnswer(ErrorResult& rv) { rv = CreateAnswer(); }
    265 
    266  NS_IMETHODIMP CreateOffer(const JsepOfferOptions& aConstraints);
    267 
    268  NS_IMETHODIMP SetLocalDescription(int32_t aAction, const char* aSDP);
    269 
    270  void SetLocalDescription(int32_t aAction, const nsAString& aSDP,
    271                           ErrorResult& rv) {
    272    rv = SetLocalDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get());
    273  }
    274 
    275  NS_IMETHODIMP SetRemoteDescription(int32_t aAction, const char* aSDP);
    276 
    277  void SetRemoteDescription(int32_t aAction, const nsAString& aSDP,
    278                            ErrorResult& rv) {
    279    rv = SetRemoteDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get());
    280  }
    281 
    282  already_AddRefed<dom::Promise> GetStats(dom::MediaStreamTrack* aSelector);
    283 
    284  void GetRemoteStreams(nsTArray<RefPtr<DOMMediaStream>>& aStreamsOut) const;
    285 
    286  NS_IMETHODIMP AddIceCandidate(const char* aCandidate, const char* aMid,
    287                                const char* aUfrag,
    288                                const dom::Nullable<unsigned short>& aLevel);
    289 
    290  void AddIceCandidate(const nsAString& aCandidate, const nsAString& aMid,
    291                       const nsAString& aUfrag,
    292                       const dom::Nullable<unsigned short>& aLevel,
    293                       ErrorResult& rv) {
    294    rv = AddIceCandidate(NS_ConvertUTF16toUTF8(aCandidate).get(),
    295                         NS_ConvertUTF16toUTF8(aMid).get(),
    296                         NS_ConvertUTF16toUTF8(aUfrag).get(), aLevel);
    297  }
    298 
    299  void UpdateNetworkState(bool online);
    300 
    301  NS_IMETHODIMP CloseStreams();
    302 
    303  void CloseStreams(ErrorResult& rv) { rv = CloseStreams(); }
    304 
    305  already_AddRefed<dom::RTCRtpTransceiver> AddTransceiver(
    306      const dom::RTCRtpTransceiverInit& aInit, const nsAString& aKind,
    307      dom::MediaStreamTrack* aSendTrack, bool aAddTrackMagic, ErrorResult& aRv);
    308 
    309  bool CheckNegotiationNeeded();
    310  bool CreatedSender(const dom::RTCRtpSender& aSender) const;
    311 
    312  // test-only
    313  NS_IMETHODIMP_TO_ERRORRESULT(EnablePacketDump, ErrorResult& rv,
    314                               unsigned long level, dom::mozPacketDumpType type,
    315                               bool sending) {
    316    rv = EnablePacketDump(level, type, sending);
    317  }
    318 
    319  // test-only
    320  NS_IMETHODIMP_TO_ERRORRESULT(DisablePacketDump, ErrorResult& rv,
    321                               unsigned long level, dom::mozPacketDumpType type,
    322                               bool sending) {
    323    rv = DisablePacketDump(level, type, sending);
    324  }
    325 
    326  void GetPeerIdentity(nsAString& peerIdentity) {
    327    if (mPeerIdentity) {
    328      peerIdentity = mPeerIdentity->ToString();
    329      return;
    330    }
    331 
    332    peerIdentity.SetIsVoid(true);
    333  }
    334 
    335  const PeerIdentity* GetPeerIdentity() const { return mPeerIdentity; }
    336  NS_IMETHODIMP_TO_ERRORRESULT(SetPeerIdentity, ErrorResult& rv,
    337                               const nsAString& peerIdentity) {
    338    rv = SetPeerIdentity(peerIdentity);
    339  }
    340 
    341  const std::string& GetIdAsAscii() const { return mName; }
    342 
    343  void GetId(nsAString& id) { id = NS_ConvertASCIItoUTF16(mName.c_str()); }
    344 
    345  void SetId(const nsAString& id) { mName = NS_ConvertUTF16toUTF8(id).get(); }
    346 
    347  // this method checks to see if we've made a promise to protect media.
    348  bool PrivacyRequested() const {
    349    return mRequestedPrivacy.valueOr(PrincipalPrivacy::NonPrivate) ==
    350           PrincipalPrivacy::Private;
    351  }
    352 
    353  bool DuplicateFingerprintQuirk() { return mDuplicateFingerprintQuirk; }
    354 
    355  NS_IMETHODIMP GetFingerprint(char** fingerprint);
    356  void GetFingerprint(nsAString& fingerprint) {
    357    char* tmp;
    358    nsresult rv = GetFingerprint(&tmp);
    359    NS_ENSURE_SUCCESS_VOID(rv);
    360    fingerprint.AssignASCII(tmp);
    361    delete[] tmp;
    362  }
    363 
    364  void GetCurrentLocalDescription(nsAString& aSDP) const;
    365  void GetPendingLocalDescription(nsAString& aSDP) const;
    366 
    367  void GetCurrentRemoteDescription(nsAString& aSDP) const;
    368  void GetPendingRemoteDescription(nsAString& aSDP) const;
    369 
    370  dom::Nullable<bool> GetCurrentOfferer() const;
    371  dom::Nullable<bool> GetPendingOfferer() const;
    372 
    373  NS_IMETHODIMP SignalingState(dom::RTCSignalingState* aState);
    374 
    375  dom::RTCSignalingState SignalingState() {
    376    dom::RTCSignalingState state;
    377    SignalingState(&state);
    378    return state;
    379  }
    380 
    381  NS_IMETHODIMP IceConnectionState(dom::RTCIceConnectionState* aState);
    382 
    383  dom::RTCIceConnectionState IceConnectionState() {
    384    dom::RTCIceConnectionState state;
    385    IceConnectionState(&state);
    386    return state;
    387  }
    388 
    389  NS_IMETHODIMP IceGatheringState(dom::RTCIceGatheringState* aState);
    390 
    391  dom::RTCIceGatheringState IceGatheringState() { return mIceGatheringState; }
    392 
    393  NS_IMETHODIMP ConnectionState(dom::RTCPeerConnectionState* aState);
    394 
    395  dom::RTCPeerConnectionState ConnectionState() {
    396    dom::RTCPeerConnectionState state;
    397    ConnectionState(&state);
    398    return state;
    399  }
    400 
    401  NS_IMETHODIMP Close();
    402 
    403  void Close(ErrorResult& rv) { rv = Close(); }
    404 
    405  // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
    406  MOZ_CAN_RUN_SCRIPT_BOUNDARY bool PluginCrash(uint32_t aPluginID,
    407                                               const nsAString& aPluginName);
    408 
    409  NS_IMETHODIMP_TO_ERRORRESULT(SetConfiguration, ErrorResult& rv,
    410                               const RTCConfiguration& aConfiguration) {
    411    rv = SetConfiguration(aConfiguration);
    412  }
    413 
    414  dom::RTCSctpTransport* GetSctp() const;
    415 
    416  void RestartIce();
    417  void RestartIceNoRenegotiationNeeded();
    418 
    419  void RecordEndOfCallTelemetry();
    420 
    421  void RecordSignalingTelemetry() const;
    422 
    423  nsresult MaybeInitializeDataChannel();
    424 
    425  NS_IMETHODIMP_TO_ERRORRESULT_RETREF(RTCDataChannel, CreateDataChannel,
    426                                      ErrorResult& rv, const nsACString& aLabel,
    427                                      const nsACString& aProtocol,
    428                                      uint16_t aType, bool outOfOrderAllowed,
    429                                      uint16_t aMaxTime, uint16_t aMaxNum,
    430                                      bool aExternalNegotiated,
    431                                      uint16_t aStream);
    432 
    433  // Base class for chained operations. Necessary right now because some
    434  // operations come from JS (in the form of dom::ChainedOperation), and others
    435  // come from c++ (dom::ChainedOperation is very unwieldy and arcane to build
    436  // in c++). Once we stop using JSImpl, we should be able to simplify this.
    437  class Operation : public dom::PromiseNativeHandler {
    438   public:
    439    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    440    NS_DECL_CYCLE_COLLECTION_CLASS(Operation)
    441    Operation(PeerConnectionImpl* aPc, ErrorResult& aError);
    442    MOZ_CAN_RUN_SCRIPT
    443    void Call(ErrorResult& aError);
    444    dom::Promise* GetPromise() { return mPromise; }
    445    MOZ_CAN_RUN_SCRIPT
    446    void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
    447                          ErrorResult& aRv) override;
    448 
    449    MOZ_CAN_RUN_SCRIPT
    450    void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
    451                          ErrorResult& aRv) override;
    452 
    453   protected:
    454    MOZ_CAN_RUN_SCRIPT
    455    virtual RefPtr<dom::Promise> CallImpl(ErrorResult& aError) = 0;
    456    virtual ~Operation();
    457    // This is the promise p from https://w3c.github.io/webrtc-pc/#dfn-chain
    458    // This will be a content promise, since we return this to the caller of
    459    // Chain.
    460    RefPtr<dom::Promise> mPromise;
    461    RefPtr<PeerConnectionImpl> mPc;
    462  };
    463 
    464  class JSOperation final : public Operation {
    465   public:
    466    JSOperation(PeerConnectionImpl* aPc, dom::ChainedOperation& aOp,
    467                ErrorResult& aError);
    468    NS_DECL_ISUPPORTS_INHERITED
    469    NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(JSOperation, Operation)
    470 
    471   private:
    472    MOZ_CAN_RUN_SCRIPT
    473    RefPtr<dom::Promise> CallImpl(ErrorResult& aError) override;
    474    ~JSOperation() = default;
    475    RefPtr<dom::ChainedOperation> mOperation;
    476  };
    477 
    478  MOZ_CAN_RUN_SCRIPT
    479  already_AddRefed<dom::Promise> Chain(dom::ChainedOperation& aOperation,
    480                                       ErrorResult& aError);
    481  MOZ_CAN_RUN_SCRIPT
    482  already_AddRefed<dom::Promise> Chain(const RefPtr<Operation>& aOperation,
    483                                       ErrorResult& aError);
    484  already_AddRefed<dom::Promise> MakePromise(ErrorResult& aError) const;
    485 
    486  void UpdateNegotiationNeeded();
    487 
    488  void GetTransceivers(
    489      nsTArray<RefPtr<dom::RTCRtpTransceiver>>& aTransceiversOut) {
    490    aTransceiversOut = mTransceivers.Clone();
    491  }
    492 
    493  RefPtr<dom::RTCRtpTransceiver> GetTransceiver(
    494      const std::string& aTransceiverId);
    495 
    496  // Gets the RTC Signaling State of the JSEP session
    497  dom::RTCSignalingState GetSignalingState() const;
    498 
    499  already_AddRefed<dom::Promise> OnSetDescriptionSuccess(
    500      dom::RTCSdpType aSdpType, bool aRemote, ErrorResult& aError);
    501 
    502  void OnSetDescriptionError();
    503 
    504  bool IsClosed() const;
    505 
    506  // called when DTLS connects; we only need this once
    507  nsresult OnAlpnNegotiated(const std::string& aAlpn, bool aPrivacyRequested);
    508 
    509  void OnDtlsStateChange(const std::string& aTransportId,
    510                         TransportLayer::State aState);
    511  dom::RTCPeerConnectionState GetNewConnectionState() const;
    512  // Returns whether we need to fire a state change event
    513  bool UpdateConnectionState();
    514  dom::RTCIceConnectionState GetNewIceConnectionState() const;
    515  // Returns whether we need to fire a state change event
    516  bool UpdateIceConnectionState();
    517  dom::RTCIceGatheringState GetNewIceGatheringState() const;
    518  // Returns whether we need to fire a state change event
    519  bool UpdateIceGatheringState();
    520 
    521  // initialize telemetry for when calls start
    522  void StartCallTelem();
    523 
    524  // Gets all codec stats for all transports, coalesced to transport level.
    525  nsTArray<dom::RTCCodecStats> GetCodecStats(DOMHighResTimeStamp aNow);
    526 
    527  RefPtr<dom::RTCStatsReportPromise> GetStats(dom::MediaStreamTrack* aSelector,
    528                                              bool aInternalStats);
    529 
    530  void CollectConduitTelemetryData();
    531 
    532  void OnMediaError(const std::string& aError);
    533 
    534  void DumpPacket_m(size_t level, dom::mozPacketDumpType type, bool sending,
    535                    UniquePtr<uint8_t[]>& packet, size_t size);
    536 
    537  const dom::RTCStatsTimestampMaker& GetTimestampMaker() const {
    538    return mTimestampMaker;
    539  }
    540 
    541  void StampTimecard(const char* aEvent);
    542 
    543  bool RelayOnly() const {
    544    return mJsConfiguration.mIceTransportPolicy.WasPassed() &&
    545           mJsConfiguration.mIceTransportPolicy.Value() ==
    546               dom::RTCIceTransportPolicy::Relay;
    547  }
    548 
    549  RefPtr<PacketDumper> GetPacketDumper() {
    550    if (!mPacketDumper) {
    551      mPacketDumper = new PacketDumper(mHandle);
    552    }
    553 
    554    return mPacketDumper;
    555  }
    556 
    557  nsString GenerateUUID() const {
    558    std::string result;
    559    if (!mUuidGen->Generate(&result)) {
    560      MOZ_CRASH();
    561    }
    562    return NS_ConvertUTF8toUTF16(result.c_str());
    563  }
    564 
    565  bool ShouldAllowOldSetParameters() const { return mAllowOldSetParameters; }
    566 
    567  nsCString GetHostname() const { return mHostname; }
    568  nsCString GetEffectiveTLDPlus1() const { return mEffectiveTLDPlus1; }
    569 
    570  void SendWarningToConsole(const nsCString& aWarning);
    571 
    572  const UniquePtr<dom::RTCStatsReportInternal>& GetFinalStats() const {
    573    return mFinalStats;
    574  }
    575 
    576  void DisableLongTermStats() { mDisableLongTermStats = true; }
    577 
    578  bool LongTermStatsIsDisabled() const { return mDisableLongTermStats; }
    579 
    580  static void GetDefaultVideoCodecs(
    581      std::vector<UniquePtr<JsepCodecDescription>>& aSupportedCodecs,
    582      const OverrideRtxPreference aOverrideRtxPreference);
    583 
    584  static void GetDefaultAudioCodecs(
    585      std::vector<UniquePtr<JsepCodecDescription>>& aSupportedCodecs);
    586 
    587  static void GetDefaultRtpExtensions(
    588      std::vector<RtpExtensionHeader>& aRtpExtensions);
    589 
    590  static void GetCapabilities(const nsAString& aKind,
    591                              dom::Nullable<dom::RTCRtpCapabilities>& aResult,
    592                              sdp::Direction aDirection);
    593  static void SetupPreferredCodecs(
    594      std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs);
    595 
    596  static void SetupPreferredRtpExtensions(
    597      std::vector<RtpExtensionHeader>& aPreferredheaders);
    598 
    599  void BreakCycles();
    600 
    601  using RTCDtlsTransportMap =
    602      nsTHashMap<nsCStringHashKey, RefPtr<dom::RTCDtlsTransport>>;
    603 
    604 private:
    605  virtual ~PeerConnectionImpl();
    606  PeerConnectionImpl(const PeerConnectionImpl& rhs);
    607  PeerConnectionImpl& operator=(PeerConnectionImpl);
    608 
    609  RefPtr<dom::RTCStatsPromise> GetDataChannelStats(
    610      const DOMHighResTimeStamp aTimestamp);
    611  nsresult CalculateFingerprint(const nsACString& algorithm,
    612                                std::vector<uint8_t>* fingerprint) const;
    613 
    614  NS_IMETHODIMP EnsureDataConnection(uint16_t aLocalPort, uint16_t aNumstreams);
    615 
    616  nsresult CheckApiState(bool assert_ice_ready) const;
    617  void StoreFinalStats(UniquePtr<dom::RTCStatsReportInternal>&& report);
    618  void CheckThread() const { MOZ_ASSERT(NS_IsMainThread(), "Wrong thread"); }
    619 
    620  // test-only: called from AddRIDExtension and AddRIDFilter
    621  // for simulcast mochitests.
    622  RefPtr<MediaPipeline> GetMediaPipelineForTrack(
    623      dom::MediaStreamTrack& aRecvTrack);
    624 
    625  void CandidateReady(const std::string& candidate,
    626                      const std::string& transportId, const std::string& ufrag);
    627  void SendLocalIceCandidateToContent(uint16_t level, const std::string& mid,
    628                                      const std::string& candidate,
    629                                      const std::string& ufrag);
    630 
    631  nsresult GetDatachannelParameters(uint32_t* channels, uint16_t* localport,
    632                                    uint16_t* remoteport,
    633                                    uint32_t* maxmessagesize,
    634                                    std::string* transportId,
    635                                    bool* client) const;
    636 
    637  nsresult AddRtpTransceiverToJsepSession(JsepTransceiver& transceiver);
    638 
    639  void RecordIceRestartStatistics(JsepSdpType type);
    640 
    641  void StoreConfigurationForAboutWebrtc(const RTCConfiguration& aConfig);
    642 
    643  dom::Sequence<dom::RTCSdpParsingErrorInternal> GetLastSdpParsingErrors()
    644      const;
    645 
    646  MOZ_CAN_RUN_SCRIPT
    647  void RunNextOperation(ErrorResult& aError);
    648 
    649  void SyncToJsep();
    650  void SyncFromJsep();
    651 
    652  void DoSetDescriptionSuccessPostProcessing(dom::RTCSdpType aSdpType,
    653                                             bool aRemote,
    654                                             const RefPtr<dom::Promise>& aP);
    655 
    656  // Timecard used to measure processing time. This should be the first class
    657  // attribute so that we accurately measure the time required to instantiate
    658  // any other attributes of this class.
    659  Timecard* mTimeCard;
    660 
    661  // Configuration used to initialize the PeerConnection
    662  dom::RTCConfigurationInternal mJsConfiguration;
    663 
    664  dom::RTCSignalingState mSignalingState;
    665 
    666  // ICE State
    667  dom::RTCIceConnectionState mIceConnectionState;
    668  dom::RTCIceGatheringState mIceGatheringState;
    669 
    670  dom::RTCPeerConnectionState mConnectionState;
    671 
    672  RefPtr<PeerConnectionObserver> mPCObserver;
    673 
    674  nsCOMPtr<nsPIDOMWindowInner> mWindow;
    675  nsString mOrigin;
    676 
    677  // The SDP sent in from JS
    678  std::string mLocalRequestedSDP;
    679  std::string mRemoteRequestedSDP;
    680  // Only accessed from main
    681  dom::Sequence<dom::RTCSdpHistoryEntryInternal> mSdpHistory;
    682  std::string mPendingLocalDescription;
    683  std::string mPendingRemoteDescription;
    684  std::string mCurrentLocalDescription;
    685  std::string mCurrentRemoteDescription;
    686  Maybe<bool> mPendingOfferer;
    687  Maybe<bool> mCurrentOfferer;
    688 
    689  // DTLS fingerprint
    690  std::string mFingerprint;
    691  std::string mRemoteFingerprint;
    692 
    693  // identity-related fields
    694  // The entity on the other end of the peer-to-peer connection;
    695  // void if they are not yet identified, and no identity setting has been set
    696  RefPtr<PeerIdentity> mPeerIdentity;
    697  // The certificate we are using.
    698  RefPtr<dom::RTCCertificate> mCertificate;
    699  // Whether an app should be prevented from accessing media produced by the PC
    700  // If this is true, then media will not be sent until mPeerIdentity matches
    701  // local streams PeerIdentity; and remote streams are protected from content
    702  //
    703  // This can be false if mPeerIdentity is set, in the case where identity is
    704  // provided, but the media is not protected from the app on either side
    705  Maybe<PrincipalPrivacy> mRequestedPrivacy;
    706 
    707  // A handle to refer to this PC with
    708  std::string mHandle;
    709 
    710  // A name for this PC that we are willing to expose to content.
    711  std::string mName;
    712  nsCString mHostname;
    713  nsCString mEffectiveTLDPlus1;
    714 
    715  // The target to run stuff on
    716  nsCOMPtr<nsISerialEventTarget> mSTSThread;
    717 
    718  // DataConnection that's used to get all the DataChannels
    719  RefPtr<DataChannelConnection> mDataConnection;
    720  unsigned int mDataChannelsOpened = 0;
    721  unsigned int mDataChannelsClosed = 0;
    722 
    723  bool mForceIceTcp;
    724  RefPtr<MediaTransportHandler> mTransportHandler;
    725 
    726  // The JSEP negotiation session.
    727  UniquePtr<PCUuidGenerator> mUuidGen;
    728  UniquePtr<JsepSession> mJsepSession;
    729  // There are lots of error cases where we want to abandon an sRD/sLD _after_
    730  // it has already been applied to the JSEP engine, and revert back to the
    731  // previous state. We also want to ensure that the various modifications
    732  // to the JSEP engine are not exposed to JS until the sRD/sLD completes,
    733  // which is why we have a new "uncommitted" JSEP engine.
    734  UniquePtr<JsepSession> mUncommittedJsepSession;
    735  unsigned long mIceRestartCount;
    736  unsigned long mIceRollbackCount;
    737 
    738  // The following are used for Telemetry:
    739  bool mCallTelemStarted = false;
    740  bool mCallTelemEnded = false;
    741 
    742  // We _could_ make mFinalStatsQuery be an RTCStatsReportPromise, but that
    743  // would require RTCStatsReportPromise to no longer be exclusive, which is
    744  // a bit of a hassle, and not very performant.
    745  RefPtr<GenericNonExclusivePromise> mFinalStatsQuery;
    746  UniquePtr<dom::RTCStatsReportInternal> mFinalStats;
    747  bool mDisableLongTermStats = false;
    748 
    749  // Start time of ICE.
    750  TimeStamp mIceStartTime;
    751  // Hold PeerConnectionAutoTimer instances for each window.
    752  static std::map<uint64_t, PeerConnectionAutoTimer> sCallDurationTimers;
    753 
    754  bool mTrickle;
    755 
    756  bool mPrivateWindow;
    757 
    758  // Whether this PeerConnection is being counted as active by mWindow
    759  bool mActiveOnWindow;
    760 
    761  // storage for Telemetry data
    762  uint16_t mMaxReceiving[SdpMediaSection::kMediaTypes];
    763  uint16_t mMaxSending[SdpMediaSection::kMediaTypes];
    764 
    765  // used to store the raw trickle candidate string for display
    766  // on the about:webrtc raw candidates table.
    767  std::vector<std::string> mRawTrickledCandidates;
    768 
    769  dom::RTCStatsTimestampMaker mTimestampMaker;
    770 
    771  RefPtr<RTCStatsIdGenerator> mIdGenerator;
    772  // Ordinarily, I would use a std::map here, but this used to be a JS Map
    773  // which iterates in insertion order, and I want to avoid changing this.
    774  nsTArray<RefPtr<DOMMediaStream>> mReceiveStreams;
    775 
    776  DOMMediaStream* GetReceiveStream(const std::string& aId) const;
    777  DOMMediaStream* CreateReceiveStream(const std::string& aId);
    778 
    779  void InitLocalAddrs();  // for stun local address IPC request
    780  bool ShouldForceProxy() const;
    781  std::unique_ptr<NrSocketProxyConfig> GetProxyConfig() const;
    782 
    783  class StunAddrsHandler : public net::StunAddrsListener {
    784   public:
    785    explicit StunAddrsHandler(PeerConnectionImpl* aPc)
    786        : mPcHandle(aPc->GetHandle()) {}
    787 
    788    void OnMDNSQueryComplete(const nsCString& hostname,
    789                             const Maybe<nsCString>& address) override;
    790 
    791    void OnStunAddrsAvailable(const net::NrIceStunAddrArray& addrs) override;
    792 
    793   private:
    794    // This class is not cycle-collected, so we must avoid grabbing a strong
    795    // reference.
    796    const std::string mPcHandle;
    797    virtual ~StunAddrsHandler() {}
    798  };
    799 
    800  // Manage ICE transports.
    801  void UpdateTransport(const JsepTransceiver& aTransceiver, bool aForceIceTcp);
    802 
    803  void GatherIfReady();
    804  void FlushIceCtxOperationQueueIfReady();
    805  void PerformOrEnqueueIceCtxOperation(nsIRunnable* runnable);
    806  nsresult SetTargetForDefaultLocalAddressLookup();
    807  void EnsureIceGathering(bool aDefaultRouteOnly, bool aObfuscateHostAddresses);
    808 
    809  bool GetPrefDefaultAddressOnly() const;
    810  bool GetPrefObfuscateHostAddresses() const;
    811 
    812  bool IsIceCtxReady() const {
    813    return mLocalAddrsRequestState == STUN_ADDR_REQUEST_COMPLETE;
    814  }
    815 
    816  // Ensure ICE transports exist that we might need when offer/answer concludes
    817  void EnsureTransports(const JsepSession& aSession);
    818 
    819  void UpdateRTCDtlsTransports();
    820  void SaveStateForRollback();
    821  void RestoreStateForRollback();
    822  std::set<RefPtr<dom::RTCDtlsTransport>> GetActiveTransports() const;
    823 
    824  // Activate ICE transports at the conclusion of offer/answer,
    825  // or when rollback occurs.
    826  nsresult UpdateTransports(const JsepSession& aSession,
    827                            const bool forceIceTcp);
    828 
    829  void ResetStunAddrsForIceRestart() { mStunAddrs.Clear(); }
    830 
    831  // Start ICE checks.
    832  void StartIceChecks(const JsepSession& session);
    833 
    834  // Process a trickle ICE candidate.
    835  void AddIceCandidate(const std::string& candidate,
    836                       const std::string& aTransportId,
    837                       const std::string& aUFrag);
    838 
    839  // Handle complete media pipelines.
    840  // This updates codec parameters, starts/stops send/receive, and other
    841  // stuff that doesn't necessarily require negotiation. This can be called at
    842  // any time, not just when an offer/answer exchange completes.
    843  nsresult UpdateMediaPipelines();
    844 
    845  already_AddRefed<dom::RTCRtpTransceiver> CreateTransceiver(
    846      const std::string& aId, bool aIsVideo,
    847      const dom::RTCRtpTransceiverInit& aInit,
    848      dom::MediaStreamTrack* aSendTrack, bool aAddTrackMagic, ErrorResult& aRv);
    849 
    850  std::string GetTransportIdMatchingSendTrack(
    851      const dom::MediaStreamTrack& aTrack) const;
    852 
    853  // this determines if any track is peerIdentity constrained
    854  bool AnyLocalTrackHasPeerIdentity() const;
    855 
    856  bool AnyCodecHasPluginID(uint64_t aPluginID);
    857 
    858  already_AddRefed<nsIHttpChannelInternal> GetChannel() const;
    859 
    860  bool HasPendingSetParameters() const;
    861  void InvalidateLastReturnedParameters();
    862 
    863  RefPtr<WebrtcCallWrapper> mCall;
    864 
    865  // See Bug 1642419, this can be removed when all sites are working with RTX.
    866  bool mRtxIsAllowed = true;
    867 
    868  bool mDuplicateFingerprintQuirk = false;
    869 
    870  nsTArray<RefPtr<Operation>> mOperations;
    871  bool mChainingOperation = false;
    872  bool mUpdateNegotiationNeededFlagOnEmptyChain = false;
    873  bool mNegotiationNeeded = false;
    874  std::set<std::pair<std::string, std::string>> mLocalIceCredentialsToReplace;
    875 
    876  nsTArray<RefPtr<dom::RTCRtpTransceiver>> mTransceivers;
    877  RTCDtlsTransportMap mTransportIdToRTCDtlsTransport;
    878  RefPtr<dom::RTCSctpTransport> mSctpTransport;
    879  // This is similar to [[LastStableStateSender/ReceiverTransport]], but for
    880  // DataChannel.
    881  RefPtr<dom::RTCSctpTransport> mLastStableSctpTransport;
    882  RefPtr<dom::RTCDtlsTransport> mLastStableSctpDtlsTransport;
    883 
    884  // Used whenever we need to dispatch a runnable to STS to tweak something
    885  // on our ICE ctx, but are not ready to do so at the moment (eg; we are
    886  // waiting to get a callback with our http proxy config before we start
    887  // gathering or start checking)
    888  std::vector<nsCOMPtr<nsIRunnable>> mQueuedIceCtxOperations;
    889 
    890  // Set if prefs dictate that we should force the use of a web proxy.
    891  bool mForceProxy = false;
    892 
    893  // Used to cancel incoming stun addrs response
    894  RefPtr<net::StunAddrsRequestChild> mStunAddrsRequest;
    895 
    896  enum StunAddrRequestState {
    897    STUN_ADDR_REQUEST_NONE,
    898    STUN_ADDR_REQUEST_PENDING,
    899    STUN_ADDR_REQUEST_COMPLETE
    900  };
    901  // Used to track the state of the stun addr IPC request
    902  StunAddrRequestState mLocalAddrsRequestState = STUN_ADDR_REQUEST_NONE;
    903 
    904  // Used to store the result of the stun addr IPC request
    905  nsTArray<NrIceStunAddr> mStunAddrs;
    906 
    907  // Used to ensure the target for default local address lookup is only set
    908  // once.
    909  bool mTargetForDefaultLocalAddressLookupIsSet = false;
    910 
    911  // Keep track of local hostnames to register. Registration is deferred
    912  // until StartIceChecks has run. Accessed on main thread only.
    913  std::map<std::string, std::string> mMDNSHostnamesToRegister;
    914  bool mCanRegisterMDNSHostnamesDirectly = false;
    915 
    916  // Used to store the mDNS hostnames that we have registered
    917  std::set<std::string> mRegisteredMDNSHostnames;
    918 
    919  // web-compat stopgap
    920  bool mAllowOldSetParameters = false;
    921 
    922  // Used to store the mDNS hostnames that we have queried
    923  struct PendingIceCandidate {
    924    std::vector<std::string> mTokenizedCandidate;
    925    std::string mTransportId;
    926    std::string mUfrag;
    927  };
    928  std::map<std::string, std::list<PendingIceCandidate>> mQueriedMDNSHostnames;
    929 
    930  MediaEventListener mGatheringStateChangeListener;
    931  MediaEventListener mConnectionStateChangeListener;
    932  MediaEventListener mCandidateListener;
    933  MediaEventListener mAlpnNegotiatedListener;
    934  MediaEventListener mStateChangeListener;
    935  MediaEventListener mRtcpStateChangeListener;
    936 
    937  // Make absolutely sure our refcount does not go to 0 before Close() is called
    938  // This is because Close does a stats query, which needs the
    939  // PeerConnectionImpl to stick around until the query is done.
    940  RefPtr<PeerConnectionImpl> mKungFuDeathGrip;
    941  RefPtr<PacketDumper> mPacketDumper;
    942 
    943 public:
    944  // these are temporary until the DataChannel Listen/Connect API is removed
    945  unsigned short listenPort;
    946  unsigned short connectPort;
    947  char* connectStr;  // XXX ownership/free
    948 };
    949 
    950 // This is what is returned when you acquire on a handle
    951 class PeerConnectionWrapper {
    952 public:
    953  explicit PeerConnectionWrapper(const std::string& handle);
    954 
    955  PeerConnectionImpl* impl() { return impl_; }
    956 
    957 private:
    958  RefPtr<PeerConnectionImpl> impl_;
    959 };
    960 
    961 }  // namespace mozilla
    962 
    963 #undef NS_IMETHODIMP_TO_ERRORRESULT
    964 #undef NS_IMETHODIMP_TO_ERRORRESULT_RETREF
    965 #endif  // _PEER_CONNECTION_IMPL_H_