Bug 906986 - Wrap NrIceCtx in NrIceCtxHandler which will allow us to handle ice restart. draft
authorMichael Froman <mfroman@mozilla.com>
Thu, 31 Mar 2016 14:12:19 -0500
changeset 347091 7ef3b284263870ff8e285c4b41e0ad34fb7c3025
parent 347090 b2619c4947a194666b07bb8018dfe4fc4f19b71b
child 347092 ab540361661fdf973aa29a4b66d6a5d542df7816
child 347293 acf44038aeb1c928aa580548bf5b3fedeab068bd
child 348071 3040c6537ad783f17bb675de106f6a6134505219
push id14479
push usermfroman@nostrum.com
push dateFri, 01 Apr 2016 21:15:50 +0000
bugs906986
milestone48.0a1
Bug 906986 - Wrap NrIceCtx in NrIceCtxHandler which will allow us to handle ice restart. MozReview-Commit-ID: 8MEfEBf2Pvi
media/mtransport/common.build
media/mtransport/nricectx.cpp
media/mtransport/nricectx.h
media/mtransport/nricectxhandler.cpp
media/mtransport/nricectxhandler.h
media/mtransport/nricemediastream.cpp
media/mtransport/nricemediastream.h
media/mtransport/test/ice_unittest.cpp
media/mtransport/test/multi_tcp_socket_unittest.cpp
media/mtransport/test/transport_unittests.cpp
media/mtransport/test/turn_unittest.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
--- a/media/mtransport/common.build
+++ b/media/mtransport/common.build
@@ -4,16 +4,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 mtransport_lcppsrcs = [
     'dtlsidentity.cpp',
     'nr_socket_prsock.cpp',
     'nr_timer.cpp',
     'nricectx.cpp',
+    'nricectxhandler.cpp',
     'nricemediastream.cpp',
     'nriceresolver.cpp',
     'nriceresolverfake.cpp',
     'nrinterfaceprioritizer.cpp',
     'rlogringbuffer.cpp',
     'simpletokenbucket.cpp',
     'stun_udp_socket_filter.cpp',
     'test_nr_socket.cpp',
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -391,20 +391,21 @@ void NrIceCtx::trickle_cb(void *arg, nr_
     return;
 
   MOZ_MTLOG(ML_INFO, "NrIceCtx(" << ctx->name_ << "): trickling candidate "
             << candidate_str);
 
   s->SignalCandidate(s, candidate_str);
 }
 
-void NrIceCtx::Init(bool allow_loopback,
-                    bool tcp_enabled,
-                    bool allow_link_local)
-{
+
+void
+NrIceCtx::InitializeCryptoAndLogging(bool allow_loopback,
+                                     bool tcp_enabled,
+                                     bool allow_link_local) {
   // 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.
     // These numbers come from RFC 5245 S. 4.1.2.2
@@ -468,65 +469,58 @@ void NrIceCtx::Init(bool allow_loopback,
     if (force_net_interface.Length() > 0) {
       // Stupid cast.... but needed
       const nsCString& flat = PromiseFlatCString(static_cast<nsACString&>(force_net_interface));
       NR_reg_set_string((char *)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME, const_cast<char*>(flat.get()));
     }
   }
 }
 
-RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
-                                  bool offerer,
-                                  bool allow_loopback,
-                                  bool tcp_enabled,
-                                  bool allow_link_local,
-                                  bool hide_non_default,
-                                  Policy policy) {
-   RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer, policy);
-
-  // Initialize the crypto callbacks and logging stuff
-  Init(allow_loopback, tcp_enabled, allow_link_local);
-
+bool
+NrIceCtx::Initialize(NrIceCtx* ctx,
+                     bool hide_non_default)
+{
   // Create the ICE context
   int r;
 
-  UINT4 flags = offerer ? NR_ICE_CTX_FLAGS_OFFERER:
+  UINT4 flags = ctx->offerer_ ? NR_ICE_CTX_FLAGS_OFFERER:
       NR_ICE_CTX_FLAGS_ANSWERER;
   flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION;
-  if (policy == ICE_POLICY_RELAY) {
+  if (ctx->policy_ == ICE_POLICY_RELAY) {
     flags |= NR_ICE_CTX_FLAGS_RELAY_ONLY;
   }
 
   if (hide_non_default)
     flags |= NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS;
 
-  r = nr_ice_ctx_create(const_cast<char *>(name.c_str()), flags,
+  r = nr_ice_ctx_create(const_cast<char *>(ctx->name_.c_str()),
+                        flags,
                         &ctx->ctx_);
   if (r) {
-    MOZ_MTLOG(ML_ERROR, "Couldn't create ICE ctx for '" << name << "'");
-    return nullptr;
+    MOZ_MTLOG(ML_ERROR, "Couldn't create ICE ctx for '" << ctx->name_ << "'");
+    return false;
   }
 
   nr_interface_prioritizer *prioritizer = CreateInterfacePrioritizer();
   if (!prioritizer) {
     MOZ_MTLOG(LogLevel::Error, "Couldn't create interface prioritizer.");
-    return nullptr;
+    return false;
   }
 
   r = nr_ice_ctx_set_interface_prioritizer(ctx->ctx_, prioritizer);
   if (r) {
     MOZ_MTLOG(LogLevel::Error, "Couldn't set interface prioritizer.");
-    return nullptr;
+    return false;
   }
 
   if (ctx->generating_trickle()) {
     r = nr_ice_ctx_set_trickle_cb(ctx->ctx_, &NrIceCtx::trickle_cb, ctx);
     if (r) {
-      MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << name << "'");
-      return nullptr;
+      MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << ctx->name_ << "'");
+      return false;
     }
   }
 
   char* mapping_type = nullptr;
   char* filtering_type = nullptr;
   bool block_udp = false;
 
   nsresult rv;
@@ -570,31 +564,31 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const 
   ctx->ice_handler_vtbl_->ice_checking = &NrIceCtx::ice_checking;
 
   ctx->ice_handler_ = new nr_ice_handler();
   ctx->ice_handler_->vtbl = ctx->ice_handler_vtbl_;
   ctx->ice_handler_->obj = ctx;
 
   // Create the peer ctx. Because we do not support parallel forking, we
   // only have one peer ctx.
-  std::string peer_name = name + ":default";
+  std::string peer_name = ctx->name_ + ":default";
   r = nr_ice_peer_ctx_create(ctx->ctx_, ctx->ice_handler_,
                              const_cast<char *>(peer_name.c_str()),
                              &ctx->peer_);
   if (r) {
-    MOZ_MTLOG(ML_ERROR, "Couldn't create ICE peer ctx for '" << name << "'");
-    return nullptr;
+    MOZ_MTLOG(ML_ERROR, "Couldn't create ICE peer ctx for '" << ctx->name_ << "'");
+    return false;
   }
 
   ctx->sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
 
   if (!NS_SUCCEEDED(rv))
-    return nullptr;
+    return false;
 
-  return ctx;
+  return true;
 }
 
 int NrIceCtx::SetNat(const RefPtr<TestNat>& aNat) {
   nat_ = aNat;
   nr_socket_factory *fac;
   int r = nat_->create_socket_factory(&fac);
   if (r) {
     return r;
@@ -616,21 +610,16 @@ void NrIceCtx::internal_DeinitializeGlob
 NrIceCtx::~NrIceCtx() {
   MOZ_MTLOG(ML_DEBUG, "Destroying ICE ctx '" << name_ <<"'");
   nr_ice_peer_ctx_destroy(&peer_);
   nr_ice_ctx_destroy(&ctx_);
   delete ice_handler_vtbl_;
   delete ice_handler_;
 }
 
-RefPtr<NrIceMediaStream>
-NrIceCtx::CreateStream(const std::string& name, int components) {
-  return NrIceMediaStream::Create(this, name, components);
-}
-
 void
 NrIceCtx::SetStream(size_t index, NrIceMediaStream* stream) {
   if (index >= streams_.size()) {
     streams_.resize(index + 1);
   }
 
   RefPtr<NrIceMediaStream> oldStream(streams_[index]);
   streams_[index] = stream;
--- a/media/mtransport/nricectx.h
+++ b/media/mtransport/nricectx.h
@@ -208,45 +208,35 @@ class NrIceCtx {
                      ICE_CONTROLLED
   };
 
   enum Policy { ICE_POLICY_NONE,
                 ICE_POLICY_RELAY,
                 ICE_POLICY_ALL
   };
 
-  static void Init(bool allow_loopback = false,
-                   bool tcp_enabled = true,
-                   bool allow_link_local = false);
+  static void InitializeCryptoAndLogging(bool allow_loopback = false,
+                                         bool tcp_enabled = true,
+                                         bool allow_link_local = false);
 
-  // TODO(ekr@rtfm.com): Too many bools here. Bug 1193437.
-  static RefPtr<NrIceCtx> Create(const std::string& name,
-                                 bool offerer,
-                                 bool allow_loopback = false,
-                                 bool tcp_enabled = true,
-                                 bool allow_link_local = false,
-                                 bool hide_non_default = false,
-                                 Policy policy = ICE_POLICY_ALL);
+  static bool Initialize(NrIceCtx* ice_ctx,
+                         bool hide_non_default);
 
   int SetNat(const RefPtr<TestNat>& aNat);
 
   // Deinitialize all ICE global state. Used only for testing.
   static void internal_DeinitializeGlobal();
 
 
   nr_ice_ctx *ctx() { return ctx_; }
   nr_ice_peer_ctx *peer() { return peer_; }
 
   // Testing only.
   void destroy_peer_ctx();
 
-  // Create a media stream
-  RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
-                                        int components);
-
   void SetStream(size_t index, NrIceMediaStream* stream);
 
   RefPtr<NrIceMediaStream> GetStream(size_t index) {
     if (index < streams_.size()) {
       return streams_[index];
     }
     return nullptr;
   }
@@ -329,23 +319,24 @@ class NrIceCtx {
   sigslot::signal2<NrIceCtx*, NrIceCtx::ConnectionState>
     SignalConnectionStateChange;
 
   // The thread to direct method calls to
   nsCOMPtr<nsIEventTarget> thread() { return sts_target_; }
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceCtx)
 
- private:
+ protected:
+  virtual ~NrIceCtx();
+
   NrIceCtx(const std::string& name,
            bool offerer,
            Policy policy);
 
-  virtual ~NrIceCtx();
-
+ private:
   DISALLOW_COPY_ASSIGN(NrIceCtx);
 
   // Callbacks for nICEr
   static void gather_cb(NR_SOCKET s, int h, void *arg);  // ICE gather complete
 
   // Handler implementation
   static int select_pair(void *obj,nr_ice_media_stream *stream,
                          int component_id, nr_ice_cand_pair **potentials,
@@ -364,16 +355,17 @@ class NrIceCtx {
   RefPtr<NrIceMediaStream> FindStream(nr_ice_media_stream *stream);
 
   // Set the state
   void SetConnectionState(ConnectionState state);
 
   // Set the state
   void SetGatheringState(GatheringState state);
 
+protected:
   ConnectionState connection_state_;
   GatheringState gathering_state_;
   const std::string name_;
   bool offerer_;
   std::vector<RefPtr<NrIceMediaStream> > streams_;
   nr_ice_ctx *ctx_;
   nr_ice_peer_ctx *peer_;
   nr_ice_handler_vtbl* ice_handler_vtbl_;  // Must be pointer
new file mode 100644
--- /dev/null
+++ b/media/mtransport/nricectxhandler.cpp
@@ -0,0 +1,52 @@
+#include <sstream>
+
+// nICEr includes
+extern "C" {
+#include "nr_api.h"
+#include "ice_ctx.h"
+}
+
+// Local includes
+#include "nricectxhandler.h"
+#include "nricemediastream.h"
+
+namespace mozilla {
+
+NrIceCtxHandler::~NrIceCtxHandler()
+{
+}
+
+
+RefPtr<NrIceCtxHandler>
+NrIceCtxHandler::Create(const std::string& name,
+                        bool offerer,
+                        bool allow_loopback,
+                        bool tcp_enabled,
+                        bool allow_link_local,
+                        bool hide_non_default,
+                        Policy policy)
+{
+  // InitializeCryptoAndLogging only executes once
+  NrIceCtx::InitializeCryptoAndLogging(allow_loopback,
+                                       tcp_enabled,
+                                       allow_link_local);
+
+  RefPtr<NrIceCtxHandler> ctx = new NrIceCtxHandler(name, offerer, policy);
+
+  if (!NrIceCtx::Initialize(ctx,
+                            hide_non_default)) {
+    return nullptr;
+  }
+
+  return ctx;
+}
+
+
+RefPtr<NrIceMediaStream>
+NrIceCtxHandler::CreateStream(const std::string& name, int components)
+{
+  return NrIceMediaStream::Create(this, name, components);
+}
+
+
+} // close namespace
new file mode 100644
--- /dev/null
+++ b/media/mtransport/nricectxhandler.h
@@ -0,0 +1,36 @@
+#ifndef nricectxhandler_h__
+#define nricectxhandler_h__
+
+#include "nricectx.h"
+
+namespace mozilla {
+
+class NrIceCtxHandler : public NrIceCtx {
+public:
+  // TODO(ekr@rtfm.com): Too many bools here. Bug 1193437.
+  static RefPtr<NrIceCtxHandler> Create(const std::string& name,
+                                 bool offerer,
+                                 bool allow_loopback = false,
+                                 bool tcp_enabled = true,
+                                 bool allow_link_local = false,
+                                 bool hide_non_default = false,
+                                 Policy policy = ICE_POLICY_ALL);
+
+  // Create a media stream
+  RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
+                                        int components);
+
+protected:
+  NrIceCtxHandler(const std::string& name,
+                  bool offerer,
+                  Policy policy)
+  : NrIceCtx(name, offerer, policy)
+    {}
+
+  NrIceCtxHandler(); // disable
+  virtual ~NrIceCtxHandler();
+};
+
+} // close namespace
+
+#endif // nricectxhandler_h__
--- a/media/mtransport/nricemediastream.cpp
+++ b/media/mtransport/nricemediastream.cpp
@@ -179,29 +179,44 @@ static UniquePtr<NrIceCandidate> MakeNrI
 
 // NrIceMediaStream
 RefPtr<NrIceMediaStream>
 NrIceMediaStream::Create(NrIceCtx *ctx,
                          const std::string& name,
                          int components) {
   RefPtr<NrIceMediaStream> stream =
     new NrIceMediaStream(ctx, name, components);
+  MOZ_ASSERT(stream->ctx_ == ctx->ctx());
 
   int r = nr_ice_add_media_stream(ctx->ctx(),
                                   const_cast<char *>(name.c_str()),
                                   components, &stream->stream_);
   if (r) {
     MOZ_MTLOG(ML_ERROR, "Couldn't create ICE media stream for '"
               << name << "'");
     return nullptr;
   }
 
   return stream;
 }
 
+NrIceMediaStream::NrIceMediaStream(NrIceCtx *ctx,
+                                   const std::string& name,
+                                   size_t components) :
+      state_(ICE_CONNECTING),
+      ctx_(ctx->ctx()),
+      ctx_peer_(ctx->peer()),
+      name_(name),
+      components_(components),
+      stream_(nullptr),
+      level_(0),
+      has_parsed_attrs_(false)
+{
+}
+
 NrIceMediaStream::~NrIceMediaStream() {
   // We do not need to destroy anything. All major resources
   // are attached to the ice ctx.
 }
 
 nsresult NrIceMediaStream::ParseAttributes(std::vector<std::string>&
                                            attributes) {
   if (!stream_)
@@ -209,17 +224,17 @@ nsresult NrIceMediaStream::ParseAttribut
 
   std::vector<char *> attributes_in;
 
   for (size_t i=0; i<attributes.size(); ++i) {
     attributes_in.push_back(const_cast<char *>(attributes[i].c_str()));
   }
 
   // Still need to call nr_ice_ctx_parse_stream_attributes.
-  int r = nr_ice_peer_ctx_parse_stream_attributes(ctx_->peer(),
+  int r = nr_ice_peer_ctx_parse_stream_attributes(ctx_peer_,
                                                   stream_,
                                                   attributes_in.size() ?
                                                   &attributes_in[0] : nullptr,
                                                   attributes_in.size());
   if (r) {
     MOZ_MTLOG(ML_ERROR, "Couldn't parse attributes for stream "
               << name_ << "'");
     return NS_ERROR_FAILURE;
@@ -228,20 +243,20 @@ nsresult NrIceMediaStream::ParseAttribut
   has_parsed_attrs_ = true;
   return NS_OK;
 }
 
 // Parse trickle ICE candidate
 nsresult NrIceMediaStream::ParseTrickleCandidate(const std::string& candidate) {
   int r;
 
-  MOZ_MTLOG(ML_DEBUG, "NrIceCtx(" << ctx_->name() << ")/STREAM(" <<
+  MOZ_MTLOG(ML_DEBUG, "NrIceCtx(" << ctx_->label << ")/STREAM(" <<
             name() << ") : parsing trickle candidate " << candidate);
 
-  r = nr_ice_peer_ctx_parse_trickle_candidate(ctx_->peer(),
+  r = nr_ice_peer_ctx_parse_trickle_candidate(ctx_peer_,
                                               stream_,
                                               const_cast<char *>(
                                                 candidate.c_str())
                                               );
   if (r) {
     if (r == R_ALREADY) {
       MOZ_MTLOG(ML_ERROR, "Trickle candidates are redundant for stream '"
                 << name_ << "' because it is completed");
@@ -263,17 +278,17 @@ nsresult NrIceMediaStream::GetActivePair
   int r;
   nr_ice_candidate *local_int;
   nr_ice_candidate *remote_int;
 
   if (!stream_) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  r = nr_ice_media_stream_get_active(ctx_->peer(),
+  r = nr_ice_media_stream_get_active(ctx_peer_,
                                      stream_,
                                      component,
                                      &local_int, &remote_int);
   // If result is R_REJECTED then component is unpaired or disabled.
   if (r == R_REJECTED)
     return NS_ERROR_NOT_AVAILABLE;
 
   if (r)
@@ -301,24 +316,24 @@ nsresult NrIceMediaStream::GetActivePair
 nsresult NrIceMediaStream::GetCandidatePairs(std::vector<NrIceCandidatePair>*
                                              out_pairs) const {
   MOZ_ASSERT(out_pairs);
   if (!stream_) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // If we haven't at least started checking then there is nothing to report
-  if (ctx_->peer()->state != NR_ICE_PEER_STATE_PAIRED) {
+  if (ctx_peer_->state != NR_ICE_PEER_STATE_PAIRED) {
     return NS_OK;
   }
 
   // Get the check_list on the peer stream (this is where the check_list
   // actually lives, not in stream_)
   nr_ice_media_stream* peer_stream;
-  int r = nr_ice_peer_ctx_find_pstream(ctx_->peer(), stream_, &peer_stream);
+  int r = nr_ice_peer_ctx_find_pstream(ctx_peer_, stream_, &peer_stream);
   if (r != 0) {
     return NS_ERROR_FAILURE;
   }
 
   nr_ice_cand_pair *p1, *p2;
   out_pairs->clear();
 
   TAILQ_FOREACH(p1, &peer_stream->check_list, check_queue_entry) {
@@ -485,22 +500,22 @@ nsresult NrIceMediaStream::GetLocalCandi
 
 nsresult NrIceMediaStream::GetRemoteCandidates(
     std::vector<NrIceCandidate>* candidates) const {
   if (!stream_) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // If we haven't at least started checking then there is nothing to report
-  if (ctx_->peer()->state != NR_ICE_PEER_STATE_PAIRED) {
+  if (ctx_peer_->state != NR_ICE_PEER_STATE_PAIRED) {
     return NS_OK;
   }
 
   nr_ice_media_stream* peer_stream;
-  int r = nr_ice_peer_ctx_find_pstream(ctx_->peer(), stream_, &peer_stream);
+  int r = nr_ice_peer_ctx_find_pstream(ctx_peer_, stream_, &peer_stream);
   if (r != 0) {
     return NS_ERROR_FAILURE;
   }
 
   return GetCandidatesFromStream(peer_stream, candidates);
 }
 
 
@@ -520,17 +535,17 @@ nsresult NrIceMediaStream::DisableCompon
 }
 
 nsresult NrIceMediaStream::SendPacket(int component_id,
                                       const unsigned char *data,
                                       size_t len) {
   if (!stream_)
     return NS_ERROR_FAILURE;
 
-  int r = nr_ice_media_stream_send(ctx_->peer(), stream_,
+  int r = nr_ice_media_stream_send(ctx_peer_, stream_,
                                    component_id,
                                    const_cast<unsigned char *>(data), len);
   if (r) {
     MOZ_MTLOG(ML_ERROR, "Couldn't send media on '" << name_ << "'");
     if (r == R_WOULDBLOCK) {
       return NS_BASE_STREAM_WOULD_BLOCK;
     }
 
@@ -553,15 +568,15 @@ void NrIceMediaStream::Ready() {
     MOZ_MTLOG(ML_DEBUG, "Stream ready callback fired again for '" << name_ << "'");
   }
 }
 
 void NrIceMediaStream::Close() {
   MOZ_MTLOG(ML_DEBUG, "Marking stream closed '" << name_ << "'");
   state_ = ICE_CLOSED;
 
-  int r = nr_ice_remove_media_stream(ctx_->ctx(), &stream_);
+  int r = nr_ice_remove_media_stream(ctx_, &stream_);
   if (r) {
     MOZ_ASSERT(false, "Failed to remove stream");
     MOZ_MTLOG(ML_ERROR, "Failed to remove stream, error=" << r);
   }
 }
 }  // close namespace
--- a/media/mtransport/nricemediastream.h
+++ b/media/mtransport/nricemediastream.h
@@ -55,16 +55,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #include "nsIEventTarget.h"
 #include "nsITimer.h"
 
 #include "m_cpp_utils.h"
 
 
 namespace mozilla {
 
+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;
 
 class NrIceCtx;
 
 struct NrIceAddr {
   std::string host;
   uint16_t port;
   std::string transport;
@@ -194,32 +196,27 @@ class NrIceMediaStream {
   sigslot::signal1<NrIceMediaStream *> SignalReady;  // Candidate pair ready.
   sigslot::signal1<NrIceMediaStream *> SignalFailed;  // Candidate pair failed.
   sigslot::signal4<NrIceMediaStream *, int, const unsigned char *, int>
   SignalPacketReceived;  // Incoming packet
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceMediaStream)
 
  private:
-  NrIceMediaStream(NrIceCtx *ctx,  const std::string& name,
-                   size_t components) :
-      state_(ICE_CONNECTING),
-      ctx_(ctx),
-      name_(name),
-      components_(components),
-      stream_(nullptr),
-      level_(0),
-      has_parsed_attrs_(false) {}
+  NrIceMediaStream(NrIceCtx *ctx,
+                   const std::string& name,
+                   size_t components);
 
   ~NrIceMediaStream();
 
   DISALLOW_COPY_ASSIGN(NrIceMediaStream);
 
   State state_;
-  NrIceCtx *ctx_;
+  nr_ice_ctx *ctx_;
+  nr_ice_peer_ctx *ctx_peer_;
   const std::string name_;
   const size_t components_;
   nr_ice_media_stream *stream_;
   uint16_t level_;
   bool has_parsed_attrs_;
 };
 
 
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -20,17 +20,17 @@
 #include "nspr.h"
 #include "nss.h"
 #include "ssl.h"
 
 #include "mozilla/Preferences.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 
-#include "nricectx.h"
+#include "nricectxhandler.h"
 #include "nricemediastream.h"
 #include "nriceresolverfake.h"
 #include "nriceresolver.h"
 #include "nrinterfaceprioritizer.h"
 #include "gtest_ringbuffer_dumper.h"
 #include "rlogringbuffer.h"
 #include "runnable_utils.h"
 #include "stunserver.h"
@@ -378,18 +378,18 @@ class IceTestPeer : public sigslot::has_
  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, bool hide_non_default = false) :
       name_(name),
-      ice_ctx_(NrIceCtx::Create(name, offerer, allow_loopback,
-                                enable_tcp, allow_link_local, hide_non_default)),
+      ice_ctx_(NrIceCtxHandler::Create(name, offerer, allow_loopback,
+                                       enable_tcp, allow_link_local, hide_non_default)),
       candidates_(),
       gathering_complete_(false),
       ready_ct_(0),
       ice_complete_(false),
       ice_reached_checking_(false),
       received_(0),
       sent_(0),
       fake_resolver_(),
@@ -1253,17 +1253,17 @@ class IceTestPeer : public sigslot::has_
   }
 
   nsresult GetDefaultCandidate_s(unsigned int stream, NrIceCandidate* cand) {
     return ice_ctx_->GetStream(stream)->GetDefaultCandidate(1, cand);
   }
 
  private:
   std::string name_;
-  RefPtr<NrIceCtx> ice_ctx_;
+  RefPtr<NrIceCtxHandler> ice_ctx_;
   std::map<std::string, std::vector<std::string> > candidates_;
   // Maps from stream id to list of remote trickle candidates
   std::map<size_t, std::vector<SchedulableTrickleCandidate*> >
     controlled_trickle_candidates_;
   bool gathering_complete_;
   int ready_ct_;
   bool ice_complete_;
   bool ice_reached_checking_;
@@ -1821,17 +1821,17 @@ class WebRtcIcePrioritizerTest : public 
 class WebRtcIcePacketFilterTest : public StunTest {
  public:
   WebRtcIcePacketFilterTest(): filter_(nullptr) {}
 
   void SetUp() {
     StunTest::SetUp();
 
     // Set up enough of the ICE ctx to allow the packet filter to work
-    ice_ctx_ = NrIceCtx::Create("test", true);
+    ice_ctx_ = NrIceCtxHandler::Create("test", true);
 
     nsCOMPtr<nsIUDPSocketFilterHandler> handler =
       do_GetService(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID);
     handler->NewFilter(getter_AddRefs(filter_));
   }
 
   void TearDown() {
     test_utils_->sts_target()->Dispatch(WrapRunnable(this,
@@ -1874,17 +1874,17 @@ class WebRtcIcePacketFilterTest : public
   void MakeNetAddr(mozilla::net::NetAddr* net_addr,
                    uint8_t last_digit, uint16_t port) {
     net_addr->inet.family = AF_INET;
     net_addr->inet.ip = 192 << 24 | 168 << 16 | 1 << 8 | last_digit;
     net_addr->inet.port = port;
   }
 
   nsCOMPtr<nsIUDPSocketFilter> filter_;
-  RefPtr<NrIceCtx> ice_ctx_;
+  RefPtr<NrIceCtxHandler> ice_ctx_;
 };
 }  // end namespace
 
 TEST_F(WebRtcIceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
   if (stun_server_hostname_.empty()) {
     return;
   }
 
--- a/media/mtransport/test/multi_tcp_socket_unittest.cpp
+++ b/media/mtransport/test/multi_tcp_socket_unittest.cpp
@@ -19,17 +19,17 @@ extern "C" {
 #include "ice_ctx.h"
 #include "nr_socket_multi_tcp.h"
 }
 
 #include "nr_socket_prsock.h"
 
 #include "stunserver.h"
 
-#include "nricectx.h"
+#include "nricectxhandler.h"
 #include "nricemediastream.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 using namespace mozilla;
 
@@ -42,17 +42,17 @@ class MultiTcpSocketTest : public Mtrans
      socks(3,nullptr),
      readable(false),
      ice_ctx_()
    {}
 
   void SetUp() {
     MtransportTest::SetUp();
 
-    ice_ctx_ = NrIceCtx::Create("stun", true);
+    ice_ctx_ = NrIceCtxHandler::Create("stun", true);
 
     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/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -21,17 +21,17 @@
 #include "ssl.h"
 #include "sslproto.h"
 
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 
 #include "databuffer.h"
 #include "dtlsidentity.h"
-#include "nricectx.h"
+#include "nricectxhandler.h"
 #include "nricemediastream.h"
 #include "transportflow.h"
 #include "transportlayer.h"
 #include "transportlayerdtls.h"
 #include "transportlayerice.h"
 #include "transportlayerlog.h"
 #include "transportlayerloopback.h"
 
@@ -436,20 +436,20 @@ class TransportTestPeer : public sigslot
   TransportTestPeer(nsCOMPtr<nsIEventTarget> target, std::string name, MtransportTestUtils* utils)
       : name_(name), target_(target),
         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,
-                                  name == "P2" ?
-                                  TransportLayerDtls::CLIENT :
-                                  TransportLayerDtls::SERVER)),
+        ice_ctx_(NrIceCtxHandler::Create(name,
+                                         name == "P2" ?
+                                         TransportLayerDtls::CLIENT :
+                                         TransportLayerDtls::SERVER)),
         streams_(), candidates_(),
         peer_(nullptr),
         gathering_complete_(false),
         enabled_cipersuites_(),
         disabled_cipersuites_(),
         reuse_dhe_key_(false),
         test_utils_(utils) {
     std::vector<NrIceStunServer> stun_servers;
@@ -805,17 +805,17 @@ class TransportTestPeer : public sigslot
   size_t received_bytes_;
     RefPtr<TransportFlow> flow_;
   TransportLayerLoopback *loopback_;
   TransportLayerLogging *logging_;
   TransportLayerLossy *lossy_;
   TransportLayerDtls *dtls_;
   TransportLayerIce *ice_;
   RefPtr<DtlsIdentity> identity_;
-  RefPtr<NrIceCtx> ice_ctx_;
+  RefPtr<NrIceCtxHandler> ice_ctx_;
   std::vector<RefPtr<NrIceMediaStream> > streams_;
   std::map<std::string, std::vector<std::string> > candidates_;
   TransportTestPeer *peer_;
   bool gathering_complete_;
   unsigned char fingerprint_[TransportLayerDtls::kMaxDigestLength];
   size_t fingerprint_len_;
   std::vector<uint16_t> enabled_cipersuites_;
   std::vector<uint16_t> disabled_cipersuites_;
--- a/media/mtransport/test/turn_unittest.cpp
+++ b/media/mtransport/test/turn_unittest.cpp
@@ -72,17 +72,17 @@ extern "C" {
 #include "nr_socket.h"
 #include "nr_socket_local.h"
 #include "nr_socket_buffered_stun.h"
 #include "stun_client_ctx.h"
 #include "turn_client_ctx.h"
 }
 
 #include "nricemediastream.h"
-#include "nricectx.h"
+#include "nricectxhandler.h"
 
 
 using namespace mozilla;
 
 static std::string kDummyTurnServer("192.0.2.1");  // From RFC 5737
 
 class TurnClient : public MtransportTest {
  public:
@@ -97,17 +97,17 @@ class TurnClient : public MtransportTest
         received_(0),
         protocol_(IPPROTO_UDP) {
   }
 
   ~TurnClient() {
   }
 
   static void SetUpTestCase() {
-    NrIceCtx::Init(false, false, false);
+    NrIceCtx::InitializeCryptoAndLogging(false, false, false);
   }
 
   void SetTcp() {
     protocol_ = IPPROTO_TCP;
   }
 
   void Init_s() {
     int r;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -303,23 +303,23 @@ nsresult PeerConnectionMedia::Init(const
 #else
   bool ice_tcp = false;
   bool default_address_only = false;
 #endif
 
 
   // TODO(ekr@rtfm.com): need some way to set not offerer later
   // Looks like a bug in the NrIceCtx API.
-  mIceCtx = NrIceCtx::Create("PC:" + mParentName,
-                             true, // Offerer
-                             mParent->GetAllowIceLoopback(),
-                             ice_tcp,
-                             mParent->GetAllowIceLinkLocal(),
-                             default_address_only,
-                             policy);
+  mIceCtx = NrIceCtxHandler::Create("PC:" + mParentName,
+                                    true, // Offerer
+                                    mParent->GetAllowIceLoopback(),
+                                    ice_tcp,
+                                    mParent->GetAllowIceLinkLocal(),
+                                    default_address_only,
+                                    policy);
   if(!mIceCtx) {
     CSFLogError(logTag, "%s: Failed to create Ice Context", __FUNCTION__);
     return NS_ERROR_FAILURE;
   }
 
   if (NS_FAILED(rv = mIceCtx->SetStunServers(stun_servers))) {
     CSFLogError(logTag, "%s: Failed to set stun servers", __FUNCTION__);
     return rv;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -42,17 +42,17 @@ class DataChannel;
 class PeerIdentity;
 class MediaPipelineFactory;
 namespace dom {
 struct RTCInboundRTPStreamStats;
 struct RTCOutboundRTPStreamStats;
 }
 }
 
-#include "nricectx.h"
+#include "nricectxhandler.h"
 #include "nriceresolver.h"
 #include "nricemediastream.h"
 #include "MediaPipeline.h"
 
 namespace mozilla {
 
 class PeerConnectionImpl;
 class PeerConnectionMedia;
@@ -229,17 +229,17 @@ class PeerConnectionMedia : public sigsl
 
   PeerConnectionImpl* GetPC() { return mParent; }
   nsresult Init(const std::vector<NrIceStunServer>& stun_servers,
                 const std::vector<NrIceTurnServer>& turn_servers,
                 NrIceCtx::Policy policy);
   // WARNING: This destroys the object!
   void SelfDestruct();
 
-  RefPtr<NrIceCtx> ice_ctx() const { return mIceCtx; }
+  RefPtr<NrIceCtxHandler> ice_ctx() const { return mIceCtx; }
 
   RefPtr<NrIceMediaStream> ice_media_stream(size_t i) const {
     return mIceCtx->GetStream(i);
   }
 
   size_t num_ice_media_streams() const {
     return mIceCtx->GetStreamCount();
   }
@@ -494,17 +494,17 @@ class PeerConnectionMedia : public sigsl
 
   // A list of streams provided by the other side
   // This is only accessed on the main thread (with one special exception)
   nsTArray<RefPtr<RemoteSourceStreamInfo> > mRemoteSourceStreams;
 
   std::map<size_t, std::pair<bool, RefPtr<MediaSessionConduit>>> mConduits;
 
   // ICE objects
-  RefPtr<NrIceCtx> mIceCtx;
+  RefPtr<NrIceCtxHandler> mIceCtx;
 
   // DNS
   RefPtr<NrIceResolver> mDNSResolver;
 
   // Transport flows: even is RTP, odd is RTCP
   std::map<int, RefPtr<TransportFlow> > mTransportFlows;
 
   // UUID Generator