Bug 906986 - Wrap NrIceCtx in NrIceCtxHandler which will allow us to handle ice restart. r=bwc, r=drno
authorMichael Froman <mfroman@mozilla.com>
Thu, 31 Mar 2016 14:12:19 -0500
changeset 292370 f6dd0039f260e8082895f3f1beb5e4306f254092
parent 292369 603dd13fc4e7664f314075662b52dba4bcd668c1
child 292371 651e8c7355bad2c551e99676a922dec0cb7486da
push id74831
push userryanvm@gmail.com
push dateFri, 08 Apr 2016 16:47:14 +0000
treeherdermozilla-inbound@dbde614eac1b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc, drno
bugs906986
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 906986 - Wrap NrIceCtx in NrIceCtxHandler which will allow us to handle ice restart. r=bwc, r=drno 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_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_;
@@ -1822,17 +1822,17 @@ class WebRtcIcePacketFilterTest : public
  public:
   WebRtcIcePacketFilterTest(): udp_filter_(nullptr),
                                tcp_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<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);
@@ -1934,17 +1934,17 @@ class WebRtcIcePacketFilterTest : public
                    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<nsISocketFilter> udp_filter_;
   nsCOMPtr<nsISocketFilter> tcp_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
@@ -314,23 +314,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
@@ -35,17 +35,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;
@@ -290,17 +290,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();
   }
@@ -560,17 +560,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