void PeerConnectionMedia::FinalizeIceRestart() { ASSERT_ON_THREAD(mMainThread); if (!IsIceRestarting()) { return; } RUN_ON_THREAD(GetSTSThread(), WrapRunnable( RefPtr<PeerConnectionMedia>(this), &PeerConnectionMedia::FinalizeIceRestart_s), NS_DISPATCH_NORMAL); mIceRestartState = ICE_RESTART_NONE; }
void PeerConnectionMedia::BeginIceRestart(const std::string& ufrag, const std::string& pwd) { ASSERT_ON_THREAD(mMainThread); if (IsIceRestarting()) { return; } RefPtr<NrIceCtx> new_ctx = mIceCtxHdlr->CreateCtx(ufrag, pwd); RUN_ON_THREAD(GetSTSThread(), WrapRunnable( RefPtr<PeerConnectionMedia>(this), &PeerConnectionMedia::BeginIceRestart_s, new_ctx), NS_DISPATCH_NORMAL); mIceRestartState = ICE_RESTART_PROVISIONAL; }
nsresult PeerConnectionMedia::UpdateTransportFlow( size_t aLevel, bool aIsRtcp, const JsepTransport& aTransport) { if (aIsRtcp && aTransport.mComponents < 2) { RemoveTransportFlow(aLevel, aIsRtcp); return NS_OK; } if (!aIsRtcp && !aTransport.mComponents) { RemoveTransportFlow(aLevel, aIsRtcp); return NS_OK; } nsresult rv; RefPtr<TransportFlow> flow = GetTransportFlow(aLevel, aIsRtcp); if (flow) { if (IsIceRestarting()) { CSFLogInfo(LOGTAG, "Flow[%s]: detected ICE restart - level: %u rtcp: %d", flow->id().c_str(), (unsigned)aLevel, aIsRtcp); RefPtr<PeerConnectionMedia> pcMedia(this); rv = GetSTSThread()->Dispatch( WrapRunnableNM(AddNewIceStreamForRestart_s, pcMedia, flow, aLevel, aIsRtcp), NS_DISPATCH_NORMAL); if (NS_FAILED(rv)) { CSFLogError(LOGTAG, "Failed to dispatch AddNewIceStreamForRestart_s"); return rv; } } return NS_OK; } std::ostringstream osId; osId << mParentHandle << ":" << aLevel << "," << (aIsRtcp ? "rtcp" : "rtp"); flow = new TransportFlow(osId.str()); // The media streams are made on STS so we need to defer setup. auto ice = MakeUnique<TransportLayerIce>(); auto dtls = MakeUnique<TransportLayerDtls>(); dtls->SetRole(aTransport.mDtls->GetRole() == JsepDtlsTransport::kJsepDtlsClient ? TransportLayerDtls::CLIENT : TransportLayerDtls::SERVER); RefPtr<DtlsIdentity> pcid = mParent->Identity(); if (!pcid) { CSFLogError(LOGTAG, "Failed to get DTLS identity."); return NS_ERROR_FAILURE; } dtls->SetIdentity(pcid); const SdpFingerprintAttributeList& fingerprints = aTransport.mDtls->GetFingerprints(); for (const auto& fingerprint : fingerprints.mFingerprints) { std::ostringstream ss; ss << fingerprint.hashFunc; rv = dtls->SetVerificationDigest(ss.str(), &fingerprint.fingerprint[0], fingerprint.fingerprint.size()); if (NS_FAILED(rv)) { CSFLogError(LOGTAG, "Could not set fingerprint"); return rv; } } std::vector<uint16_t> srtpCiphers; srtpCiphers.push_back(SRTP_AES128_CM_HMAC_SHA1_80); srtpCiphers.push_back(SRTP_AES128_CM_HMAC_SHA1_32); rv = dtls->SetSrtpCiphers(srtpCiphers); if (NS_FAILED(rv)) { CSFLogError(LOGTAG, "Couldn't set SRTP ciphers"); return rv; } // Always permits negotiation of the confidential mode. // Only allow non-confidential (which is an allowed default), // if we aren't confidential. std::set<std::string> alpn; std::string alpnDefault = ""; alpn.insert("c-webrtc"); if (!mParent->PrivacyRequested()) { alpnDefault = "webrtc"; alpn.insert(alpnDefault); } rv = dtls->SetAlpn(alpn, alpnDefault); if (NS_FAILED(rv)) { CSFLogError(LOGTAG, "Couldn't set ALPN"); return rv; } nsAutoPtr<PtrVector<TransportLayer> > layers(new PtrVector<TransportLayer>); layers->values.push_back(ice.release()); layers->values.push_back(dtls.release()); RefPtr<PeerConnectionMedia> pcMedia(this); rv = GetSTSThread()->Dispatch( WrapRunnableNM(FinalizeTransportFlow_s, pcMedia, flow, aLevel, aIsRtcp, layers), NS_DISPATCH_NORMAL); if (NS_FAILED(rv)) { CSFLogError(LOGTAG, "Failed to dispatch FinalizeTransportFlow_s"); return rv; } AddTransportFlow(aLevel, aIsRtcp, flow); return NS_OK; }