Bug 1193437: Use config structs in NrIceCtx, and centralize pref lookups some. r=mjf, a=RyanVM
authorByron Campen [:bwc] <docfaraday@gmail.com>
Thu, 09 Jul 2020 15:36:07 +0000
changeset 599935 58e9540c98888cc87231cba05e2fdd444711f0ef
parent 599934 f64d74a9b713d0237f03593b7adcd79a77c9b02d
child 599936 56922d42adad86d28f2225ec6a94154a4821cdf2
push id41
push userryanvm@gmail.com
push dateThu, 16 Jul 2020 22:30:31 +0000
treeherdermozilla-esr78@0fa2e6171e7d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmjf, RyanVM
bugs1193437
milestone78.1.0
Bug 1193437: Use config structs in NrIceCtx, and centralize pref lookups some. r=mjf, a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D82549
media/mtransport/nricectx.cpp
media/mtransport/nricectx.h
media/mtransport/test/ice_unittest.cpp
media/mtransport/test/multi_tcp_socket_unittest.cpp
media/mtransport/test/test_nr_socket_ice_unittest.cpp
media/mtransport/test/transport_unittests.cpp
media/mtransport/test/turn_unittest.cpp
media/webrtc/signaling/src/peerconnection/MediaTransportHandler.cpp
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -260,40 +260,36 @@ nsresult NrIceTurnServer::ToNicerTurnStr
   if (r) {
     RFREE(server->username);
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
-NrIceCtx::NrIceCtx(const std::string& name, Policy policy)
+NrIceCtx::NrIceCtx(const std::string& name, const Config& aConfig)
     : connection_state_(ICE_CTX_INIT),
       gathering_state_(ICE_CTX_GATHER_INIT),
       name_(name),
       ice_controlling_set_(false),
       streams_(),
       ctx_(nullptr),
       peer_(nullptr),
       ice_handler_vtbl_(nullptr),
       ice_handler_(nullptr),
       trickle_(true),
-      policy_(policy),
+      config_(aConfig),
       nat_(nullptr),
       proxy_config_(nullptr),
       obfuscate_host_addresses_(false) {}
 
 /* static */
-RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name, bool allow_loopback,
-                                  bool tcp_enabled, bool allow_link_local,
-                                  Policy policy) {
-  // InitializeGlobals only executes once
-  NrIceCtx::InitializeGlobals(allow_loopback, tcp_enabled, allow_link_local);
-
-  RefPtr<NrIceCtx> ctx = new NrIceCtx(name, policy);
+RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& aName,
+                                  const Config& aConfig) {
+  RefPtr<NrIceCtx> ctx = new NrIceCtx(aName, aConfig);
 
   if (!ctx->Initialize()) {
     return nullptr;
   }
 
   return ctx;
 }
 
@@ -452,18 +448,17 @@ void NrIceCtx::trickle_cb(void* arg, nr_
   if (r) return;
 
   MOZ_MTLOG(ML_INFO, "NrIceCtx(" << ctx->name_ << "): trickling candidate "
                                  << candidate_str);
 
   s->SignalCandidate(s, candidate_str, stream->ufrag, mdns_addr, actual_addr);
 }
 
-void NrIceCtx::InitializeGlobals(bool allow_loopback, bool tcp_enabled,
-                                 bool allow_link_local) {
+void NrIceCtx::InitializeGlobals(const GlobalConfig& aConfig) {
   RLogConnector::CreateInstance();
   // Initialize the crypto callbacks and logging stuff
   if (!initialized) {
     NR_reg_init(NR_REG_MODE_LOCAL);
     nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl;
     initialized = true;
 
     // Set the priorites for candidate type preferences.
@@ -471,67 +466,37 @@ void NrIceCtx::InitializeGlobals(bool al
     NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_SRV_RFLX, 100);
     NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_PEER_RFLX, 110);
     NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_HOST, 126);
     NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_RELAYED, 5);
     NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_SRV_RFLX_TCP, 99);
     NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_PEER_RFLX_TCP, 109);
     NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_HOST_TCP, 125);
     NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_RELAYED_TCP, 0);
-
-    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;
-    nsresult res;
-    nsCOMPtr<nsIPrefService> prefs =
-        do_GetService("@mozilla.org/preferences-service;1", &res);
+    NR_reg_set_uint4((char*)"stun.client.maximum_transmits",
+                     aConfig.mStunClientMaxTransmits);
+    NR_reg_set_uint4((char*)NR_ICE_REG_TRICKLE_GRACE_PERIOD,
+                     aConfig.mTrickleIceGracePeriod);
+    NR_reg_set_int4((char*)NR_ICE_REG_ICE_TCP_SO_SOCK_COUNT,
+                    aConfig.mIceTcpSoSockCount);
+    NR_reg_set_int4((char*)NR_ICE_REG_ICE_TCP_LISTEN_BACKLOG,
+                    aConfig.mIceTcpListenBacklog);
 
-    if (NS_SUCCEEDED(res)) {
-      nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
-      if (branch) {
-        branch->GetIntPref(
-            "media.peerconnection.ice.stun_client_maximum_transmits",
-            &stun_client_maximum_transmits);
-        branch->GetIntPref("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",
-                            force_net_interface);
-      }
-    }
+    NR_reg_set_char((char*)NR_ICE_REG_ICE_TCP_DISABLE, !aConfig.mTcpEnabled);
 
-    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,
-                    ice_tcp_so_sock_count);
-    NR_reg_set_int4((char*)NR_ICE_REG_ICE_TCP_LISTEN_BACKLOG,
-                    ice_tcp_listen_backlog);
-
-    NR_reg_set_char((char*)NR_ICE_REG_ICE_TCP_DISABLE, !tcp_enabled);
-
-    if (allow_loopback) {
+    if (aConfig.mAllowLoopback) {
       NR_reg_set_char((char*)NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, 1);
     }
 
-    if (allow_link_local) {
+    if (aConfig.mAllowLinkLocal) {
       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));
+    if (!aConfig.mForceNetInterface.Length()) {
       NR_reg_set_string((char*)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME,
-                        const_cast<char*>(flat.get()));
+                        const_cast<char*>(aConfig.mForceNetInterface.get()));
     }
   }
 }
 
 void NrIceCtx::SetTargetForDefaultLocalAddressLookup(
     const std::string& target_ip, uint16_t target_port) {
   nr_ice_set_target_for_default_local_address_lookup(ctx_, target_ip.c_str(),
                                                      target_port);
@@ -578,17 +543,17 @@ void NrIceCtx::SetStunAddrs(const nsTArr
   delete[] local_addrs;
 }
 
 bool NrIceCtx::Initialize() {
   // Create the ICE context
   int r;
 
   UINT4 flags = NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION;
-  switch (policy_) {
+  switch (config_.mPolicy) {
     case ICE_POLICY_RELAY:
       flags |= NR_ICE_CTX_FLAGS_RELAY_ONLY;
       break;
     case ICE_POLICY_NO_HOST:
       flags |= NR_ICE_CTX_FLAGS_HIDE_HOST_CANDIDATES;
       break;
     case ICE_POLICY_ALL:
       break;
@@ -627,48 +592,24 @@ bool NrIceCtx::Initialize() {
   if (generating_trickle()) {
     r = nr_ice_ctx_set_trickle_cb(ctx_, &NrIceCtx::trickle_cb, this);
     if (r) {
       MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << name_ << "'");
       return false;
     }
   }
 
-  nsAutoCString mapping_type;
-  nsAutoCString filtering_type;
-  bool block_udp = false;
-  bool block_tcp = false;
-
-  nsresult rv;
-  nsCOMPtr<nsIPrefService> pref_service =
-      do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
-
-  if (NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsIPrefBranch> pref_branch;
-    rv = pref_service->GetBranch(nullptr, getter_AddRefs(pref_branch));
-    if (NS_SUCCEEDED(rv)) {
-      Unused << pref_branch->GetCharPref(
-          "media.peerconnection.nat_simulator.mapping_type", mapping_type);
-      Unused << pref_branch->GetCharPref(
-          "media.peerconnection.nat_simulator.filtering_type", filtering_type);
-      Unused << pref_branch->GetBoolPref(
-          "media.peerconnection.nat_simulator.block_udp", &block_udp);
-      Unused << pref_branch->GetBoolPref(
-          "media.peerconnection.nat_simulator.block_tcp", &block_tcp);
-    }
-  }
-
-  if (!mapping_type.IsEmpty() && !filtering_type.IsEmpty()) {
-    MOZ_MTLOG(ML_DEBUG, "NAT filtering type: " << filtering_type.get());
-    MOZ_MTLOG(ML_DEBUG, "NAT mapping type: " << mapping_type.get());
+  if (config_.mNatSimulatorConfig.isSome()) {
     TestNat* test_nat = new TestNat;
-    test_nat->filtering_type_ = TestNat::ToNatBehavior(filtering_type.get());
-    test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type.get());
-    test_nat->block_udp_ = block_udp;
-    test_nat->block_tcp_ = block_tcp;
+    test_nat->filtering_type_ = TestNat::ToNatBehavior(
+        config_.mNatSimulatorConfig->mFilteringType.get());
+    test_nat->mapping_type_ =
+        TestNat::ToNatBehavior(config_.mNatSimulatorConfig->mMappingType.get());
+    test_nat->block_udp_ = config_.mNatSimulatorConfig->mBlockUdp;
+    test_nat->block_tcp_ = config_.mNatSimulatorConfig->mBlockTcp;
     test_nat->enabled_ = true;
     SetNat(test_nat);
   }
 
   // Create the handler objects
   ice_handler_vtbl_ = new nr_ice_handler_vtbl();
   ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair;
   ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready;
@@ -687,16 +628,17 @@ bool NrIceCtx::Initialize() {
   std::string peer_name = name_ + ":default";
   r = nr_ice_peer_ctx_create(ctx_, ice_handler_,
                              const_cast<char*>(peer_name.c_str()), &peer_);
   if (r) {
     MOZ_MTLOG(ML_ERROR, "Couldn't create ICE peer ctx for '" << name_ << "'");
     return false;
   }
 
+  nsresult rv;
   sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
 
   if (!NS_SUCCEEDED(rv)) return false;
 
   return true;
 }
 
 int NrIceCtx::SetNat(const RefPtr<TestNat>& aNat) {
@@ -779,21 +721,16 @@ nsresult NrIceCtx::SetControlling(Contro
   }
   return NS_OK;
 }
 
 NrIceCtx::Controlling NrIceCtx::GetControlling() {
   return (peer_->controlling) ? ICE_CONTROLLING : ICE_CONTROLLED;
 }
 
-nsresult NrIceCtx::SetPolicy(Policy policy) {
-  policy_ = policy;
-  return NS_OK;
-}
-
 nsresult NrIceCtx::SetStunServers(
     const std::vector<NrIceStunServer>& stun_servers) {
   if (stun_servers.empty()) return NS_OK;
 
   auto servers = MakeUnique<nr_ice_stun_server[]>(stun_servers.size());
 
   for (size_t i = 0; i < stun_servers.size(); ++i) {
     nsresult rv = stun_servers[i].ToNicerStunStruct(&servers[i]);
--- a/media/mtransport/nricectx.h
+++ b/media/mtransport/nricectx.h
@@ -58,16 +58,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #include "sigslot.h"
 
 #include "prnetdb.h"
 
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsIEventTarget.h"
 #include "nsTArray.h"
+#include "mozilla/Maybe.h"
 
 #include "m_cpp_utils.h"
 #include "nricestunaddr.h"
 #include "nricemediastream.h"
 
 typedef struct nr_ice_ctx_ nr_ice_ctx;
 typedef struct nr_ice_peer_ctx_ nr_ice_peer_ctx;
 typedef struct nr_ice_media_stream_ nr_ice_media_stream;
@@ -196,30 +197,49 @@ class NrIceCtx {
     ICE_CTX_GATHER_STARTED,
     ICE_CTX_GATHER_COMPLETE
   };
 
   enum Controlling { ICE_CONTROLLING, ICE_CONTROLLED };
 
   enum Policy { ICE_POLICY_RELAY, ICE_POLICY_NO_HOST, ICE_POLICY_ALL };
 
-  static RefPtr<NrIceCtx> Create(
-      const std::string& name, bool allow_loopback = false,
-      bool tcp_enabled = true, bool allow_link_local = false,
-      NrIceCtx::Policy policy = NrIceCtx::ICE_POLICY_ALL);
+  struct NatSimulatorConfig {
+    bool mBlockTcp = false;
+    bool mBlockUdp = false;
+    nsCString mMappingType = NS_LITERAL_CSTRING("ENDPOINT_INDEPENDENT");
+    nsCString mFilteringType = NS_LITERAL_CSTRING("ENDPOINT_INDEPENDENT");
+  };
+
+  struct Config {
+    NrIceCtx::Policy mPolicy = NrIceCtx::ICE_POLICY_ALL;
+    Maybe<NatSimulatorConfig> mNatSimulatorConfig;
+  };
+
+  static RefPtr<NrIceCtx> Create(const std::string& aName,
+                                 const Config& aConfig);
 
   RefPtr<NrIceMediaStream> CreateStream(const std::string& id,
                                         const std::string& name,
                                         int components);
   void DestroyStream(const std::string& id);
 
+  struct GlobalConfig {
+    bool mAllowLinkLocal = false;
+    bool mAllowLoopback = false;
+    bool mTcpEnabled = true;
+    int mStunClientMaxTransmits = 7;
+    int mTrickleIceGracePeriod = 5000;
+    int mIceTcpSoSockCount = 3;
+    int mIceTcpListenBacklog = 10;
+    nsCString mForceNetInterface;
+  };
+
   // initialize ICE globals, crypto, and logging
-  static void InitializeGlobals(bool allow_loopback = false,
-                                bool tcp_enabled = true,
-                                bool allow_link_local = false);
+  static void InitializeGlobals(const GlobalConfig& aConfig);
 
   void SetTargetForDefaultLocalAddressLookup(const std::string& target_ip,
                                              uint16_t target_port);
 
   // static GetStunAddrs for use in parent process to support
   // sandboxing restrictions
   static nsTArray<NrIceStunAddr> GetStunAddrs();
   void SetStunAddrs(const nsTArray<NrIceStunAddr>& addrs);
@@ -273,22 +293,16 @@ class NrIceCtx {
   // Set the other side's global attributes
   nsresult ParseGlobalAttributes(std::vector<std::string> attrs);
 
   // Set whether we are controlling or not.
   nsresult SetControlling(Controlling controlling);
 
   Controlling GetControlling();
 
-  // Set whether we're allowed to produce none, relay or all candidates.
-  // TODO(jib@mozilla.com): Work out what change means mid-connection (1181768)
-  nsresult SetPolicy(Policy policy);
-
-  Policy policy() const { return policy_; }
-
   // Set the STUN servers. Must be called before StartGathering
   // (if at all).
   nsresult SetStunServers(const std::vector<NrIceStunServer>& stun_servers);
 
   // Set the TURN servers. Must be called before StartGathering
   // (if at all).
   nsresult SetTurnServers(const std::vector<NrIceTurnServer>& turn_servers);
 
@@ -334,17 +348,17 @@ class NrIceCtx {
       SignalConnectionStateChange;
 
   // The thread to direct method calls to
   nsCOMPtr<nsIEventTarget> thread() { return sts_target_; }
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceCtx)
 
  private:
-  NrIceCtx(const std::string& name, Policy policy);
+  NrIceCtx(const std::string& name, const Config& aConfig);
 
   virtual ~NrIceCtx();
 
   DISALLOW_COPY_ASSIGN(NrIceCtx);
 
   // Callbacks for nICEr
   static void gather_cb(NR_SOCKET s, int h, void* arg);  // ICE gather complete
 
@@ -383,17 +397,17 @@ class NrIceCtx {
   bool ice_controlling_set_;
   std::map<std::string, RefPtr<NrIceMediaStream>> streams_;
   nr_ice_ctx* ctx_;
   nr_ice_peer_ctx* peer_;
   nr_ice_handler_vtbl* ice_handler_vtbl_;  // Must be pointer
   nr_ice_handler* ice_handler_;            // Must be pointer
   bool trickle_;
   nsCOMPtr<nsIEventTarget> sts_target_;  // The thread to run on
-  Policy policy_;
+  Config config_;
   RefPtr<TestNat> nat_;
   std::shared_ptr<NrSocketProxyConfig> proxy_config_;
   bool obfuscate_host_addresses_;
   std::map<std::string, std::string> obfuscated_host_addresses_;
 };
 
 }  // namespace mozilla
 #endif
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -169,21 +169,16 @@ class StunTest : public MtransportTest {
     MtransportTest::TearDown();
   }
 };
 
 enum TrickleMode { TRICKLE_NONE, TRICKLE_SIMULATE, TRICKLE_REAL };
 
 enum ConsentStatus { CONSENT_FRESH, CONSENT_STALE, CONSENT_EXPIRED };
 
-const unsigned int ICE_TEST_PEER_OFFERER = (1 << 0);
-const unsigned int ICE_TEST_PEER_ALLOW_LOOPBACK = (1 << 1);
-const unsigned int ICE_TEST_PEER_ENABLED_TCP = (1 << 2);
-const unsigned int ICE_TEST_PEER_ALLOW_LINK_LOCAL = (1 << 3);
-
 typedef std::string (*CandidateFilter)(const std::string& candidate);
 
 std::vector<std::string> split(const std::string& s, char delim) {
   std::vector<std::string> elems;
   std::stringstream ss(s);
   std::string item;
   while (std::getline(ss, item, delim)) {
     elems.push_back(item);
@@ -356,25 +351,20 @@ class SchedulableTrickleCandidate {
   void* timer_handle_;
   MtransportTestUtils* test_utils_;
 
   DISALLOW_COPY_ASSIGN(SchedulableTrickleCandidate);
 };
 
 class IceTestPeer : public sigslot::has_slots<> {
  public:
-  // TODO(ekr@rtfm.com): Convert to flags when NrIceCtx::Create() does.
-  // Bug 1193437.
   IceTestPeer(const std::string& name, MtransportTestUtils* utils, bool offerer,
-              bool allow_loopback = false, bool enable_tcp = true,
-              bool allow_link_local = false,
-              NrIceCtx::Policy ice_policy = NrIceCtx::ICE_POLICY_ALL)
+              const NrIceCtx::Config& config)
       : name_(name),
-        ice_ctx_(NrIceCtx::Create(name, allow_loopback, enable_tcp,
-                                  allow_link_local, ice_policy)),
+        ice_ctx_(NrIceCtx::Create(name, config)),
         offerer_(offerer),
         candidates_(),
         stream_counter_(0),
         shutting_down_(false),
         gathering_complete_(false),
         ready_ct_(0),
         ice_connected_(false),
         ice_failed_(false),
@@ -1416,23 +1406,20 @@ class WebRtcIceGatherTest : public StunT
     }
   }
 
   void TearDown() override {
     peer_ = nullptr;
     StunTest::TearDown();
   }
 
-  void EnsurePeer(const unsigned int flags = ICE_TEST_PEER_OFFERER) {
+  void EnsurePeer() {
     if (!peer_) {
-      peer_ = MakeUnique<IceTestPeer>("P1", test_utils_,
-                                      flags & ICE_TEST_PEER_OFFERER,
-                                      flags & ICE_TEST_PEER_ALLOW_LOOPBACK,
-                                      flags & ICE_TEST_PEER_ENABLED_TCP,
-                                      flags & ICE_TEST_PEER_ALLOW_LINK_LOCAL);
+      peer_ =
+          MakeUnique<IceTestPeer>("P1", test_utils_, true, NrIceCtx::Config());
       peer_->AddStream(1);
     }
   }
 
   void Gather(unsigned int waitTime = kDefaultTimeout) {
     EnsurePeer();
     peer_->Gather();
 
@@ -1488,27 +1475,27 @@ class WebRtcIceGatherTest : public StunT
     std::vector<NrIceStunServer> stun_servers;
     AddStunServerWithResponse(fake_addr, fake_port, fqdn, "udp", &stun_servers);
     peer_->SetStunServers(stun_servers);
   }
 
   void UseFakeStunTcpServerWithResponse(
       const std::string& fake_addr, uint16_t fake_port,
       const std::string& fqdn = std::string()) {
-    EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
+    EnsurePeer();
     std::vector<NrIceStunServer> stun_servers;
     AddStunServerWithResponse(fake_addr, fake_port, fqdn, "tcp", &stun_servers);
     peer_->SetStunServers(stun_servers);
   }
 
   void UseFakeStunUdpTcpServersWithResponse(const std::string& fake_udp_addr,
                                             uint16_t fake_udp_port,
                                             const std::string& fake_tcp_addr,
                                             uint16_t fake_tcp_port) {
-    EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
+    EnsurePeer();
     std::vector<NrIceStunServer> stun_servers;
     AddStunServerWithResponse(fake_udp_addr, fake_udp_port,
                               "",  // no fqdn
                               "udp", &stun_servers);
     AddStunServerWithResponse(fake_tcp_addr, fake_tcp_port,
                               "",  // no fqdn
                               "tcp", &stun_servers);
 
@@ -1572,37 +1559,37 @@ class WebRtcIceConnectTest : public Stun
   void TearDown() override {
     p1_ = nullptr;
     p2_ = nullptr;
 
     StunTest::TearDown();
   }
 
   void AddStream(int components) {
-    Init(false, false);
+    Init();
     p1_->AddStream(components);
     p2_->AddStream(components);
   }
 
   void RemoveStream(size_t index) {
     p1_->RemoveStream(index);
     p2_->RemoveStream(index);
   }
 
-  void Init(bool allow_loopback, bool enable_tcp,
-            bool setup_stun_servers = true,
+  void Init(bool setup_stun_servers = true,
             NrIceCtx::Policy ice_policy = NrIceCtx::ICE_POLICY_ALL) {
     if (initted_) {
       return;
     }
 
-    p1_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, allow_loopback,
-                                  enable_tcp, false, ice_policy);
-    p2_ = MakeUnique<IceTestPeer>("P2", test_utils_, false, allow_loopback,
-                                  enable_tcp, false, ice_policy);
+    NrIceCtx::Config config;
+    config.mPolicy = ice_policy;
+
+    p1_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, config);
+    p2_ = MakeUnique<IceTestPeer>("P2", test_utils_, false, config);
     InitPeer(p1_.get(), setup_stun_servers);
     InitPeer(p2_.get(), setup_stun_servers);
 
     initted_ = true;
   }
 
   void InitPeer(IceTestPeer* peer, bool setup_stun_servers = true) {
     if (use_nat_) {
@@ -1627,17 +1614,17 @@ class WebRtcIceConnectTest : public Stun
           stun_server_address_, kDefaultStunServerPort, kNrIceTransportTcp));
 
       peer->SetStunServers(stun_servers);
     }
   }
 
   bool Gather(unsigned int waitTime = kDefaultTimeout,
               bool default_route_only = false) {
-    Init(false, false);
+    Init();
 
     return GatherCallerAndCallee(p1_.get(), p2_.get(), waitTime,
                                  default_route_only);
   }
 
   bool GatherCallerAndCallee(IceTestPeer* caller, IceTestPeer* callee,
                              unsigned int waitTime = kDefaultTimeout,
                              bool default_route_only = false) {
@@ -1936,18 +1923,20 @@ class WebRtcIcePrioritizerTest : public 
 
 class WebRtcIcePacketFilterTest : public StunTest {
  public:
   WebRtcIcePacketFilterTest() : udp_filter_(nullptr), tcp_filter_(nullptr) {}
 
   void SetUp() {
     StunTest::SetUp();
 
+    NrIceCtx::InitializeGlobals(NrIceCtx::GlobalConfig());
+
     // Set up enough of the ICE ctx to allow the packet filter to work
-    ice_ctx_ = NrIceCtx::Create("test", true);
+    ice_ctx_ = NrIceCtx::Create("test", NrIceCtx::Config());
 
     nsCOMPtr<nsISocketFilterHandler> udp_handler =
         do_GetService(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID);
     ASSERT_TRUE(udp_handler);
     udp_handler->NewFilter(getter_AddRefs(udp_filter_));
 
     nsCOMPtr<nsISocketFilterHandler> tcp_handler =
         do_GetService(NS_STUN_TCP_SOCKET_FILTER_HANDLER_CONTRACTID);
@@ -2048,121 +2037,155 @@ class WebRtcIcePacketFilterTest : public
 };
 }  // end namespace
 
 TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
   if (stun_server_hostname_.empty()) {
     return;
   }
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
   Gather();
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerTcpHostnameNoResolver) {
   if (stun_server_hostname_.empty()) {
     return;
   }
 
-  EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  EnsurePeer();
   peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort,
                        kNrIceTransportTcp);
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerIpAddress) {
   if (stun_server_address_.empty()) {
     return;
   }
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
   peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
   Gather();
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherStunServerIpAddressNoHost) {
   if (stun_server_address_.empty()) {
     return;
   }
 
-  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false, false,
-                                  NrIceCtx::ICE_POLICY_NO_HOST);
+  {
+    NrIceCtx::GlobalConfig config;
+    config.mTcpEnabled = false;
+    NrIceCtx::InitializeGlobals(config);
+  }
+
+  NrIceCtx::Config config;
+  config.mPolicy = NrIceCtx::ICE_POLICY_NO_HOST;
+  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, config);
   peer_->AddStream(1);
   peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
   peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
   Gather();
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " host "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerHostname) {
   if (stun_server_hostname_.empty()) {
     return;
   }
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
   peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
   Gather();
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherFakeStunBogusHostname) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort);
   peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
   Gather();
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddress) {
   if (stun_server_address_.empty()) {
     return;
   }
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddressTcp) {
   if (stun_server_address_.empty()) {
     return;
   }
 
-  EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  EnsurePeer();
   peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort,
                        kNrIceTransportTcp);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype passive"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype passive", " 9 "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype so"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype so", " 9 "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype active", " 9 "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostname) {
   if (stun_server_hostname_.empty()) {
     return;
   }
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostnameTcp) {
-  EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  EnsurePeer();
   peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort,
                        kNrIceTransportTcp);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype passive"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype passive", " 9 "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype so"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype so", " 9 "));
@@ -2171,17 +2194,20 @@ TEST_F(WebRtcIceGatherTest, TestGatherDN
 
 TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostnameBothUdpTcp) {
   if (stun_server_hostname_.empty()) {
     return;
   }
 
   std::vector<NrIceStunServer> stun_servers;
 
-  EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  EnsurePeer();
   stun_servers.push_back(*NrIceStunServer::Create(
       stun_server_hostname_, kDefaultStunServerPort, kNrIceTransportUdp));
   stun_servers.push_back(*NrIceStunServer::Create(
       stun_server_hostname_, kDefaultStunServerPort, kNrIceTransportTcp));
   peer_->SetStunServers(stun_servers);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
@@ -2190,308 +2216,412 @@ TEST_F(WebRtcIceGatherTest, TestGatherDN
 
 TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddressBothUdpTcp) {
   if (stun_server_address_.empty()) {
     return;
   }
 
   std::vector<NrIceStunServer> stun_servers;
 
-  EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  EnsurePeer();
   stun_servers.push_back(*NrIceStunServer::Create(
       stun_server_address_, kDefaultStunServerPort, kNrIceTransportUdp));
   stun_servers.push_back(*NrIceStunServer::Create(
       stun_server_address_, kDefaultStunServerPort, kNrIceTransportTcp));
   peer_->SetStunServers(stun_servers);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherDNSStunBogusHostname) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherDNSStunBogusHostnameTcp) {
-  EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  EnsurePeer();
   peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort,
                        kNrIceTransportTcp);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestDefaultCandidate) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
   Gather();
   NrIceCandidate default_candidate;
   ASSERT_TRUE(NS_SUCCEEDED(peer_->GetDefaultCandidate(0, &default_candidate)));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherTurn) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   if (turn_server_.empty()) return;
   peer_->SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                        turn_password_, kNrIceTransportUdp);
   Gather();
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherTurnTcp) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   if (turn_server_.empty()) return;
   peer_->SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                        turn_password_, kNrIceTransportTcp);
   Gather();
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherDisableComponent) {
   if (stun_server_hostname_.empty()) {
     return;
   }
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
   peer_->AddStream(2);
   peer_->DisableComponent(1, 2);
   Gather();
   std::vector<std::string> attributes = peer_->GetAttributes(1);
 
   for (auto& attribute : attributes) {
     if (attribute.find("candidate:") != std::string::npos) {
       size_t sp1 = attribute.find(' ');
       ASSERT_EQ(0, attribute.compare(sp1 + 1, 1, "1", 1));
     }
   }
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherVerifyNoLoopback) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   Gather();
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "127.0.0.1"));
 }
 
 TEST_F(WebRtcIceGatherTest, TestGatherAllowLoopback) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  config.mAllowLoopback = true;
+  NrIceCtx::InitializeGlobals(config);
+
   // Set up peer with loopback allowed.
-  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, true);
+  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, NrIceCtx::Config());
   peer_->AddStream(1);
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "127.0.0.1"));
 }
 
-TEST_F(WebRtcIceGatherTest, TestGatherTcpDisabled) {
-  // Set up peer with tcp disabled.
-  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false);
-  peer_->AddStream(1);
+TEST_F(WebRtcIceGatherTest, TestGatherTcpDisabledNoStun) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
+  EnsurePeer();
   Gather();
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " TCP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
 }
 
 TEST_F(WebRtcIceGatherTest, VerifyTestStunServer) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("192.0.2.133", 3333);
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.133 3333 "));
 }
 
 TEST_F(WebRtcIceGatherTest, VerifyTestStunTcpServer) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunTcpServerWithResponse("192.0.2.233", 3333);
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.233 3333 typ srflx",
                                          " tcptype "));
 }
 
 TEST_F(WebRtcIceGatherTest, VerifyTestStunServerV6) {
   if (!TestStunServer::GetInstance(AF_INET6)) {
     // No V6 addresses
     return;
   }
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("beef::", 3333);
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " beef:: 3333 "));
 }
 
 TEST_F(WebRtcIceGatherTest, VerifyTestStunServerFQDN) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("192.0.2.133", 3333, "stun.example.com");
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.133 3333 "));
 }
 
 TEST_F(WebRtcIceGatherTest, VerifyTestStunServerV6FQDN) {
   if (!TestStunServer::GetInstance(AF_INET6)) {
     // No V6 addresses
     return;
   }
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("beef::", 3333, "stun.example.com");
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " beef:: 3333 "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestStunServerReturnsWildcardAddr) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("0.0.0.0", 3333);
   Gather(kDefaultTimeout * 3);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " 0.0.0.0 "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestStunServerReturnsWildcardAddrV6) {
   if (!TestStunServer::GetInstance(AF_INET6)) {
     // No V6 addresses
     return;
   }
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("::", 3333);
   Gather(kDefaultTimeout * 3);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " :: "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestStunServerReturnsPort0) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("192.0.2.133", 0);
   Gather(kDefaultTimeout * 3);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.2.133 0 "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestStunServerReturnsLoopbackAddr) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("127.0.0.133", 3333);
   Gather(kDefaultTimeout * 3);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " 127.0.0.133 "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestStunServerReturnsLoopbackAddrV6) {
   if (!TestStunServer::GetInstance(AF_INET6)) {
     // No V6 addresses
     return;
   }
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("::1", 3333);
   Gather(kDefaultTimeout * 3);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " ::1 "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestStunServerTrickle) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
   TestStunServer::GetInstance(AF_INET)->SetDropInitialPackets(3);
   Gather(0);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "192.0.2.1"));
   WaitForGather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "192.0.2.1"));
 }
 
 // Test no host with our fake STUN server and apparently NATted.
 TEST_F(WebRtcIceGatherTest, TestFakeStunServerNatedNoHost) {
-  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false, false,
-                                  NrIceCtx::ICE_POLICY_NO_HOST);
+  {
+    NrIceCtx::GlobalConfig config;
+    config.mTcpEnabled = false;
+    NrIceCtx::InitializeGlobals(config);
+  }
+
+  NrIceCtx::Config config;
+  config.mPolicy = NrIceCtx::ICE_POLICY_NO_HOST;
+  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, config);
   peer_->AddStream(1);
   UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
   Gather(0);
   WaitForGather();
   DumpAttributes(0);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "host"));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
   NrIceCandidate default_candidate;
   nsresult rv = peer_->GetDefaultCandidate(0, &default_candidate);
   if (NS_SUCCEEDED(rv)) {
     ASSERT_NE(NrIceCandidate::ICE_HOST, default_candidate.type);
   }
 }
 
 // Test no host with our fake STUN server and apparently non-NATted.
 TEST_F(WebRtcIceGatherTest, TestFakeStunServerNoNatNoHost) {
-  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false, false,
-                                  NrIceCtx::ICE_POLICY_NO_HOST);
+  {
+    NrIceCtx::GlobalConfig config;
+    config.mTcpEnabled = false;
+    NrIceCtx::InitializeGlobals(config);
+  }
+
+  NrIceCtx::Config config;
+  config.mPolicy = NrIceCtx::ICE_POLICY_NO_HOST;
+  peer_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, config);
   peer_->AddStream(1);
   UseTestStunServer();
   Gather(0);
   WaitForGather();
   DumpAttributes(0);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "host"));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
 }
 
 TEST_F(WebRtcIceGatherTest, TestStunTcpServerTrickle) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunTcpServerWithResponse("192.0.3.1", 3333);
   TestStunTcpServer::GetInstance(AF_INET)->SetDelay(500);
   Gather(0);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
   WaitForGather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestStunTcpAndUdpServerTrickle) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
   UseFakeStunUdpTcpServersWithResponse("192.0.2.1", 3333, "192.0.3.1", 3333);
   TestStunServer::GetInstance(AF_INET)->SetDropInitialPackets(3);
   TestStunTcpServer::GetInstance(AF_INET)->SetDelay(500);
   Gather(0);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "192.0.2.1", "UDP"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
   WaitForGather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "192.0.2.1", "UDP"));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
 }
 
 TEST_F(WebRtcIceGatherTest, TestSetIceControlling) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   NrIceCtx::Controlling controlling = peer_->GetControlling();
   ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, controlling);
   // SetControlling should only allow setting this once
   peer_->SetControlling(NrIceCtx::ICE_CONTROLLED);
   controlling = peer_->GetControlling();
   ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, controlling);
 }
 
 TEST_F(WebRtcIceGatherTest, TestSetIceControlled) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   EnsurePeer();
   peer_->SetControlling(NrIceCtx::ICE_CONTROLLED);
   NrIceCtx::Controlling controlling = peer_->GetControlling();
   ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, controlling);
   // SetControlling should only allow setting this once
   peer_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   controlling = peer_->GetControlling();
   ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, controlling);
 }
 
 TEST_F(WebRtcIceConnectTest, TestGather) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(WebRtcIceConnectTest, TestGatherTcp) {
-  Init(false, true);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  Init();
   AddStream(1);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(WebRtcIceConnectTest, TestGatherAutoPrioritize) {
-  Init(false, false);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
+  Init();
   AddStream(1);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnect) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectRestartIce) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   Connect();
   SendReceive(p1_.get(), p2_.get());
 
   p2_->RestartIce();
   ASSERT_FALSE(p2_->gathering_complete());
 
   // verify p1 and p2 streams are still connected after restarting ice on p2
   SendReceive(p1_.get(), p2_.get());
 
   mozilla::UniquePtr<IceTestPeer> p3_;
-  p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, false, false, false);
+  p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, NrIceCtx::Config());
   InitPeer(p3_.get());
   p3_->AddStream(1);
 
   ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
   std::cout << "-------------------------------------------------" << std::endl;
   ConnectCallerAndCallee(p3_.get(), p2_.get(), TRICKLE_SIMULATE);
   SendReceive(p1_.get(), p2_.get());  // p1 and p2 are still connected
   SendReceive(p3_.get(), p2_.get(), true, true);  // p3 and p2 not yet connected
@@ -2499,41 +2629,47 @@ TEST_F(WebRtcIceConnectTest, TestConnect
   p3_->SimulateTrickle(0);
   SendReceive(p1_.get(), p2_.get(), false, true);  // p1 and p2 not connected
   SendReceive(p3_.get(), p2_.get());  // p3 and p2 are now connected
 
   p3_ = nullptr;
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectRestartIceThenAbort) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   Connect();
   SendReceive(p1_.get(), p2_.get());
 
   p2_->RestartIce();
   ASSERT_FALSE(p2_->gathering_complete());
 
   // verify p1 and p2 streams are still connected after restarting ice on p2
   SendReceive(p1_.get(), p2_.get());
 
   mozilla::UniquePtr<IceTestPeer> p3_;
-  p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, false, false, false);
+  p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, NrIceCtx::Config());
   InitPeer(p3_.get());
   p3_->AddStream(1);
 
   ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
   std::cout << "-------------------------------------------------" << std::endl;
   p2_->RollbackIceRestart();
   p2_->Connect(p1_.get(), TRICKLE_NONE);
   SendReceive(p1_.get(), p2_.get());
   p3_ = nullptr;
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectIceRestartRoleConflict) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   // Just for fun lets do this with switched rolls
   p1_->SetControlling(NrIceCtx::ICE_CONTROLLED);
   p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   Connect();
   SendReceive(p1_.get(), p2_.get());
   // Set rolls should not switch by connecting
@@ -2542,17 +2678,17 @@ TEST_F(WebRtcIceConnectTest, TestConnect
 
   p2_->RestartIce();
   ASSERT_FALSE(p2_->gathering_complete());
   p2_->SetControlling(NrIceCtx::ICE_CONTROLLED);
   ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p2_->GetControlling())
       << "ICE restart should not allow role to change, unless ice-lite happens";
 
   mozilla::UniquePtr<IceTestPeer> p3_;
-  p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, false, false, false);
+  p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, NrIceCtx::Config());
   InitPeer(p3_.get());
   p3_->AddStream(1);
   // Set control role for p3 accordingly (with role conflict)
   p3_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p3_->GetControlling());
 
   ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
   std::cout << "-------------------------------------------------" << std::endl;
@@ -2581,16 +2717,19 @@ TEST_F(WebRtcIceConnectTest,
   wifi_addr.interface.type = NR_INTERFACE_TYPE_WIFI;
   wifi_addr.interface.estimated_speed = 1000;
 
   int r = nr_str_port_to_transport_addr(FAKE_WIFI_ADDR, 0, IPPROTO_UDP,
                                         &(wifi_addr.addr));
   ASSERT_EQ(0, r);
   strncpy(wifi_addr.addr.ifname, FAKE_WIFI_IF_NAME, MAXIFNAME);
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   // setup initial ICE connection between p1_ and p2_
   UseNat();
   AddStream(1);
   SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
                    NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
   ASSERT_TRUE(Gather(kDefaultTimeout, true));
   Connect();
 
@@ -2612,250 +2751,324 @@ TEST_F(WebRtcIceConnectTest,
   ASSERT_FALSE(p2_->gathering_complete());
 
   // verify that we can successfully gather candidates
   p2_->Gather();
   EXPECT_TRUE_WAIT(p2_->gathering_complete(), kDefaultTimeout);
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTcp) {
-  Init(false, true);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  Init();
   AddStream(1);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsTcpCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
                    NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
   Connect();
 }
 
 // TCP SO tests works on localhost only with delay applied:
 //  tc qdisc add dev lo root netem delay 10ms
 TEST_F(WebRtcIceConnectTest, DISABLED_TestConnectTcpSo) {
-  Init(false, true);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  Init();
   AddStream(1);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsTcpSoCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
                    NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
   Connect();
 }
 
 // Disabled because this breaks with hairpinning.
 TEST_F(WebRtcIceConnectTest, DISABLED_TestConnectNoHost) {
-  Init(false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
+  Init(false, NrIceCtx::ICE_POLICY_NO_HOST);
   AddStream(1);
   ASSERT_TRUE(Gather());
   SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
                    NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
                    kNrIceTransportTcp);
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestLoopbackOnlySortOf) {
-  Init(true, false, false);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  config.mAllowLoopback = true;
+  NrIceCtx::InitializeGlobals(config);
+  Init(false);
   AddStream(1);
   SetCandidateFilter(IsLoopbackCandidate);
   ASSERT_TRUE(Gather());
   SetExpectedRemoteCandidateAddr("127.0.0.1");
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectBothControllingP1Wins) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   p1_->SetTiebreaker(1);
   p2_->SetTiebreaker(0);
   ASSERT_TRUE(Gather());
   p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectBothControllingP2Wins) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   p1_->SetTiebreaker(0);
   p2_->SetTiebreaker(1);
   ASSERT_TRUE(Gather());
   p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectIceLiteOfferer) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   p1_->SimulateIceLite();
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestTrickleBothControllingP1Wins) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   p1_->SetTiebreaker(1);
   p2_->SetTiebreaker(0);
   ASSERT_TRUE(Gather());
   p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   ConnectTrickle();
   SimulateTrickle(0);
   WaitForConnected(1000);
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestTrickleBothControllingP2Wins) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   p1_->SetTiebreaker(0);
   p2_->SetTiebreaker(1);
   ASSERT_TRUE(Gather());
   p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
   ConnectTrickle();
   SimulateTrickle(0);
   WaitForConnected(1000);
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestTrickleIceLiteOfferer) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   p1_->SimulateIceLite();
   ConnectTrickle();
   SimulateTrickle(0);
   WaitForConnected(1000);
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestGatherFullCone) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   AddStream(1);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(WebRtcIceConnectTest, TestGatherFullConeAutoPrioritize) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
-  Init(true, false);
+  Init();
   AddStream(1);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectFullCone) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   AddStream(1);
   SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
                    NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectNoNatNoHost) {
-  Init(false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
+  Init(false, NrIceCtx::ICE_POLICY_NO_HOST);
   AddStream(1);
   UseTestStunServer();
   // Because we are connecting from our host candidate to the
   // other side's apparent srflx (which is also their host)
   // we see a host/srflx pair.
   SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
                    NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectFullConeNoHost) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
-  Init(false, false, false, NrIceCtx::ICE_POLICY_NO_HOST);
+  Init(false, NrIceCtx::ICE_POLICY_NO_HOST);
   AddStream(1);
   UseTestStunServer();
   SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
                    NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestGatherAddressRestrictedCone) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   SetFilteringType(TestNat::ADDRESS_DEPENDENT);
   SetMappingType(TestNat::ENDPOINT_INDEPENDENT);
   AddStream(1);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectAddressRestrictedCone) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   SetFilteringType(TestNat::ADDRESS_DEPENDENT);
   SetMappingType(TestNat::ENDPOINT_INDEPENDENT);
   AddStream(1);
   SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
                    NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestGatherPortRestrictedCone) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   SetFilteringType(TestNat::PORT_DEPENDENT);
   SetMappingType(TestNat::ENDPOINT_INDEPENDENT);
   AddStream(1);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectPortRestrictedCone) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   SetFilteringType(TestNat::PORT_DEPENDENT);
   SetMappingType(TestNat::ENDPOINT_INDEPENDENT);
   AddStream(1);
   SetExpectedTypes(NrIceCandidate::Type::ICE_SERVER_REFLEXIVE,
                    NrIceCandidate::Type::ICE_SERVER_REFLEXIVE);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestGatherSymmetricNat) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   SetFilteringType(TestNat::PORT_DEPENDENT);
   SetMappingType(TestNat::PORT_DEPENDENT);
   AddStream(1);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectSymmetricNat) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   SetFilteringType(TestNat::PORT_DEPENDENT);
   SetMappingType(TestNat::PORT_DEPENDENT);
   AddStream(1);
   p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                         NrIceCandidate::Type::ICE_RELAYED);
   p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                         NrIceCandidate::Type::ICE_RELAYED);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectSymmetricNatAndNoNat) {
-  p1_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, false, false);
+  {
+    NrIceCtx::GlobalConfig config;
+    config.mTcpEnabled = true;
+    NrIceCtx::InitializeGlobals(config);
+  }
+
+  NrIceCtx::Config config;
+  p1_ = MakeUnique<IceTestPeer>("P1", test_utils_, true, config);
   p1_->UseNat();
   p1_->SetFilteringType(TestNat::PORT_DEPENDENT);
   p1_->SetMappingType(TestNat::PORT_DEPENDENT);
 
-  p2_ = MakeUnique<IceTestPeer>("P2", test_utils_, false, false, false);
+  p2_ = MakeUnique<IceTestPeer>("P2", test_utils_, false, config);
   initted_ = true;
 
   AddStream(1);
   p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_PEER_REFLEXIVE,
                         NrIceCandidate::Type::ICE_HOST);
   p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
                         NrIceCandidate::Type::ICE_PEER_REFLEXIVE);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestGatherNatBlocksUDP) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   BlockUdp();
   AddStream(1);
   std::vector<NrIceTurnServer> turn_servers;
   std::vector<unsigned char> password_vec(turn_password_.begin(),
                                           turn_password_.end());
   turn_servers.push_back(
       *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort, turn_user_,
@@ -2866,16 +3079,19 @@ TEST_F(WebRtcIceConnectTest, TestGatherN
   SetTurnServers(turn_servers);
   // We have to wait for the UDP-based stuff to time out.
   ASSERT_TRUE(Gather(kDefaultTimeout * 3));
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectNatBlocksUDP) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   UseNat();
   BlockUdp();
   AddStream(1);
   std::vector<NrIceTurnServer> turn_servers;
   std::vector<unsigned char> password_vec(turn_password_.begin(),
                                           turn_password_.end());
   turn_servers.push_back(
       *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort, turn_user_,
@@ -2888,80 +3104,104 @@ TEST_F(WebRtcIceConnectTest, TestConnect
                         NrIceCandidate::Type::ICE_RELAYED, kNrIceTransportTcp);
   p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                         NrIceCandidate::Type::ICE_RELAYED, kNrIceTransportTcp);
   ASSERT_TRUE(Gather(kDefaultTimeout * 3));
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTwoComponents) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(2);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTwoComponentsDisableSecond) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(2);
   ASSERT_TRUE(Gather());
   p1_->DisableComponent(0, 2);
   p2_->DisableComponent(0, 2);
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectP2();
   PR_Sleep(1000);
   ConnectP1();
   WaitForConnectedStreams();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1Trickle) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectP2();
   PR_Sleep(1000);
   ConnectP1(TRICKLE_SIMULATE);
   SimulateTrickleP1(0);
   WaitForConnectedStreams();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectP2ThenP1TrickleTwoComponents) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   AddStream(2);
   ASSERT_TRUE(Gather());
   ConnectP2();
   PR_Sleep(1000);
   ConnectP1(TRICKLE_SIMULATE);
   SimulateTrickleP1(0);
   std::cerr << "Sleeping between trickle streams" << std::endl;
   PR_Sleep(1000);  // Give this some time to settle but not complete
                    // all of ICE.
   SimulateTrickleP1(1);
   WaitForConnectedStreams(2);
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectAutoPrioritize) {
-  Init(false, false);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
+  Init();
   AddStream(1);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTrickleOneStreamOneComponent) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   SimulateTrickle(0);
   WaitForConnected(1000);
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTrickleTwoStreamsOneComponent) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   SimulateTrickle(0);
   SimulateTrickle(1);
   WaitForConnected(1000);
   AssertCheckingReached();
@@ -3033,79 +3273,97 @@ void AddNonPairableCandidates(
     (*i)->Schedule(0);
   }
 }
 
 void DropTrickleCandidates(
     std::vector<SchedulableTrickleCandidate*>& candidates) {}
 
 TEST_F(WebRtcIceConnectTest, TestConnectTrickleAddStreamDuringICE) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   RealisticTrickleDelay(p2_->ControlTrickle(0));
   AddStream(1);
   RealisticTrickleDelay(p1_->ControlTrickle(1));
   RealisticTrickleDelay(p2_->ControlTrickle(1));
   WaitForConnected(1000);
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTrickleAddStreamAfterICE) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   RealisticTrickleDelay(p2_->ControlTrickle(0));
   WaitForConnected(1000);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(1));
   RealisticTrickleDelay(p2_->ControlTrickle(1));
   WaitForConnected(1000);
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, RemoveStream) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   RealisticTrickleDelay(p2_->ControlTrickle(0));
   RealisticTrickleDelay(p1_->ControlTrickle(1));
   RealisticTrickleDelay(p2_->ControlTrickle(1));
   WaitForConnected(1000);
 
   RemoveStream(0);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
 }
 
 TEST_F(WebRtcIceConnectTest, P1NoTrickle) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   DropTrickleCandidates(p1_->ControlTrickle(0));
   RealisticTrickleDelay(p2_->ControlTrickle(0));
   WaitForConnected(1000);
 }
 
 TEST_F(WebRtcIceConnectTest, P2NoTrickle) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   DropTrickleCandidates(p2_->ControlTrickle(0));
   WaitForConnected(1000);
 }
 
 TEST_F(WebRtcIceConnectTest, RemoveAndAddStream) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   RealisticTrickleDelay(p2_->ControlTrickle(0));
   RealisticTrickleDelay(p1_->ControlTrickle(1));
   RealisticTrickleDelay(p2_->ControlTrickle(1));
@@ -3116,113 +3374,143 @@ TEST_F(WebRtcIceConnectTest, RemoveAndAd
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(2));
   RealisticTrickleDelay(p2_->ControlTrickle(2));
   WaitForConnected(1000);
 }
 
 TEST_F(WebRtcIceConnectTest, RemoveStreamBeforeGather) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   AddStream(1);
   ASSERT_TRUE(Gather(0));
   RemoveStream(0);
   WaitForGather();
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(1));
   RealisticTrickleDelay(p2_->ControlTrickle(1));
   WaitForConnected(1000);
 }
 
 TEST_F(WebRtcIceConnectTest, RemoveStreamDuringGather) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   AddStream(1);
   RemoveStream(0);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(1));
   RealisticTrickleDelay(p2_->ControlTrickle(1));
   WaitForConnected(1000);
 }
 
 TEST_F(WebRtcIceConnectTest, RemoveStreamDuringConnect) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   RealisticTrickleDelay(p2_->ControlTrickle(0));
   RealisticTrickleDelay(p1_->ControlTrickle(1));
   RealisticTrickleDelay(p2_->ControlTrickle(1));
   RemoveStream(0);
   WaitForConnected(1000);
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectRealTrickleOneStreamOneComponent) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   AddStream(1);
   ASSERT_TRUE(Gather(0));
   ConnectTrickle(TRICKLE_REAL);
   WaitForConnected();
   WaitForGather();  // ICE can complete before we finish gathering.
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestSendReceive) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   Connect();
   SendReceive();
 }
 
 TEST_F(WebRtcIceConnectTest, TestSendReceiveTcp) {
-  Init(false, true);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  Init();
   AddStream(1);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsTcpCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
                    NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
   Connect();
   SendReceive();
 }
 
 // TCP SO tests works on localhost only with delay applied:
 //  tc qdisc add dev lo root netem delay 10ms
 TEST_F(WebRtcIceConnectTest, DISABLED_TestSendReceiveTcpSo) {
-  Init(false, true);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  Init();
   AddStream(1);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsTcpSoCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
                    NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
   Connect();
   SendReceive();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConsent) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetupAndCheckConsent();
   PR_Sleep(1500);
   AssertConsentRefresh();
   SendReceive();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConsentTcp) {
-  Init(false, true);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = true;
+  NrIceCtx::InitializeGlobals(config);
+  Init();
   AddStream(1);
   SetCandidateFilter(IsTcpCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
                    NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
   SetupAndCheckConsent();
   PR_Sleep(1500);
   AssertConsentRefresh();
   SendReceive();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConsentIntermittent) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetupAndCheckConsent();
   p1_->SetBlockStun(true);
   p2_->SetBlockStun(true);
   WaitForDisconnected();
   AssertConsentRefresh(CONSENT_STALE);
   SendReceive();
   p1_->SetBlockStun(false);
@@ -3237,70 +3525,88 @@ TEST_F(WebRtcIceConnectTest, TestConsent
   SendReceive();
   p1_->SetBlockStun(false);
   p2_->SetBlockStun(false);
   WaitForConnected();
   AssertConsentRefresh();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConsentTimeout) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetupAndCheckConsent();
   p1_->SetBlockStun(true);
   p2_->SetBlockStun(true);
   WaitForDisconnected();
   AssertConsentRefresh(CONSENT_STALE);
   SendReceive();
   WaitForFailed();
   AssertConsentRefresh(CONSENT_EXPIRED);
   SendFailure();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConsentDelayed) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetupAndCheckConsent();
   /* Note: We don't have a list of STUN transaction IDs of the previously timed
            out consent requests. Thus responses after sending the next consent
            request are ignored. */
   p1_->SetStunResponseDelay(200);
   p2_->SetStunResponseDelay(200);
   PR_Sleep(1000);
   AssertConsentRefresh();
   SendReceive();
 }
 
 TEST_F(WebRtcIceConnectTest, TestNetworkForcedOfflineAndRecovery) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetupAndCheckConsent();
   p1_->ChangeNetworkStateToOffline();
   ASSERT_TRUE_WAIT(p1_->ice_connected() == 0, kDefaultTimeout);
   // Next round of consent check should switch it back to online
   ASSERT_TRUE_WAIT(p1_->ice_connected(), kDefaultTimeout);
 }
 
 TEST_F(WebRtcIceConnectTest, TestNetworkForcedOfflineTwice) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetupAndCheckConsent();
   p2_->ChangeNetworkStateToOffline();
   ASSERT_TRUE_WAIT(p2_->ice_connected() == 0, kDefaultTimeout);
   p2_->ChangeNetworkStateToOffline();
   ASSERT_TRUE_WAIT(p2_->ice_connected() == 0, kDefaultTimeout);
 }
 
 TEST_F(WebRtcIceConnectTest, TestNetworkOnlineDoesntChangeState) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetupAndCheckConsent();
   p2_->ChangeNetworkStateToOnline();
   ASSERT_TRUE(p2_->ice_connected());
   PR_Sleep(1500);
   p2_->ChangeNetworkStateToOnline();
   ASSERT_TRUE(p2_->ice_connected());
 }
 
 TEST_F(WebRtcIceConnectTest, TestNetworkOnlineTriggersConsent) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   // Let's emulate audio + video w/o rtcp-mux
   AddStream(2);
   AddStream(2);
   SetupAndCheckConsent();
   p1_->ChangeNetworkStateToOffline();
   p1_->SetBlockStun(true);
   ASSERT_TRUE_WAIT(p1_->ice_connected() == 0, kDefaultTimeout);
   PR_Sleep(1500);
@@ -3308,71 +3614,86 @@ TEST_F(WebRtcIceConnectTest, TestNetwork
   p1_->SetBlockStun(false);
   p1_->ChangeNetworkStateToOnline();
   ASSERT_TRUE_WAIT(p1_->ice_connected(), 500);
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTurn) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTurnWithDelay) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_);
   SetCandidateFilter(SabotageHostCandidateAndDropReflexive);
   p1_->Gather();
   PR_Sleep(500);
   p2_->Gather();
   ConnectTrickle(TRICKLE_REAL);
   WaitForGather();
   WaitForConnectedStreams();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTurnWithNormalTrickleDelay) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   RealisticTrickleDelay(p2_->ControlTrickle(0));
 
   WaitForConnected();
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTurnWithNormalTrickleDelayOneSided) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   p2_->SimulateTrickle(0);
 
   WaitForConnected();
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTurnWithLargeTrickleDelay) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_);
   SetCandidateFilter(SabotageHostCandidateAndDropReflexive);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   // Trickle host candidates immediately, but delay relay candidates
   DelayRelayCandidates(p1_->ControlTrickle(0), 3700);
@@ -3380,80 +3701,98 @@ TEST_F(WebRtcIceConnectTest, TestConnect
 
   WaitForConnected();
   AssertCheckingReached();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTurnTcp) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_, kNrIceTransportTcp);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTurnOnly) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED);
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectTurnTcpOnly) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_, kNrIceTransportTcp);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED, kNrIceTransportTcp);
   Connect();
 }
 
 TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnOnly) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED);
   Connect();
   SendReceive();
 }
 
 TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnTcpOnly) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   SetTurnServer(turn_server_, kDefaultStunServerPort, turn_user_,
                 turn_password_, kNrIceTransportTcp);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED, kNrIceTransportTcp);
   Connect();
   SendReceive();
 }
 
 TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnBothOnly) {
   if (turn_server_.empty()) return;
 
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   std::vector<NrIceTurnServer> turn_servers;
   std::vector<unsigned char> password_vec(turn_password_.begin(),
                                           turn_password_.end());
   turn_servers.push_back(
       *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort, turn_user_,
                                password_vec, kNrIceTransportTcp));
   turn_servers.push_back(
@@ -3465,37 +3804,46 @@ TEST_F(WebRtcIceConnectTest, TestSendRec
   // UDP is preferred.
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED, kNrIceTransportUdp);
   Connect();
   SendReceive();
 }
 
 TEST_F(WebRtcIceConnectTest, TestConnectShutdownOneSide) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   ConnectThenDelete();
 }
 
 TEST_F(WebRtcIceConnectTest, TestPollCandPairsBeforeConnect) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
 
   std::vector<NrIceCandidatePair> pairs;
   nsresult res = p1_->GetCandidatePairs(0, &pairs);
   // There should be no candidate pairs prior to calling Connect()
   ASSERT_EQ(NS_OK, res);
   ASSERT_EQ(0U, pairs.size());
 
   res = p2_->GetCandidatePairs(0, &pairs);
   ASSERT_EQ(NS_OK, res);
   ASSERT_EQ(0U, pairs.size());
 }
 
 TEST_F(WebRtcIceConnectTest, TestPollCandPairsAfterConnect) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
   Connect();
 
   std::vector<NrIceCandidatePair> pairs;
   nsresult r = p1_->GetCandidatePairs(0, &pairs);
   ASSERT_EQ(NS_OK, r);
   // How detailed of a check do we want to do here? If the turn server is
@@ -3511,17 +3859,20 @@ TEST_F(WebRtcIceConnectTest, TestPollCan
   ASSERT_NE(0U, pairs.size());
   ASSERT_TRUE(p2_->CandidatePairsPriorityDescending(pairs));
   ASSERT_TRUE(ContainsSucceededPair(pairs));
 }
 
 // TODO Bug 1259842 - disabled until we find a better way to handle two
 // candidates from different RFC1918 ranges
 TEST_F(WebRtcIceConnectTest, DISABLED_TestHostCandPairingFilter) {
-  Init(false, false, false);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
+  Init(false);
   AddStream(1);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsIpv4Candidate);
 
   int host_net = p1_->GetCandidatesPrivateIpv4Range(0);
   if (host_net <= 0) {
     // TODO bug 1226838: make this work with multiple private IPs
     FAIL() << "This test needs exactly one private IPv4 host candidate to work"
@@ -3550,17 +3901,20 @@ TEST_F(WebRtcIceConnectTest, DISABLED_Te
 }
 
 // TODO Bug 1226838 - See Comment 2 - this test can't work as written
 TEST_F(WebRtcIceConnectTest, DISABLED_TestSrflxCandPairingFilter) {
   if (stun_server_address_.empty()) {
     return;
   }
 
-  Init(false, false, false);
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
+  Init(false);
   AddStream(1);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsSrflxCandidate);
 
   if (p1_->GetCandidatesPrivateIpv4Range(0) <= 0) {
     // TODO bug 1226838: make this work with public IP addresses
     std::cerr << "Don't run this test at IETF meetings!" << std::endl;
     FAIL() << "This test needs one private IPv4 host candidate to work"
@@ -3594,16 +3948,19 @@ TEST_F(WebRtcIceConnectTest, DISABLED_Te
     ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) != 0);
     nr_str_port_to_transport_addr(p.remote.cand_addr.host.c_str(), 0,
                                   IPPROTO_UDP, &addr);
     ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) == 0);
   }
 }
 
 TEST_F(WebRtcIceConnectTest, TestPollCandPairsDuringConnect) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
 
   p2_->Connect(p1_.get(), TRICKLE_NONE, false);
   p1_->Connect(p2_.get(), TRICKLE_NONE, false);
 
   std::vector<NrIceCandidatePair> pairs1;
   std::vector<NrIceCandidatePair> pairs2;
@@ -3619,16 +3976,19 @@ TEST_F(WebRtcIceConnectTest, TestPollCan
   WaitForConnectedStreams();
   p1_->UpdateAndValidateCandidatePairs(0, &pairs1);
   p2_->UpdateAndValidateCandidatePairs(0, &pairs2);
   ASSERT_TRUE(ContainsSucceededPair(pairs1));
   ASSERT_TRUE(ContainsSucceededPair(pairs2));
 }
 
 TEST_F(WebRtcIceConnectTest, TestRLogConnector) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   ASSERT_TRUE(Gather());
 
   p2_->Connect(p1_.get(), TRICKLE_NONE, false);
   p1_->Connect(p2_.get(), TRICKLE_NONE, false);
 
   std::vector<NrIceCandidatePair> pairs1;
   std::vector<NrIceCandidatePair> pairs2;
@@ -3662,41 +4022,50 @@ TEST_F(WebRtcIceConnectTest, TestRLogCon
     RLogConnector::GetInstance()->Filter(substring, 0, &logs);
     ASSERT_NE(0U, logs.size());
   }
 }
 
 // Verify that a bogus candidate doesn't cause crashes on the
 // main thread. See bug 856433.
 TEST_F(WebRtcIceConnectTest, TestBogusCandidate) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   Gather();
   ConnectTrickle();
   p1_->ParseCandidate(0, kBogusIceCandidate, "");
 
   std::vector<NrIceCandidatePair> pairs;
   nsresult res = p1_->GetCandidatePairs(0, &pairs);
   ASSERT_EQ(NS_OK, res);
   ASSERT_EQ(0U, pairs.size());
 }
 
 TEST_F(WebRtcIceConnectTest, TestNonMDNSCandidate) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   Gather();
   ConnectTrickle();
   p1_->ParseCandidate(0, kUnreachableHostIceCandidate, "");
 
   std::vector<NrIceCandidatePair> pairs;
   nsresult res = p1_->GetCandidatePairs(0, &pairs);
   ASSERT_EQ(NS_OK, res);
   ASSERT_EQ(1U, pairs.size());
   ASSERT_EQ(pairs[0].remote.mdns_addr, "");
 }
 
 TEST_F(WebRtcIceConnectTest, TestMDNSCandidate) {
+  NrIceCtx::GlobalConfig config;
+  config.mTcpEnabled = false;
+  NrIceCtx::InitializeGlobals(config);
   AddStream(1);
   Gather();
   ConnectTrickle();
   p1_->ParseCandidate(0, kUnreachableHostIceCandidate, "host.local");
 
   std::vector<NrIceCandidatePair> pairs;
   nsresult res = p1_->GetCandidatePairs(0, &pairs);
   ASSERT_EQ(NS_OK, res);
--- a/media/mtransport/test/multi_tcp_socket_unittest.cpp
+++ b/media/mtransport/test/multi_tcp_socket_unittest.cpp
@@ -38,17 +38,18 @@ namespace {
 class MultiTcpSocketTest : public MtransportTest {
  public:
   MultiTcpSocketTest()
       : MtransportTest(), socks(3, nullptr), readable(false), ice_ctx_() {}
 
   void SetUp() {
     MtransportTest::SetUp();
 
-    ice_ctx_ = NrIceCtx::Create("stun", true);
+    NrIceCtx::InitializeGlobals(NrIceCtx::GlobalConfig());
+    ice_ctx_ = NrIceCtx::Create("stun", NrIceCtx::Config());
 
     test_utils_->sts_target()->Dispatch(
         WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET),
         NS_DISPATCH_SYNC);
     test_utils_->sts_target()->Dispatch(
         WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET6),
         NS_DISPATCH_SYNC);
   }
--- a/media/mtransport/test/test_nr_socket_ice_unittest.cpp
+++ b/media/mtransport/test/test_nr_socket_ice_unittest.cpp
@@ -302,17 +302,17 @@ class TestNrSocketIceUnitTest : public :
  public:
   void SetUp() override {
     NSS_NoDB_Init(nullptr);
     NSS_SetDomesticPolicy();
 
     test_utils_ = new MtransportTestUtils();
     test_utils2_ = new MtransportTestUtils();
 
-    NrIceCtx::InitializeGlobals(false, false, false);
+    NrIceCtx::InitializeGlobals(NrIceCtx::GlobalConfig());
   }
 
   void TearDown() override {
     delete test_utils_;
     delete test_utils2_;
   }
 
   MtransportTestUtils* test_utils_;
--- a/media/mtransport/test/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -437,24 +437,26 @@ class TransportTestPeer : public sigslot
         received_packets_(0),
         received_bytes_(0),
         flow_(new TransportFlow(name)),
         loopback_(new TransportLayerLoopback()),
         logging_(new TransportLayerLogging()),
         lossy_(new TransportLayerLossy()),
         dtls_(new TransportLayerDtls()),
         identity_(DtlsIdentity::Generate()),
-        ice_ctx_(NrIceCtx::Create(name)),
+        ice_ctx_(),
         streams_(),
         peer_(nullptr),
         gathering_complete_(false),
         digest_("sha-1"),
         enabled_cipersuites_(),
         disabled_cipersuites_(),
         test_utils_(utils) {
+    NrIceCtx::InitializeGlobals(NrIceCtx::GlobalConfig());
+    ice_ctx_ = NrIceCtx::Create(name, NrIceCtx::Config());
     std::vector<NrIceStunServer> stun_servers;
     UniquePtr<NrIceStunServer> server(NrIceStunServer::Create(
         std::string((char*)"stun.services.mozilla.com"), 3478));
     stun_servers.push_back(*server);
     EXPECT_TRUE(NS_SUCCEEDED(ice_ctx_->SetStunServers(stun_servers)));
 
     dtls_->SetIdentity(identity_);
     dtls_->SetRole(offerer_ ? TransportLayerDtls::SERVER
--- a/media/mtransport/test/turn_unittest.cpp
+++ b/media/mtransport/test/turn_unittest.cpp
@@ -91,17 +91,17 @@ class TurnClient : public MtransportTest
         turn_ctx_(nullptr),
         allocated_(false),
         received_(0),
         protocol_(IPPROTO_UDP) {}
 
   ~TurnClient() = default;
 
   static void SetUpTestCase() {
-    NrIceCtx::InitializeGlobals(false, false, false);
+    NrIceCtx::InitializeGlobals(NrIceCtx::GlobalConfig());
   }
 
   void SetTcp() { protocol_ = IPPROTO_TCP; }
 
   void Init_s() {
     int r;
     nr_transport_addr addr;
     r = nr_ip4_port_to_transport_addr(0, 0, protocol_, &addr);
--- a/media/webrtc/signaling/src/peerconnection/MediaTransportHandler.cpp
+++ b/media/webrtc/signaling/src/peerconnection/MediaTransportHandler.cpp
@@ -154,18 +154,18 @@ class MediaTransportHandlerSTS : public 
                    dom::RTCStatsCollection* aStats) const;
 
   virtual ~MediaTransportHandlerSTS() = default;
   nsCOMPtr<nsISerialEventTarget> mStsThread;
   RefPtr<NrIceCtx> mIceCtx;
   RefPtr<NrIceResolver> mDNSResolver;
   std::map<std::string, Transport> mTransports;
   bool mObfuscateHostAddresses = false;
-  uint32_t minDtlsVersion = 0;
-  uint32_t maxDtlsVersion = 0;
+  uint32_t mMinDtlsVersion = 0;
+  uint32_t mMaxDtlsVersion = 0;
 
   std::set<std::string> mSignaledAddresses;
 
   // Init can only be done on main, but we want this to be usable on any thread
   typedef MozPromise<bool, std::string, false> InitPromise;
   RefPtr<InitPromise> mInitPromise;
 };
 
@@ -335,16 +335,66 @@ nsresult MediaTransportHandler::ConvertI
         return rv;
       }
     }
   }
 
   return NS_OK;
 }
 
+static NrIceCtx::GlobalConfig GetGlobalConfig() {
+  NrIceCtx::GlobalConfig config;
+  config.mAllowLinkLocal =
+      Preferences::GetBool("media.peerconnection.ice.link_local", false);
+  config.mAllowLoopback =
+      Preferences::GetBool("media.peerconnection.ice.loopback", false);
+  config.mTcpEnabled =
+      Preferences::GetBool("media.peerconnection.ice.tcp", false);
+  config.mStunClientMaxTransmits = Preferences::GetInt(
+      "media.peerconnection.ice.stun_client_maximum_transmits",
+      config.mStunClientMaxTransmits);
+  config.mTrickleIceGracePeriod =
+      Preferences::GetInt("media.peerconnection.ice.trickle_grace_period",
+                          config.mTrickleIceGracePeriod);
+  config.mIceTcpSoSockCount = Preferences::GetInt(
+      "media.peerconnection.ice.tcp_so_sock_count", config.mIceTcpSoSockCount);
+  config.mIceTcpListenBacklog =
+      Preferences::GetInt("media.peerconnection.ice.tcp_listen_backlog",
+                          config.mIceTcpListenBacklog);
+  (void)Preferences::GetCString("media.peerconnection.ice.force_interface",
+                                config.mForceNetInterface);
+  return config;
+}
+
+static Maybe<NrIceCtx::NatSimulatorConfig> GetNatConfig() {
+  bool block_tcp = Preferences::GetBool(
+      "media.peerconnection.nat_simulator.block_tcp", false);
+  bool block_udp = Preferences::GetBool(
+      "media.peerconnection.nat_simulator.block_udp", false);
+  nsAutoCString mapping_type;
+  (void)Preferences::GetCString(
+      "media.peerconnection.nat_simulator.mapping_type", mapping_type);
+  nsAutoCString filtering_type;
+  (void)Preferences::GetCString(
+      "media.peerconnection.nat_simulator.filtering_type", filtering_type);
+
+  if (block_udp || block_tcp || !mapping_type.IsEmpty() ||
+      !filtering_type.IsEmpty()) {
+    CSFLogDebug(LOGTAG, "NAT filtering type: %s", filtering_type.get());
+    CSFLogDebug(LOGTAG, "NAT mapping type: %s", mapping_type.get());
+    NrIceCtx::NatSimulatorConfig natConfig;
+    natConfig.mBlockUdp = block_udp;
+    natConfig.mBlockTcp = block_tcp;
+    natConfig.mFilteringType = filtering_type;
+    natConfig.mMappingType = mapping_type;
+    return Some(natConfig);
+  }
+  return Nothing();
+}
+
 nsresult MediaTransportHandlerSTS::CreateIceCtx(
     const std::string& aName, const nsTArray<dom::RTCIceServer>& aIceServers,
     dom::RTCIceTransportPolicy aIcePolicy) {
   // We rely on getting an error when this happens, so do it up front.
   std::vector<NrIceStunServer> stunServers;
   std::vector<NrIceTurnServer> turnServers;
   nsresult rv = ConvertIceServers(aIceServers, &stunServers, &turnServers);
   if (NS_FAILED(rv)) {
@@ -366,82 +416,90 @@ nsresult MediaTransportHandlerSTS::Creat
             MOZ_CRASH();
             return InitPromise::CreateAndReject("InitializeCipherSuite failed",
                                                 __func__);
           }
 
           mozilla::psm::DisableMD5();
         }
 
-        // This stuff will probably live on the other side of IPC; errors down
-        // here will either need to be ignored, or plumbed back in some way
-        // other than the return.
-        bool allowLoopback =
-            Preferences::GetBool("media.peerconnection.ice.loopback", false);
-        bool tcpEnabled =
-            Preferences::GetBool("media.peerconnection.ice.tcp", false);
-        bool allowLinkLocal =
-            Preferences::GetBool("media.peerconnection.ice.link_local", false);
-
-        mIceCtx = NrIceCtx::Create(aName, allowLoopback, tcpEnabled,
-                                   allowLinkLocal, toNrIcePolicy(aIcePolicy));
-        if (!mIceCtx) {
-          return InitPromise::CreateAndReject("NrIceCtx::Create failed",
-                                              __func__);
+        static bool globalInitDone = false;
+        if (!globalInitDone) {
+          mStsThread->Dispatch(
+              WrapRunnableNM(&NrIceCtx::InitializeGlobals, GetGlobalConfig()),
+              NS_DISPATCH_NORMAL);
+          globalInitDone = true;
         }
 
-        mIceCtx->SignalGatheringStateChange.connect(
-            this, &MediaTransportHandlerSTS::OnGatheringStateChange);
-        mIceCtx->SignalConnectionStateChange.connect(
-            this, &MediaTransportHandlerSTS::OnConnectionStateChange);
-
-        nsresult rv;
-
-        if (NS_FAILED(rv = mIceCtx->SetStunServers(stunServers))) {
-          CSFLogError(LOGTAG, "%s: Failed to set stun servers", __FUNCTION__);
-          return InitPromise::CreateAndReject("Failed to set stun servers",
-                                              __func__);
-        }
         // Give us a way to globally turn off TURN support
-        bool disabled =
+        bool turnDisabled =
             Preferences::GetBool("media.peerconnection.turn.disable", false);
-        if (!disabled) {
-          if (NS_FAILED(rv = mIceCtx->SetTurnServers(turnServers))) {
-            CSFLogError(LOGTAG, "%s: Failed to set turn servers", __FUNCTION__);
-            return InitPromise::CreateAndReject("Failed to set turn servers",
-                                                __func__);
-          }
-        } else if (!turnServers.empty()) {
-          CSFLogError(LOGTAG, "%s: Setting turn servers disabled",
-                      __FUNCTION__);
-        }
-
-        mDNSResolver = new NrIceResolver;
-        if (NS_FAILED(rv = mDNSResolver->Init())) {
-          CSFLogError(LOGTAG, "%s: Failed to initialize dns resolver",
-                      __FUNCTION__);
-          return InitPromise::CreateAndReject(
-              "Failed to initialize dns resolver", __func__);
-        }
-        if (NS_FAILED(
-                rv = mIceCtx->SetResolver(mDNSResolver->AllocateResolver()))) {
-          CSFLogError(LOGTAG, "%s: Failed to get dns resolver", __FUNCTION__);
-          return InitPromise::CreateAndReject("Failed to get dns resolver",
-                                              __func__);
-        }
-
         // We are reading these here, because when we setup the DTLS transport
         // we are on the wrong thread to read prefs
-        minDtlsVersion =
+        mMinDtlsVersion =
             Preferences::GetUint("media.peerconnection.dtls.version.min");
-        maxDtlsVersion =
+        mMaxDtlsVersion =
             Preferences::GetUint("media.peerconnection.dtls.version.max");
 
-        CSFLogDebug(LOGTAG, "%s done", __func__);
-        return InitPromise::CreateAndResolve(true, __func__);
+        NrIceCtx::Config config;
+        config.mPolicy = toNrIcePolicy(aIcePolicy);
+        config.mNatSimulatorConfig = GetNatConfig();
+
+        return InvokeAsync(
+            mStsThread, __func__,
+            [=, self = RefPtr<MediaTransportHandlerSTS>(this)]() {
+              mIceCtx = NrIceCtx::Create(aName, config);
+              if (!mIceCtx) {
+                return InitPromise::CreateAndReject("NrIceCtx::Create failed",
+                                                    __func__);
+              }
+
+              mIceCtx->SignalGatheringStateChange.connect(
+                  this, &MediaTransportHandlerSTS::OnGatheringStateChange);
+              mIceCtx->SignalConnectionStateChange.connect(
+                  this, &MediaTransportHandlerSTS::OnConnectionStateChange);
+
+              nsresult rv;
+
+              if (NS_FAILED(rv = mIceCtx->SetStunServers(stunServers))) {
+                CSFLogError(LOGTAG, "%s: Failed to set stun servers",
+                            __FUNCTION__);
+                return InitPromise::CreateAndReject(
+                    "Failed to set stun servers", __func__);
+              }
+              if (!turnDisabled) {
+                if (NS_FAILED(rv = mIceCtx->SetTurnServers(turnServers))) {
+                  CSFLogError(LOGTAG, "%s: Failed to set turn servers",
+                              __FUNCTION__);
+                  return InitPromise::CreateAndReject(
+                      "Failed to set turn servers", __func__);
+                }
+              } else if (!turnServers.empty()) {
+                CSFLogError(LOGTAG, "%s: Setting turn servers disabled",
+                            __FUNCTION__);
+              }
+
+              mDNSResolver = new NrIceResolver;
+              if (NS_FAILED(rv = mDNSResolver->Init())) {
+                CSFLogError(LOGTAG, "%s: Failed to initialize dns resolver",
+                            __FUNCTION__);
+                return InitPromise::CreateAndReject(
+                    "Failed to initialize dns resolver", __func__);
+              }
+              if (NS_FAILED(rv = mIceCtx->SetResolver(
+                                mDNSResolver->AllocateResolver()))) {
+                CSFLogError(LOGTAG, "%s: Failed to get dns resolver",
+                            __FUNCTION__);
+                return InitPromise::CreateAndReject(
+                    "Failed to get dns resolver", __func__);
+              }
+
+              CSFLogDebug(LOGTAG, "%s done", __func__);
+              return InitPromise::CreateAndResolve(true, __func__);
+            });
       });
   return NS_OK;
 }
 
 void MediaTransportHandlerSTS::Destroy() {
   if (!mInitPromise) {
     return;
   }
@@ -1188,18 +1246,18 @@ RefPtr<TransportFlow> MediaTransportHand
   auto dtls = MakeUnique<TransportLayerDtls>();
   auto srtp = MakeUnique<TransportLayerSrtp>(*dtls);
   dtls->SetRole(aDtlsClient ? TransportLayerDtls::CLIENT
                             : TransportLayerDtls::SERVER);
 
   dtls->SetIdentity(aDtlsIdentity);
 
   dtls->SetMinMaxVersion(
-      static_cast<TransportLayerDtls::Version>(minDtlsVersion),
-      static_cast<TransportLayerDtls::Version>(maxDtlsVersion));
+      static_cast<TransportLayerDtls::Version>(mMinDtlsVersion),
+      static_cast<TransportLayerDtls::Version>(mMaxDtlsVersion));
 
   for (const auto& digest : aDigests) {
     rv = dtls->SetVerificationDigest(digest);
     if (NS_FAILED(rv)) {
       CSFLogError(LOGTAG, "Could not set fingerprint");
       return nullptr;
     }
   }