Bug 1189040: add a whitelist for network interfaces to use with ICE/webrtc r=ekr
authorRandell Jesup <rjesup@jesup.org>
Wed, 12 Aug 2015 19:45:36 -0400
changeset 257528 9141e5b245f644ad4940f9d5b1903b8a86762fe8
parent 257527 4f0f45233e6be53b101bd97891bbacf3c3c37c5d
child 257529 89be963360a2daef1f86c1853953748dd3de270a
push id29221
push userryanvm@gmail.com
push dateThu, 13 Aug 2015 14:43:44 +0000
treeherdermozilla-central@0cddd6a6565a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersekr
bugs1189040
milestone43.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 1189040: add a whitelist for network interfaces to use with ICE/webrtc r=ekr
media/mtransport/nricectx.cpp
media/mtransport/third_party/nICEr/src/ice/ice_ctx.c
media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
media/mtransport/third_party/nICEr/src/ice/ice_reg.h
modules/libpref/init/all.js
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -430,16 +430,17 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const 
       NR_reg_set_uchar((char *)"ice.pref.interface.virbr0", 233);
       NR_reg_set_uchar((char *)"ice.pref.interface.wlan0", 232);
     }
 
     int32_t stun_client_maximum_transmits = 7;
     int32_t ice_trickle_grace_period = 5000;
     int32_t ice_tcp_so_sock_count = 3;
     int32_t ice_tcp_listen_backlog = 10;
+    nsAutoCString force_net_interface;
 #ifndef MOZILLA_XPCOMRT_API
     nsresult res;
     nsCOMPtr<nsIPrefService> prefs =
       do_GetService("@mozilla.org/preferences-service;1", &res);
 
     if (NS_SUCCEEDED(res)) {
       nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
       if (branch) {
@@ -450,16 +451,19 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const 
             "media.peerconnection.ice.trickle_grace_period",
             &ice_trickle_grace_period);
         branch->GetIntPref(
             "media.peerconnection.ice.tcp_so_sock_count",
             &ice_tcp_so_sock_count);
         branch->GetIntPref(
             "media.peerconnection.ice.tcp_listen_backlog",
             &ice_tcp_listen_backlog);
+        branch->GetCharPref(
+            "media.peerconnection.ice.force_interface",
+            getter_Copies(force_net_interface));
       }
     }
 #endif
     NR_reg_set_uint4((char *)"stun.client.maximum_transmits",
                      stun_client_maximum_transmits);
     NR_reg_set_uint4((char *)NR_ICE_REG_TRICKLE_GRACE_PERIOD,
                      ice_trickle_grace_period);
     NR_reg_set_int4((char *)NR_ICE_REG_ICE_TCP_SO_SOCK_COUNT,
@@ -473,16 +477,21 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const 
 
     if (allow_loopback) {
       NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, 1);
     }
 
     if (allow_link_local) {
       NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LINK_LOCAL_ADDRS, 1);
     }
+    if (force_net_interface.Length() > 0) {
+      // Stupid cast.... but needed
+      const nsCString& flat = PromiseFlatCString(static_cast<nsACString&>(force_net_interface));
+      NR_reg_set_string((char *)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME, const_cast<char*>(flat.get()));
+    }
   }
 
   // Create the ICE context
   int r;
 
   UINT4 flags = offerer ? NR_ICE_CTX_FLAGS_OFFERER:
       NR_ICE_CTX_FLAGS_ANSWERER;
   flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION;
--- a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.c
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.c
@@ -311,17 +311,17 @@ int nr_ice_fetch_turn_servers(int ct, nr
   abort:
     RFREE(data.data);
     RFREE(addr);
     if (_status) RFREE(servers);
     return(_status);
   }
 #endif /* USE_TURN */
 
-#define MAXADDRS 100 // Ridiculously high
+#define MAXADDRS 100 /* Ridiculously high */
 int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp)
   {
     nr_ice_ctx *ctx=0;
     int r,_status;
     char buf[100];
 
     if(r=r_log_register("ice", &LOG_ICE))
       ABORT(r);
@@ -395,16 +395,24 @@ int nr_ice_ctx_create(char *label, UINT4
 #endif /* USE_TURN */
 
 
     ctx->Ta = 20;
 
     if (r=nr_socket_factory_create_int(NULL, &default_socket_factory_vtbl, &ctx->socket_factory))
       ABORT(r);
 
+    if ((r=NR_reg_get_string((char *)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME, ctx->force_net_interface, sizeof(ctx->force_net_interface)))) {
+      if (r == R_NOT_FOUND) {
+        ctx->force_net_interface[0] = 0;
+      } else {
+        ABORT(r);
+      }
+    }
+
     STAILQ_INIT(&ctx->streams);
     STAILQ_INIT(&ctx->sockets);
     STAILQ_INIT(&ctx->foundations);
     STAILQ_INIT(&ctx->peers);
     STAILQ_INIT(&ctx->ids);
 
     *ctxp=ctx;
 
@@ -487,17 +495,17 @@ void nr_ice_gather_finished_cb(NR_SOCKET
 
     assert(cb_arg);
     if (!cb_arg)
       return;
     ctx = cand->ctx;
 
     ctx->uninitialized_candidates--;
 
-    // Avoid the need for yet another initialization function
+    /* Avoid the need for yet another initialization function */
     if (cand->state == NR_ICE_CAND_STATE_INITIALIZING && cand->type == HOST)
       cand->state = NR_ICE_CAND_STATE_INITIALIZED;
 
     if (cand->state == NR_ICE_CAND_STATE_INITIALIZED) {
       int was_pruned = 0;
 
       if (r=nr_ice_component_maybe_prune_candidate(ctx, cand->component,
                                                    cand, &was_pruned)) {
@@ -635,16 +643,33 @@ static int nr_ice_get_local_addresses(nr
 
     if (!ctx->local_addrs) {
       /* First, gather all the local addresses we have */
       if((r=nr_stun_find_local_addresses(local_addrs,MAXADDRS,&addr_ct))) {
         r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to find local addresses",ctx->label);
         ABORT(r);
       }
 
+      if (ctx->force_net_interface[0]) {
+        /* Limit us to only addresses on a single interface */
+        int force_addr_ct = 0;
+        for(i=0;i<addr_ct;i++){
+          if (!strcmp(local_addrs[i].addr.ifname, ctx->force_net_interface)) {
+            // copy it down in the array, if needed
+            if (i != force_addr_ct) {
+              if (r=nr_local_addr_copy(&local_addrs[force_addr_ct], &local_addrs[i])) {
+                ABORT(r);
+              }
+            }
+            force_addr_ct++;
+          }
+        }
+        addr_ct = force_addr_ct;
+      }
+
       if (ctx->flags & NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS) {
         /* Get just the default IPv4 and IPv6 addrs */
         if(!nr_ice_get_default_local_address(ctx, NR_IPV4, local_addrs, addr_ct,
                                              &default_addrs[default_addr_ct])) {
           ++default_addr_ct;
         }
         if(!nr_ice_get_default_local_address(ctx, NR_IPV6, local_addrs, addr_ct,
                                              &default_addrs[default_addr_ct])) {
@@ -796,18 +821,16 @@ static int nr_ice_random_string(char *st
     int needed;
     int r,_status;
 
     if(len%2) ABORT(R_BAD_ARGS);
     needed=len/2;
 
     if(needed>sizeof(bytes)) ABORT(R_BAD_ARGS);
 
-    //memset(bytes,0,needed);
-
     if(r=nr_crypto_random_bytes(bytes,needed))
       ABORT(r);
 
     if(r=nr_bin2hex(bytes,needed,(unsigned char *)str))
       ABORT(r);
 
     _status=0;
   abort:
@@ -925,9 +948,8 @@ int nr_ice_ctx_hide_candidate(nr_ice_ctx
 
     if (ctx->flags & NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS) {
       if (cand->type == HOST)
         return 1;
     }
 
     return 0;
   }
-
--- a/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_ctx.h
@@ -145,16 +145,18 @@ struct nr_ice_ctx_ {
   nr_ice_peer_ctx_head peers;
   nr_ice_stun_id_head ids;
 
   NR_async_cb done_cb;
   void *cb_arg;
 
   nr_ice_trickle_candidate_cb trickle_cb;
   void *trickle_cb_arg;
+
+  char force_net_interface[MAXIFNAME];
 };
 
 int nr_ice_ctx_create(char *label, UINT4 flags, 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)
--- a/media/mtransport/third_party/nICEr/src/ice/ice_reg.h
+++ b/media/mtransport/third_party/nICEr/src/ice/ice_reg.h
@@ -65,13 +65,15 @@ extern "C" {
 
 #define NR_ICE_REG_ICE_TCP_DISABLE          "ice.tcp.disable"
 #define NR_ICE_REG_ICE_TCP_SO_SOCK_COUNT    "ice.tcp.so_sock_count"
 #define NR_ICE_REG_ICE_TCP_LISTEN_BACKLOG   "ice.tcp.listen_backlog"
 
 #define NR_ICE_REG_KEEPALIVE_TIMER          "ice.keepalive_timer"
 
 #define NR_ICE_REG_TRICKLE_GRACE_PERIOD     "ice.trickle_grace_period"
+#define NR_ICE_REG_PREF_FORCE_INTERFACE_NAME "ice.forced_interface_name"
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 #endif
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -393,16 +393,17 @@ pref("media.peerconnection.video.min_bit
 pref("media.peerconnection.video.start_bitrate", 300);
 pref("media.peerconnection.video.max_bitrate", 2000);
 #endif
 pref("media.navigator.permission.disabled", false);
 pref("media.peerconnection.default_iceservers", "[]");
 pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments.
 pref("media.peerconnection.ice.tcp", false);
 pref("media.peerconnection.ice.link_local", false); // Set only for testing IPV6 in networks that don't assign IPV6 addresses
+pref("media.peerconnection.ice.force_interface", ""); // Limit to only a single interface
 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.default_address_only", false);