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_