Bug 1297416 - Part 3: Add proxy-only mode and pref. r=drno
authorByron Campen [:bwc] <docfaraday@gmail.com>
Tue, 23 Aug 2016 15:15:33 -0500
changeset 313414 f17f59899b314ccdcfdf62ddb730c8c46b596c5a
parent 313413 ea1469f882726de365837bcf3a450db7f2bf3164
child 313415 57647be72e76cb9c8b8ea6069c6d53362c9892d9
push id30681
push userphilringnalda@gmail.com
push dateSat, 10 Sep 2016 07:13:06 +0000
treeherdermozilla-central@61cc64967515 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrno
bugs1297416
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1297416 - Part 3: Add proxy-only mode and pref. r=drno MozReview-Commit-ID: D1e9f3OkVsU
media/mtransport/nricectx.cpp
media/mtransport/nricectx.h
media/mtransport/test/ice_unittest.cpp
media/mtransport/test/transport_unittests.cpp
media/mtransport/third_party/nICEr/src/ice/ice_component.c
media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
modules/libpref/init/all.js
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -830,29 +830,35 @@ abort:
   nr_proxy_tunnel_config_destroy(&config);
   if (_status) {
     nr_socket_wrapper_factory_destroy(&wrapper);
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
-nsresult NrIceCtx::StartGathering(bool default_route_only) {
+nsresult NrIceCtx::StartGathering(bool default_route_only, bool proxy_only) {
   ASSERT_ON_THREAD(sts_target_);
   if (policy_ == ICE_POLICY_NONE) {
     return NS_OK;
   }
   SetGatheringState(ICE_CTX_GATHER_STARTED);
 
   if (default_route_only) {
     nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS);
   } else {
     nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS);
   }
 
+  if (proxy_only) {
+    nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_PROXY);
+  } else {
+    nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_PROXY);
+  }
+
   // This might start gathering for the first time, or again after
   // renegotiation, or might do nothing at all if gathering has already
   // finished.
   int r = nr_ice_gather(ctx_, &NrIceCtx::gather_cb, this);
 
   if (!r) {
     SetGatheringState(ICE_CTX_GATHER_COMPLETE);
   } else if (r != R_WOULDBLOCK) {
--- a/media/mtransport/nricectx.h
+++ b/media/mtransport/nricectx.h
@@ -302,17 +302,17 @@ class NrIceCtx {
   // StartGathering.
   nsresult SetResolver(nr_resolver *resolver);
 
   // Provide the proxy address. Must be called before
   // StartGathering.
   nsresult SetProxyServer(const NrIceProxyServer& proxy_server);
 
   // Start ICE gathering
-  nsresult StartGathering(bool default_route_only);
+  nsresult StartGathering(bool default_route_only, bool proxy_only);
 
   // Start checking
   nsresult StartChecks();
 
   // Finalize the ICE negotiation. I.e., there will be no
   // more forking.
   nsresult Finalize();
 
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -535,17 +535,18 @@ class IceTestPeer : public sigslot::has_
 
   void Gather(bool default_route_only = false) {
     nsresult res;
 
     test_utils_->sts_target()->Dispatch(
         WrapRunnableRet(&res,
                         ice_ctx_->ctx(),
                         &NrIceCtx::StartGathering,
-                        default_route_only),
+                        default_route_only,
+                        false),
         NS_DISPATCH_SYNC);
 
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void UseNat() {
     nat_->enabled_ = true;
   }
--- a/media/mtransport/test/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -638,16 +638,17 @@ class TransportTestPeer : public sigslot
     flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
     flow_->SignalStateChange.connect(this, &TransportTestPeer::StateChanged);
 
     // Start gathering
     test_utils_->sts_target()->Dispatch(
         WrapRunnableRet(&res,
                         ice_ctx_->ctx(),
                         &NrIceCtx::StartGathering,
+                        false,
                         false),
         NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void ConnectIce(TransportTestPeer *peer) {
     peer_ = peer;
 
--- a/media/mtransport/third_party/nICEr/src/ice/ice_component.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_component.c
@@ -202,16 +202,21 @@ static int nr_ice_component_initialize_u
   {
     nr_socket *sock;
     nr_ice_socket *isock=0;
     nr_ice_candidate *cand=0;
     int i;
     int j;
     int r,_status;
 
+    if(ctx->flags & NR_ICE_CTX_FLAGS_ONLY_PROXY) {
+      /* No UDP support if we must use a proxy */
+      return 0;
+    }
+
     /* Now one ice_socket for each address */
     for(i=0;i<addr_ct;i++){
       char suppress;
 
       if(r=NR_reg_get2_char(NR_ICE_REG_SUPPRESS_INTERFACE_PRFX,addrs[i].addr.ifname,&suppress)){
         if(r!=R_NOT_FOUND)
           ABORT(r);
       }
@@ -424,18 +429,19 @@ static int nr_ice_component_initialize_t
       if(r!=R_NOT_FOUND)
         ABORT(r);
     }
 
     if ((r=NR_reg_get_char(NR_ICE_REG_ICE_TCP_DISABLE, &ice_tcp_disabled))) {
       if (r != R_NOT_FOUND)
         ABORT(r);
     }
-    if (ctx->flags & NR_ICE_CTX_FLAGS_RELAY_ONLY) {
-      r_log(LOG_ICE,LOG_WARNING,"ICE(%s): relay only option results in ICE TCP being disabled",ctx->label);
+    if ((ctx->flags & NR_ICE_CTX_FLAGS_RELAY_ONLY) ||
+        (ctx->flags & NR_ICE_CTX_FLAGS_ONLY_PROXY)) {
+      r_log(LOG_ICE,LOG_WARNING,"ICE(%s): relay/proxy only option results in ICE TCP being disabled",ctx->label);
       ice_tcp_disabled = 1;
     }
 
     for(i=0;i<addr_ct;i++){
       char suppress;
       nr_ice_socket *isock_psv=0;
       nr_ice_socket *isock_so=0;
 
@@ -1084,16 +1090,22 @@ int nr_ice_component_pair_candidates(nr_
     nr_ice_candidate *lcand, *pcand;
     nr_ice_socket *isock;
     int r,_status;
 
     r_log(LOG_ICE,LOG_DEBUG,"Pairing candidates======");
 
     /* Create the candidate pairs */
     lcand=TAILQ_FIRST(&lcomp->candidates);
+
+    if (!lcand) {
+      /* No local candidates, initialized or not! */
+      ABORT(R_FAILED);
+    }
+
     while(lcand){
       if (lcand->state == NR_ICE_CAND_STATE_INITIALIZED) {
         if ((r = nr_ice_component_pair_candidate(pctx, pcomp, lcand, 0)))
           ABORT(r);
       }
 
       lcand=TAILQ_NEXT(lcand,entry_comp);
     }
--- a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
@@ -160,16 +160,17 @@ int nr_ice_ctx_create(char *label, UINT4
 int nr_ice_ctx_create_with_credentials(char *label, UINT4 flags, char* ufrag, char* pwd, nr_ice_ctx **ctxp);
 #define NR_ICE_CTX_FLAGS_OFFERER                           1
 #define NR_ICE_CTX_FLAGS_ANSWERER                          (1<<1)
 #define NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION             (1<<2)
 #define NR_ICE_CTX_FLAGS_LITE                              (1<<3)
 #define NR_ICE_CTX_FLAGS_RELAY_ONLY                        (1<<4)
 #define NR_ICE_CTX_FLAGS_HIDE_HOST_CANDIDATES              (1<<5)
 #define NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS                (1<<6)
+#define NR_ICE_CTX_FLAGS_ONLY_PROXY                        (1<<7)
 
 void nr_ice_ctx_add_flags(nr_ice_ctx *ctx, UINT4 flags);
 void nr_ice_ctx_remove_flags(nr_ice_ctx *ctx, UINT4 flags);
 int nr_ice_ctx_destroy(nr_ice_ctx **ctxp);
 int nr_ice_gather(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg);
 int nr_ice_add_candidate(nr_ice_ctx *ctx, nr_ice_candidate *cand);
 void nr_ice_gather_finished_cb(NR_SOCKET s, int h, void *cb_arg);
 int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp);
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -785,16 +785,28 @@ PeerConnectionMedia::GetPrefDefaultAddre
   default_address_only |=
     !MediaManager::Get()->IsActivelyCapturingOrHasAPermission(winId);
 #else
   bool default_address_only = true;
 #endif
   return default_address_only;
 }
 
+bool
+PeerConnectionMedia::GetPrefProxyOnly() const
+{
+  ASSERT_ON_THREAD(mMainThread); // will crash on STS thread
+
+#if !defined(MOZILLA_EXTERNAL_LINKAGE)
+  return Preferences::GetBool("media.peerconnection.ice.proxy_only", false);
+#else
+  return false;
+#endif
+}
+
 void
 PeerConnectionMedia::ConnectSignals(NrIceCtx *aCtx, NrIceCtx *aOldCtx)
 {
   aCtx->SignalGatheringStateChange.connect(
       this,
       &PeerConnectionMedia::IceGatheringStateChange_s);
   aCtx->SignalConnectionStateChange.connect(
       this,
@@ -882,31 +894,37 @@ PeerConnectionMedia::PerformOrEnqueueIce
 
 void
 PeerConnectionMedia::GatherIfReady() {
   ASSERT_ON_THREAD(mMainThread);
 
   nsCOMPtr<nsIRunnable> runnable(WrapRunnable(
         RefPtr<PeerConnectionMedia>(this),
         &PeerConnectionMedia::EnsureIceGathering_s,
-        GetPrefDefaultAddressOnly()));
+        GetPrefDefaultAddressOnly(),
+        GetPrefProxyOnly()));
 
   PerformOrEnqueueIceCtxOperation(runnable);
 }
 
 void
-PeerConnectionMedia::EnsureIceGathering_s(bool aDefaultRouteOnly) {
+PeerConnectionMedia::EnsureIceGathering_s(bool aDefaultRouteOnly,
+                                          bool aProxyOnly) {
   if (mProxyServer) {
     mIceCtxHdlr->ctx()->SetProxyServer(*mProxyServer);
+  } else if (aProxyOnly) {
+    IceGatheringStateChange_s(mIceCtxHdlr->ctx().get(),
+                              NrIceCtx::ICE_CTX_GATHER_COMPLETE);
+    return;
   }
 
   // Start gathering, but only if there are streams
   for (size_t i = 0; i < mIceCtxHdlr->ctx()->GetStreamCount(); ++i) {
     if (mIceCtxHdlr->ctx()->GetStream(i)) {
-      mIceCtxHdlr->ctx()->StartGathering(aDefaultRouteOnly);
+      mIceCtxHdlr->ctx()->StartGathering(aDefaultRouteOnly, aProxyOnly);
       return;
     }
   }
 
   // If there are no streams, we're probably in a situation where we've rolled
   // back while still waiting for our proxy configuration to come back. Make
   // sure content knows that the rollback has stuck wrt gathering.
   IceGatheringStateChange_s(mIceCtxHdlr->ctx().get(),
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -469,25 +469,26 @@ class PeerConnectionMedia : public sigsl
       const std::string& aUfrag,
       const std::string& aPassword,
       const std::vector<std::string>& aCandidateList);
   void RemoveTransportsAtOrAfter_s(size_t aMLine);
 
   void GatherIfReady();
   void FlushIceCtxOperationQueueIfReady();
   void PerformOrEnqueueIceCtxOperation(nsIRunnable* runnable);
-  void EnsureIceGathering_s(bool aDefaultRouteOnly);
+  void EnsureIceGathering_s(bool aDefaultRouteOnly, bool aProxyOnly);
   void StartIceChecks_s(bool aIsControlling,
                         bool aIsIceLite,
                         const std::vector<std::string>& aIceOptionsList);
 
   void BeginIceRestart_s(RefPtr<NrIceCtx> new_ctx);
   void FinalizeIceRestart_s();
   void RollbackIceRestart_s();
   bool GetPrefDefaultAddressOnly() const;
+  bool GetPrefProxyOnly() const;
 
   void ConnectSignals(NrIceCtx *aCtx, NrIceCtx *aOldCtx=nullptr);
 
   // Process a trickle ICE candidate.
   void AddIceCandidate_s(const std::string& aCandidate, const std::string& aMid,
                          uint32_t aMLine);
 
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -468,16 +468,17 @@ pref("media.peerconnection.ice.force_int
 pref("media.peerconnection.ice.relay_only", false); // Limit candidates to TURN
 pref("media.peerconnection.use_document_iceservers", true);
 pref("media.peerconnection.identity.enabled", true);
 pref("media.peerconnection.identity.timeout", 10000);
 pref("media.peerconnection.ice.stun_client_maximum_transmits", 7);
 pref("media.peerconnection.ice.trickle_grace_period", 5000);
 pref("media.peerconnection.ice.no_host", false);
 pref("media.peerconnection.ice.default_address_only", false);
+pref("media.peerconnection.ice.proxy_only", false);
 
 // These values (aec, agc, and noice) are from media/webrtc/trunk/webrtc/common_types.h
 // kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each
 // setting (for Xxx = Ec, Agc, or Ns).  Defaults are all set to kXxxDefault here.
 pref("media.peerconnection.turn.disable", false);
 #if defined(MOZ_WEBRTC_HARDWARE_AEC_NS)
 pref("media.getusermedia.aec_enabled", false);
 pref("media.getusermedia.noise_enabled", false);