Bug 1266667: added user-pref to force ICE TCP. r?bwc draft
authorNils Ohlmeier [:drno] <drno@ohlmeier.org>
Wed, 21 Dec 2016 23:40:45 -0800
changeset 457227 2dc4b672165b707808273bc37ce7dcf95d544f06
parent 454985 d7ff24fcafd4361b43ab1df0c453bdc48e6694ea
child 541430 5a338cad2f701188f3fc8bf3e8ac781da6fc08a8
push id40719
push userdrno@ohlmeier.org
push dateSat, 07 Jan 2017 08:19:49 +0000
reviewersbwc
bugs1266667
milestone53.0a1
Bug 1266667: added user-pref to force ICE TCP. r?bwc MozReview-Commit-ID: D0jZcqWkNdV
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -329,16 +329,17 @@ PeerConnectionImpl::PeerConnectionImpl(c
   , mCertificate(nullptr)
 #else
   , mIdentity(nullptr)
 #endif
   , mPrivacyRequested(false)
   , mSTSThread(nullptr)
   , mAllowIceLoopback(false)
   , mAllowIceLinkLocal(false)
+  , mForceIceTcp(false)
   , mMedia(nullptr)
   , mUuidGen(MakeUnique<PCUuidGenerator>())
   , mNumAudioStreams(0)
   , mNumVideoStreams(0)
   , mHaveConfiguredCodecs(false)
   , mHaveDataStream(false)
   , mAddCandidateErrorCount(0)
   , mTrickle(true) // TODO(ekr@rtfm.com): Use pref
@@ -359,16 +360,18 @@ PeerConnectionImpl::PeerConnectionImpl(c
   CSFLogInfo(logTag, "%s: PeerConnectionImpl constructor for %s",
              __FUNCTION__, mHandle.c_str());
   STAMP_TIMECARD(mTimeCard, "Constructor Completed");
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
   mAllowIceLoopback = Preferences::GetBool(
     "media.peerconnection.ice.loopback", false);
   mAllowIceLinkLocal = Preferences::GetBool(
     "media.peerconnection.ice.link_local", false);
+  mForceIceTcp = Preferences::GetBool(
+    "media.peerconnection.ice.force_ice_tcp", false);
 #endif
   memset(mMaxReceiving, 0, sizeof(mMaxReceiving));
   memset(mMaxSending, 0, sizeof(mMaxSending));
 }
 
 PeerConnectionImpl::~PeerConnectionImpl()
 {
   if (mTimeCard) {
@@ -2230,16 +2233,21 @@ PeerConnectionImpl::GetStats(MediaStream
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel) {
   PC_AUTO_ENTER_API_CALL(true);
 
+  if (mForceIceTcp && std::string::npos != std::string(aCandidate).find(" UDP ")) {
+    CSFLogError(logTag, "Blocking remote UDP candidate: %s", aCandidate);
+    return NS_OK;
+  }
+
   JSErrorResult rv;
   RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
   if (!pco) {
     return NS_OK;
   }
 
   STAMP_TIMECARD(mTimeCard, "Add Ice Candidate");
 
@@ -3158,17 +3166,17 @@ PeerConnectionImpl::SetSignalingState_m(
       }
     }
 
     // Either negotiation is done, or we've rolled back. In either case, we
     // need to re-evaluate whether further negotiation is required.
     mNegotiationNeeded = false;
     // If we're rolling back a local offer, we might need to remove some
     // transports, but nothing further needs to be done.
-    mMedia->ActivateOrRemoveTransports(*mJsepSession);
+    mMedia->ActivateOrRemoveTransports(*mJsepSession, mForceIceTcp);
     if (!rollback) {
       if (NS_FAILED(mMedia->UpdateMediaPipelines(*mJsepSession))) {
         CSFLogError(logTag, "Error Updating MediaPipelines");
         NS_ASSERTION(false, "Error Updating MediaPipelines in SetSignalingState_m()");
         // XXX what now?  Not much we can do but keep going, without major restructuring
       }
       InitializeDataChannel();
       mMedia->StartIceChecks(*mJsepSession);
@@ -3327,16 +3335,21 @@ toDomIceGatheringState(NrIceCtx::Gatheri
   MOZ_CRASH();
 }
 
 void
 PeerConnectionImpl::CandidateReady(const std::string& candidate,
                                    uint16_t level) {
   PC_AUTO_ENTER_API_CALL_VOID_RETURN(false);
 
+  if (mForceIceTcp && std::string::npos != candidate.find(" UDP ")) {
+    CSFLogError(logTag, "Blocking local UDP candidate: %s", candidate.c_str());
+    return;
+  }
+
   std::string mid;
   bool skipped = false;
   nsresult res = mJsepSession->AddLocalIceCandidate(candidate,
                                                     level,
                                                     &mid,
                                                     &skipped);
 
   if (NS_FAILED(res)) {
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -806,16 +806,17 @@ private:
 
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // DataConnection that's used to get all the DataChannels
   RefPtr<mozilla::DataChannelConnection> mDataConnection;
 #endif
 
   bool mAllowIceLoopback;
   bool mAllowIceLinkLocal;
+  bool mForceIceTcp;
   RefPtr<PeerConnectionMedia> mMedia;
 
   // The JSEP negotiation session.
   mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
   mozilla::UniquePtr<mozilla::JsepSession> mJsepSession;
   std::string mPreviousIceUfrag; // used during rollback of ice restart
   std::string mPreviousIcePwd; // used during rollback of ice restart
 
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -463,17 +463,18 @@ PeerConnectionMedia::EnsureTransport_s(s
     stream->SignalReady.connect(this, &PeerConnectionMedia::IceStreamReady_s);
     stream->SignalCandidate.connect(this,
                                     &PeerConnectionMedia::OnCandidateFound_s);
     mIceCtxHdlr->ctx()->SetStream(aLevel, stream);
   }
 }
 
 void
-PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession)
+PeerConnectionMedia::ActivateOrRemoveTransports(const JsepSession& aSession,
+                                                const bool forceIceTcp)
 {
   auto transports = aSession.GetTransports();
   for (size_t i = 0; i < transports.size(); ++i) {
     RefPtr<JsepTransport> transport = transports[i];
 
     std::string ufrag;
     std::string pwd;
     std::vector<std::string> candidates;
@@ -486,16 +487,24 @@ PeerConnectionMedia::ActivateOrRemoveTra
       candidates = transport->mIce->GetCandidates();
     } else {
       CSFLogDebug(logTag, "Transport %u is disabled", static_cast<unsigned>(i));
       // Make sure the MediaPipelineFactory doesn't try to use these.
       RemoveTransportFlow(i, false);
       RemoveTransportFlow(i, true);
     }
 
+    if (forceIceTcp) {
+      candidates.erase(std::remove_if(candidates.begin(),
+                                      candidates.end(),
+                                      [](const std::string & s) {
+                                        return s.find(" UDP "); }),
+                       candidates.end());
+    }
+
     RUN_ON_THREAD(
         GetSTSThread(),
         WrapRunnable(RefPtr<PeerConnectionMedia>(this),
                      &PeerConnectionMedia::ActivateOrRemoveTransport_s,
                      i,
                      transport->mComponents,
                      ufrag,
                      pwd,
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -265,17 +265,18 @@ class PeerConnectionMedia : public sigsl
     return mIceCtxHdlr->ctx()->GetStreamCount();
   }
 
   // Ensure ICE transports exist that we might need when offer/answer concludes
   void EnsureTransports(const JsepSession& aSession);
 
   // Activate or remove ICE transports at the conclusion of offer/answer,
   // or when rollback occurs.
-  void ActivateOrRemoveTransports(const JsepSession& aSession);
+  void ActivateOrRemoveTransports(const JsepSession& aSession,
+                                  const bool forceIceTcp);
 
   // Start ICE checks.
   void StartIceChecks(const JsepSession& session);
 
   bool IsIceRestarting() const;
   IceRestartState GetIceRestartState() const;
 
   // Begin ICE restart