Backout a9ab0881ebe2 (bug 729512) and ed6491f2335e (bug 733002) due to M3 orange.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 03 Oct 2012 21:03:16 -0400
changeset 115475 94279b84aee8836d2109cef202b6ed7a1b06a596
parent 115474 a04b83c532975b414c8f37936ab1e57075d85391
child 115476 333a7d8241f09fa1259ab9bd7468e6c359cb9eca
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
bugs729512, 733002
milestone18.0a1
backs outa9ab0881ebe2058140cef8205aeadaf1a263936c
Backout a9ab0881ebe2 (bug 729512) and ed6491f2335e (bug 733002) due to M3 orange.
content/base/public/Makefile.in
content/base/public/nsContentUtils.h
content/base/public/nsIDOMDataChannel.idl
content/base/src/Makefile.in
content/base/src/WebSocket.cpp
content/base/src/WebSocket.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMDataChannel.cpp
content/base/src/nsDOMDataChannel.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
netwerk/Makefile.in
netwerk/build/Makefile.in
netwerk/sctp/datachannel/DataChannel.cpp
netwerk/sctp/datachannel/DataChannel.h
netwerk/sctp/datachannel/DataChannelLog.h
netwerk/sctp/datachannel/DataChannelProtocol.h
netwerk/sctp/datachannel/Makefile.in
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -60,17 +60,16 @@ EXPORTS_mozilla = \
 
 SDK_XPIDLSRCS   = \
 		nsISelection.idl  \
 		$(NULL)
 
 XPIDLSRCS	= \
 		nsIContentPolicy.idl        \
 		nsIDocumentEncoder.idl      \
-	        nsIDOMDataChannel.idl \
 		nsIDOMFile.idl \
 		nsIDOMFileReader.idl \
 		nsIDOMFileList.idl \
 		nsIDOMFormData.idl \
 		nsIDOMParser.idl \
 		nsIDOMSerializer.idl \
 		nsISelectionController.idl  \
 		nsISelectionDisplay.idl  \
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1760,20 +1760,16 @@ public:
   }
 
   /**
    * Creates an arraybuffer from a binary string.
    */
   static nsresult CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
                                     JSObject** aResult);
 
-  static nsresult CreateBlobBuffer(JSContext* aCx,
-                                   const nsACString& aData,
-                                   jsval& aBlob);
-
   static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
 
   /**
    * Strip all \n, \r and nulls from the given string
    * @param aString the string to remove newlines from [in/out]
    */
   static void RemoveNewlines(nsString &aString);
 
deleted file mode 100644
--- a/content/base/public/nsIDOMDataChannel.idl
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "domstubs.idl"
-
-#include "nsIDOMEventTarget.idl"
-
-interface nsIVariant;
-
-[scriptable, builtinclass, uuid(fb7a8ec4-c1eb-4d9f-b927-fbb8b4493e6d)]
-interface nsIDOMDataChannel : nsIDOMEventTarget
-{
-  readonly attribute DOMString label;
-  readonly attribute boolean reliable;
-  readonly attribute boolean ordered;
-
-  readonly attribute DOMString readyState;
-  readonly attribute unsigned long bufferedAmount;
-
-  [implicit_jscontext] attribute jsval onopen;
-  [implicit_jscontext] attribute jsval onerror;
-  [implicit_jscontext] attribute jsval onclose;
-  [implicit_jscontext] attribute jsval onmessage;
-
-  attribute DOMString binaryType;
-
-  void close();
-
-  /**
-   * Transmits data to other end of the connection.
-   * @param data The data to be transmitted.  Arraybuffers and Blobs are sent as
-   * binary data.  Strings are sent as UTF-8 text data.  Other types are
-   * converted to a String and sent as a String.
-   * @return if the connection is still established and the data was queued or
-   *         sent successfully.
-   */
-  [implicit_jscontext] void send(in nsIVariant data);
-};
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -132,24 +132,16 @@ CPPSRCS		= \
 		nsInProcessTabChildGlobal.cpp \
 		ThirdPartyUtil.cpp \
 		nsEventSource.cpp \
 		FileIOObject.cpp \
 		nsDOMMutationObserver.cpp \
 		nsMixedContentBlocker.cpp \
 		$(NULL)
 
-ifdef MOZ_WEBRTC
-EXPORTS += nsDOMDataChannel.h
-CPPSRCS += nsDOMDataChannel.cpp
-LOCAL_INCLUDES += \
-		-I$(topsrcdir)/netwerk/sctp/datachannel \
-		$(NULL)
-endif
-
 # Are we targeting x86-32 or x86-64?  If so, we want to include SSE2 code for
 # nsTextFragment.cpp
 ifneq (,$(INTEL_ARCHITECTURE))
 CPPSRCS += nsTextFragmentSSE2.cpp
 endif
 
 GQI_SRCS = contentbase.gqi
 
--- a/content/base/src/WebSocket.cpp
+++ b/content/base/src/WebSocket.cpp
@@ -895,17 +895,17 @@ WebSocket::CreateAndDispatchMessageEvent
   NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
 
   // Create appropriate JS object for message
   jsval jsData;
   {
     JSAutoRequest ar(cx);
     if (isBinary) {
       if (mBinaryType == BinaryTypeValues::Blob) {
-        rv = nsContentUtils::CreateBlobBuffer(cx, aData, jsData);
+        rv = CreateResponseBlob(aData, cx, jsData);
         NS_ENSURE_SUCCESS(rv, rv);
       } else if (mBinaryType == BinaryTypeValues::Arraybuffer) {
         JSObject* arrayBuf;
         rv = nsContentUtils::CreateArrayBuffer(cx, aData, &arrayBuf);
         NS_ENSURE_SUCCESS(rv, rv);
         jsData = OBJECT_TO_JSVAL(arrayBuf);
       } else {
         NS_RUNTIMEABORT("Unknown binary type!");
@@ -938,16 +938,36 @@ WebSocket::CreateAndDispatchMessageEvent
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = event->SetTrusted(true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
 }
 
+// Initial implementation: only stores to RAM, not file
+// TODO: bug 704447: large file support
+nsresult
+WebSocket::CreateResponseBlob(const nsACString& aData,
+                              JSContext *aCx,
+                              jsval &jsData)
+{
+  uint32_t blobLen = aData.Length();
+  void* blobData = PR_Malloc(blobLen);
+  nsCOMPtr<nsIDOMBlob> blob;
+  if (blobData) {
+    memcpy(blobData, aData.BeginReading(), blobLen);
+    blob = new nsDOMMemoryFile(blobData, blobLen, EmptyString());
+  } else {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  JSObject* scope = JS_GetGlobalForScopeChain(aCx);
+  return nsContentUtils::WrapNative(aCx, scope, blob, &jsData, nullptr, true);
+}
+
 nsresult
 WebSocket::CreateAndDispatchCloseEvent(bool aWasClean,
                                        uint16_t aCode,
                                        const nsString &aReason)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
   nsresult rv = CheckInnerWindowCorrectness();
--- a/content/base/src/WebSocket.h
+++ b/content/base/src/WebSocket.h
@@ -223,16 +223,19 @@ protected:
 
   // These methods actually do the dispatch for various events.
   nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
   nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
                                          bool isBinary);
   nsresult CreateAndDispatchCloseEvent(bool aWasClean,
                                        uint16_t aCode,
                                        const nsString& aReason);
+  nsresult CreateResponseBlob(const nsACString& aData,
+                              JSContext* aCx,
+                              jsval& jsData);
 
   // if there are "strong event listeners" (see comment in WebSocket.cpp) or
   // outgoing not sent messages then this method keeps the object alive
   // when js doesn't have strong references to it.
   void UpdateMustKeepAlive();
   // ATTENTION, when calling this method the object can be released
   // (and possibly collected).
   void DontKeepAliveAnyMore();
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6198,36 +6198,16 @@ nsContentUtils::CreateArrayBuffer(JSCont
   if (dataLen > 0) {
     NS_ASSERTION(JS_IsArrayBufferObject(*aResult, aCx), "What happened?");
     memcpy(JS_GetArrayBufferData(*aResult, aCx), aData.BeginReading(), dataLen);
   }
 
   return NS_OK;
 }
 
-// Initial implementation: only stores to RAM, not file
-// TODO: bug 704447: large file support
-nsresult
-nsContentUtils::CreateBlobBuffer(JSContext* aCx,
-                                 const nsACString& aData,
-                                 jsval& aBlob)
-{
-  uint32_t blobLen = aData.Length();
-  void* blobData = PR_Malloc(blobLen);
-  nsCOMPtr<nsIDOMBlob> blob;
-  if (blobData) {
-    memcpy(blobData, aData.BeginReading(), blobLen);
-    blob = new nsDOMMemoryFile(blobData, blobLen, EmptyString());
-  } else {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  JSObject* scope = JS_GetGlobalForScopeChain(aCx);
-  return nsContentUtils::WrapNative(aCx, scope, blob, &aBlob, nullptr, true);
-}
-
 void
 nsContentUtils::StripNullChars(const nsAString& aInStr, nsAString& aOutStr)
 {
   // In common cases where we don't have nulls in the
   // string we can simple simply bypass the checking code.
   int32_t firstNullPos = aInStr.FindChar('\0');
   if (firstNullPos == kNotFound) {
     aOutStr.Assign(aInStr);
deleted file mode 100644
--- a/content/base/src/nsDOMDataChannel.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#ifdef MOZ_LOGGING
-#define FORCE_PR_LOG
-#endif
-
-#include "base/basictypes.h"
-#include "prlog.h"
-
-#ifdef PR_LOGGING
-extern PRLogModuleInfo* dataChannelLog;
-#endif
-#undef LOG
-#define LOG(args) PR_LOG(dataChannelLog, PR_LOG_DEBUG, args)
-
-
-#include "nsDOMDataChannel.h"
-#include "nsIDOMFile.h"
-#include "nsIJSNativeInitializer.h"
-#include "nsIDOMDataChannel.h"
-#include "nsIDOMMessageEvent.h"
-#include "nsDOMClassInfo.h"
-#include "nsDOMEventTargetHelper.h"
-
-#include "jsval.h"
-
-#include "nsError.h"
-#include "nsAutoPtr.h"
-#include "nsContentUtils.h"
-#include "nsCycleCollectionParticipant.h"
-#include "nsIScriptObjectPrincipal.h"
-#include "nsJSUtils.h"
-#include "nsNetUtil.h"
-#include "nsDOMFile.h"
-
-#include "DataChannel.h"
-
-#ifdef GetBinaryType
-// Windows apparently has a #define for GetBinaryType...
-#undef GetBinaryType
-#endif
-
-class nsDOMDataChannel : public nsDOMEventTargetHelper,
-                         public nsIDOMDataChannel,
-                         public mozilla::DataChannelListener
-{
-public:
-  nsDOMDataChannel(mozilla::DataChannel* aDataChannel)
-    : mDataChannel(aDataChannel)
-    , mBinaryType(DC_BINARY_TYPE_BLOB)
-  {}
-
-  nsresult Init(nsPIDOMWindow* aDOMWindow);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIDOMDATACHANNEL
-
-  NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
-
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDataChannel,
-                                           nsDOMEventTargetHelper)
-
-  nsresult
-  DoOnMessageAvailable(const nsACString& aMessage, bool aBinary);
-
-  virtual nsresult
-  OnMessageAvailable(nsISupports* aContext, const nsACString& aMessage);
-
-  virtual nsresult
-  OnBinaryMessageAvailable(nsISupports* aContext, const nsACString& aMessage);
-
-  virtual nsresult OnSimpleEvent(nsISupports* aContext, const nsAString& aName);
-
-  virtual nsresult
-  OnChannelConnected(nsISupports* aContext);
-
-  virtual nsresult
-  OnChannelClosed(nsISupports* aContext);
-
-  virtual void
-  AppReady();
-
-private:
-  // Get msg info out of JS variable being sent (string, arraybuffer, blob)
-  nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut,
-                         nsCOMPtr<nsIInputStream> &aStreamOut,
-                         bool &aIsBinary, uint32_t &aOutgoingLength,
-                         JSContext *aCx);
-
-  // Owning reference
-  nsAutoPtr<mozilla::DataChannel> mDataChannel;
-  nsString  mOrigin;
-  enum
-  {
-    DC_BINARY_TYPE_ARRAYBUFFER,
-    DC_BINARY_TYPE_BLOB,
-  } mBinaryType;
-};
-
-DOMCI_DATA(DataChannel, nsDOMDataChannel)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataChannel)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDataChannel,
-                                                  nsDOMEventTargetHelper)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDataChannel,
-                                                nsDOMEventTargetHelper)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_ADDREF_INHERITED(nsDOMDataChannel, nsDOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(nsDOMDataChannel, nsDOMEventTargetHelper)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDataChannel)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMDataChannel)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DataChannel)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
-
-nsresult
-nsDOMDataChannel::Init(nsPIDOMWindow* aDOMWindow)
-{
-  nsresult rv;
-  nsAutoString urlParam;
-
-  nsDOMEventTargetHelper::Init();
-
-  MOZ_ASSERT(mDataChannel);
-  mDataChannel->SetListener(this, nullptr);
-
-  // Now grovel through the objects to get a usable origin for onMessage
-  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aDOMWindow);
-  NS_ENSURE_STATE(sgo);
-  nsCOMPtr<nsIScriptContext> scriptContext = sgo->GetContext();
-  NS_ENSURE_STATE(scriptContext);
-
-  nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal(do_QueryInterface(aDOMWindow));
-  NS_ENSURE_STATE(scriptPrincipal);
-  nsCOMPtr<nsIPrincipal> principal = scriptPrincipal->GetPrincipal();
-  NS_ENSURE_STATE(principal);
-
-  if (aDOMWindow) {
-    BindToOwner(aDOMWindow->IsOuterWindow() ?
-                aDOMWindow->GetCurrentInnerWindow() : aDOMWindow);
-  } else {
-    BindToOwner(aDOMWindow);
-  }
-
-  // Attempt to kill "ghost" DataChannel (if one can happen): but usually too early for check to fail
-  rv = CheckInnerWindowCorrectness();
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  // See bug 696085
-  // We don't need to observe for window destroyed or frozen; but PeerConnection needs
-  // to not allow itself to be bfcached (and get destroyed on navigation).
-
-  rv = nsContentUtils::GetUTFOrigin(principal,mOrigin);
-  LOG(("%s: origin = %s\n",__FUNCTION__,NS_LossyConvertUTF16toASCII(mOrigin).get()));
-  return rv;
-}
-
-NS_IMPL_EVENT_HANDLER(nsDOMDataChannel, open)
-NS_IMPL_EVENT_HANDLER(nsDOMDataChannel, error)
-NS_IMPL_EVENT_HANDLER(nsDOMDataChannel, close)
-NS_IMPL_EVENT_HANDLER(nsDOMDataChannel, message)
-
-NS_IMETHODIMP
-nsDOMDataChannel::GetLabel(nsAString& aLabel)
-{
-  mDataChannel->GetLabel(aLabel);
-  return NS_OK;
-}
-
-// XXX should be GetType()?  Open question for the spec
-NS_IMETHODIMP
-nsDOMDataChannel::GetReliable(bool* aReliable)
-{
-  *aReliable = (mDataChannel->GetType() == mozilla::DataChannelConnection::RELIABLE);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDataChannel::GetOrdered(bool* aOrdered)
-{
-  *aOrdered = mDataChannel->GetOrdered();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDataChannel::GetReadyState(nsAString& aReadyState)
-{
-  uint16_t readyState = mDataChannel->GetReadyState();
-  const char * stateName[] = {
-    "Connecting",
-    "Open",
-    "Closing",
-    "Closed"
-  };
-  MOZ_ASSERT(/*readyState >= mozilla::DataChannel::CONNECTING && */ // Always true due to datatypes
-             readyState <= mozilla::DataChannel::CLOSED);
-  aReadyState.AssignASCII(stateName[readyState]);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDataChannel::GetBufferedAmount(uint32_t* aBufferedAmount)
-{
-  *aBufferedAmount = mDataChannel->GetBufferedAmount();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsDOMDataChannel::GetBinaryType(nsAString & aBinaryType)
-{
-  switch (mBinaryType) {
-  case DC_BINARY_TYPE_ARRAYBUFFER:
-    aBinaryType.AssignLiteral("arraybuffer");
-    break;
-  case DC_BINARY_TYPE_BLOB:
-    aBinaryType.AssignLiteral("blob");
-    break;
-  default:
-    NS_ERROR("Should not happen");
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDataChannel::SetBinaryType(const nsAString& aBinaryType)
-{
-  if (aBinaryType.EqualsLiteral("arraybuffer")) {
-    mBinaryType = DC_BINARY_TYPE_ARRAYBUFFER;
-  } else if (aBinaryType.EqualsLiteral("blob")) {
-    mBinaryType = DC_BINARY_TYPE_BLOB;
-  } else  {
-    return NS_ERROR_INVALID_ARG;
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDataChannel::Close()
-{
-  mDataChannel->Close();
-  return NS_OK;
-}
-
-// Almost a clone of nsWebSocketChannel::Send()
-NS_IMETHODIMP
-nsDOMDataChannel::Send(nsIVariant* aData, JSContext* aCx)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  uint16_t state = mDataChannel->GetReadyState();
-
-  // In reality, the DataChannel protocol allows this, but we want it to
-  // look like WebSockets
-  if (state == mozilla::DataChannel::CONNECTING) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  nsCString msgString;
-  nsCOMPtr<nsIInputStream> msgStream;
-  bool isBinary;
-  uint32_t msgLen;
-  nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen, aCx);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (state == mozilla::DataChannel::CLOSING ||
-      state == mozilla::DataChannel::CLOSED) {
-    return NS_OK;
-  }
-
-  MOZ_ASSERT(state == mozilla::DataChannel::OPEN,
-             "Unknown state in nsWebSocket::Send");
-
-  int32_t sent;
-  if (msgStream) {
-    sent = mDataChannel->SendBinaryStream(msgStream, msgLen);
-  } else {
-    if (isBinary) {
-      sent = mDataChannel->SendBinaryMsg(msgString);
-    } else {
-      sent = mDataChannel->SendMsg(msgString);
-    }
-  }
-  return sent >= 0 ? NS_OK : NS_ERROR_FAILURE;
-}
-
-// XXX Exact clone of nsWebSocketChannel::GetSendParams() - find a way to share!
-nsresult
-nsDOMDataChannel::GetSendParams(nsIVariant* aData, nsCString& aStringOut,
-                                nsCOMPtr<nsIInputStream>& aStreamOut,
-                                bool& aIsBinary, uint32_t& aOutgoingLength,
-                                JSContext* aCx)
-{
-  // Get type of data (arraybuffer, blob, or string)
-  uint16_t dataType;
-  nsresult rv = aData->GetDataType(&dataType);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (dataType == nsIDataType::VTYPE_INTERFACE ||
-      dataType == nsIDataType::VTYPE_INTERFACE_IS) {
-    nsCOMPtr<nsISupports> supports;
-    nsID* iid;
-    rv = aData->GetAsInterface(&iid, getter_AddRefs(supports));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsMemory::Free(iid);
-
-    // ArrayBuffer?
-    jsval realVal;
-    JSObject* obj;
-    nsresult rv = aData->GetAsJSVal(&realVal);
-    if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
-        (obj = JSVAL_TO_OBJECT(realVal)) &&
-        (JS_IsArrayBufferObject(obj, aCx))) {
-      int32_t len = JS_GetArrayBufferByteLength(obj, aCx);
-      char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj, aCx));
-
-      aStringOut.Assign(data, len);
-      aIsBinary = true;
-      aOutgoingLength = len;
-      return NS_OK;
-    }
-
-    // Blob?
-    nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports);
-    if (blob) {
-      rv = blob->GetInternalStream(getter_AddRefs(aStreamOut));
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      // GetSize() should not perform blocking I/O (unlike Available())
-      uint64_t blobLen;
-      rv = blob->GetSize(&blobLen);
-      NS_ENSURE_SUCCESS(rv, rv);
-      if (blobLen > PR_UINT32_MAX) {
-        return NS_ERROR_FILE_TOO_BIG;
-      }
-      aOutgoingLength = static_cast<uint32_t>(blobLen);
-
-      aIsBinary = true;
-      return NS_OK;
-    }
-  }
-
-  // Text message: if not already a string, turn it into one.
-  // TODO: bug 704444: Correctly coerce any JS type to string
-  //
-  PRUnichar* data = nullptr;
-  uint32_t len = 0;
-  rv = aData->GetAsWStringWithSize(&len, &data);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsString text;
-  text.Adopt(data, len);
-
-  CopyUTF16toUTF8(text, aStringOut);
-
-  aIsBinary = false;
-  aOutgoingLength = aStringOut.Length();
-  return NS_OK;
-}
-
-nsresult
-nsDOMDataChannel::DoOnMessageAvailable(const nsACString& aData,
-                                       bool aBinary)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  LOG(("DoOnMessageAvailable%s\n",aBinary ? ((mBinaryType == DC_BINARY_TYPE_BLOB) ? " (blob)" : " (binary)") : ""));
-
-  nsresult rv = CheckInnerWindowCorrectness();
-  if (NS_FAILED(rv)) {
-    return NS_OK;
-  }
-  nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(GetOwner());
-  NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE);
-
-  nsIScriptContext* sc = sgo->GetContext();
-  NS_ENSURE_TRUE(sc, NS_ERROR_FAILURE);
-
-  JSContext* cx = sc->GetNativeContext();
-  NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
-
-  JSAutoRequest ar(cx);
-  jsval jsData;
-
-  if (aBinary) {
-    if (mBinaryType == DC_BINARY_TYPE_BLOB) {
-      rv = nsContentUtils::CreateBlobBuffer(cx, aData, jsData);
-      NS_ENSURE_SUCCESS(rv, rv);
-    } else if (mBinaryType == DC_BINARY_TYPE_ARRAYBUFFER) {
-      JSObject* arrayBuf;
-      rv = nsContentUtils::CreateArrayBuffer(cx, aData, &arrayBuf);
-      NS_ENSURE_SUCCESS(rv, rv);
-      jsData = OBJECT_TO_JSVAL(arrayBuf);
-    } else {
-      NS_RUNTIMEABORT("Unknown binary type!");
-      return NS_ERROR_UNEXPECTED;
-    }
-  } else {
-    NS_ConvertUTF8toUTF16 utf16data(aData);
-    JSString* jsString = JS_NewUCStringCopyN(cx, utf16data.get(), utf16data.Length());
-    NS_ENSURE_TRUE(jsString, NS_ERROR_FAILURE);
-
-    jsData = STRING_TO_JSVAL(jsString);
-  }
-
-  nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMMessageEvent(getter_AddRefs(event), nullptr, nullptr);
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  nsCOMPtr<nsIDOMMessageEvent> messageEvent = do_QueryInterface(event);
-  rv = messageEvent->InitMessageEvent(NS_LITERAL_STRING("message"),
-                                      false, false,
-                                      jsData, mOrigin, EmptyString(),
-                                      nullptr);
-  NS_ENSURE_SUCCESS(rv,rv);
-  event->SetTrusted(true);
-
-  LOG(("%p(%p): %s - Dispatching\n",this,(void*)mDataChannel,__FUNCTION__));
-  rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
-  if (NS_FAILED(rv)) {
-    NS_WARNING("Failed to dispatch the message event!!!");
-  }
-  return rv;
-}
-
-nsresult
-nsDOMDataChannel::OnMessageAvailable(nsISupports* aContext,
-                                     const nsACString& aMessage)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  return DoOnMessageAvailable(aMessage, false);
-}
-
-nsresult
-nsDOMDataChannel::OnBinaryMessageAvailable(nsISupports* aContext,
-                                           const nsACString& aMessage)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  return DoOnMessageAvailable(aMessage, true);
-}
-
-nsresult
-nsDOMDataChannel::OnSimpleEvent(nsISupports* aContext, const nsAString& aName)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsresult rv = CheckInnerWindowCorrectness();
-  if (NS_FAILED(rv)) {
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsIDOMEvent> event;
-  rv = NS_NewDOMEvent(getter_AddRefs(event), nullptr, nullptr);
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  rv = event->InitEvent(aName, false, false);
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  event->SetTrusted(true);
-
-  return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
-}
-
-nsresult
-nsDOMDataChannel::OnChannelConnected(nsISupports* aContext)
-{
-  LOG(("%p(%p): %s - Dispatching\n",this,(void*)mDataChannel,__FUNCTION__));
-
-  return OnSimpleEvent(aContext, NS_LITERAL_STRING("open"));
-}
-
-nsresult
-nsDOMDataChannel::OnChannelClosed(nsISupports* aContext)
-{
-  LOG(("%p(%p): %s - Dispatching\n",this,(void*)mDataChannel,__FUNCTION__));
-
-  return OnSimpleEvent(aContext, NS_LITERAL_STRING("close"));
-}
-
-void
-nsDOMDataChannel::AppReady()
-{
-  mDataChannel->AppReady();
-}
-
-/* static */
-nsresult
-NS_NewDOMDataChannel(mozilla::DataChannel* aDataChannel,
-                     nsPIDOMWindow* aWindow,
-                     nsIDOMDataChannel** aDomDataChannel)
-{
-  nsRefPtr<nsDOMDataChannel> domdc = new nsDOMDataChannel(aDataChannel);
-
-  nsresult rv = domdc->Init(aWindow);
-  NS_ENSURE_SUCCESS(rv,rv);
-
-  return CallQueryInterface(domdc, aDomDataChannel);
-}
-
-/* static */
-void
-NS_DataChannelAppReady(nsIDOMDataChannel* aDomDataChannel)
-{
-  ((nsDOMDataChannel *)aDomDataChannel)->AppReady();
-}
deleted file mode 100644
--- a/content/base/src/nsDOMDataChannel.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#ifndef nsDOMDataChannel_h__
-#define nsDOMDataChannel_h__
-
-// This defines only what's necessary to create nsDOMDataChannels, since this
-// gets used with MOZ_INTERNAL_API not set for media/webrtc/signaling/testing
-
-#include "nsIDOMDataChannel.h"
-
-namespace mozilla {
-   class DataChannel;
-}
-
-class nsPIDOMWindow;
-
-nsresult
-NS_NewDOMDataChannel(mozilla::DataChannel* dataChannel,
-                     nsPIDOMWindow* aWindow,
-                     nsIDOMDataChannel** domDataChannel);
-
-// Tell DataChannel it's ok to deliver open and message events
-void NS_DataChannelAppReady(nsIDOMDataChannel* domDataChannel);
-
-#endif
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -545,20 +545,16 @@ using mozilla::dom::indexedDB::IDBWrappe
 
 #include "DOMFileHandle.h"
 #include "FileRequest.h"
 #include "LockedFile.h"
 #include "GeneratedEvents.h"
 #include "mozilla/Likely.h"
 #include "nsDebug.h"
 
-#ifdef MOZ_WEBRTC
-#include "nsIDOMDataChannel.h"
-#endif
-
 #undef None // something included above defines this preprocessor symbol, maybe Xlib headers
 #include "WebGLContext.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/HTMLCollectionBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -1706,21 +1702,16 @@ static nsDOMClassInfoData sClassInfoData
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(LockedFile, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(MozActivity, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(MozTimeManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
-
-#ifdef MOZ_WEBRTC
-  NS_DEFINE_CLASSINFO_DATA(DataChannel, nsEventTargetSH,
-                           EVENTTARGET_SCRIPTABLE_FLAGS)
-#endif
 };
 
 // Objects that should be constructable through |new Name();|
 struct nsContractIDMapData
 {
   int32_t mDOMClassInfoID;
   const char *mContractID;
 };
@@ -4514,23 +4505,16 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMRequest)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(MozTimeManager, nsIDOMMozTimeManager)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozTimeManager)
   DOM_CLASSINFO_MAP_END
 
-#ifdef MOZ_WEBRTC
-  DOM_CLASSINFO_MAP_BEGIN(DataChannel, nsIDOMDataChannel)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataChannel)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
-  DOM_CLASSINFO_MAP_END
-#endif
-
 #ifdef DEBUG
   {
     uint32_t i = ArrayLength(sClassInfoData);
 
     if (i != eDOMClassInfoIDCount) {
       NS_ERROR("The number of items in sClassInfoData doesn't match the "
                "number of nsIDOMClassInfo ID's, this is bad! Fix it!");
 
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -532,12 +532,8 @@ DOMCI_CLASS(OpenWindowEventDetail)
 
 DOMCI_CLASS(DOMFileHandle)
 DOMCI_CLASS(FileRequest)
 DOMCI_CLASS(LockedFile)
 
 DOMCI_CLASS(MozActivity)
 
 DOMCI_CLASS(MozTimeManager)
-
-#ifdef MOZ_WEBRTC
-DOMCI_CLASS(DataChannel)
-#endif
--- a/netwerk/Makefile.in
+++ b/netwerk/Makefile.in
@@ -29,17 +29,16 @@ ifdef MOZ_SRTP
 PARALLEL_DIRS += \
   srtp/src \
   $(NULL)
 endif
 
 ifdef MOZ_SCTP
 PARALLEL_DIRS += \
   sctp/src \
-  sctp/datachannel \
   $(NULL)
 endif
 
 ifdef NECKO_WIFI
 PARALLEL_DIRS += wifi
 endif
 
 PARALLEL_DIRS += locales
--- a/netwerk/build/Makefile.in
+++ b/netwerk/build/Makefile.in
@@ -40,17 +40,16 @@ ifdef MOZ_SRTP
 SHARED_LIBRARY_LIBS += \
   ../srtp/src/$(LIB_PREFIX)nksrtp_s.$(LIB_SUFFIX) \
   $(NULL)
 endif
 
 ifdef MOZ_SCTP
 SHARED_LIBRARY_LIBS += \
   ../sctp/src/$(LIB_PREFIX)nksctp_s.$(LIB_SUFFIX) \
-  ../sctp/datachannel/$(LIB_PREFIX)nkdatachan_s.$(LIB_SUFFIX) \
   $(NULL)
 endif
 
 ifeq ($(OS_ARCH),WINNT)
     SHARED_LIBRARY_LIBS += \
         ../system/win32/$(LIB_PREFIX)neckosystem_s.$(LIB_SUFFIX)
 endif
 
deleted file mode 100644
--- a/netwerk/sctp/datachannel/DataChannel.cpp
+++ /dev/null
@@ -1,1973 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <iostream>
-#if !defined(__Userspace_os_Windows)
-#include <arpa/inet.h>
-#endif
-
-#define SCTP_DEBUG 1
-#define SCTP_STDINT_INCLUDE "mozilla/StandardInteger.h"
-#include "usrsctp.h"
-
-#include "DataChannelLog.h"
-
-#include "nsServiceManagerUtils.h"
-#include "nsIObserverService.h"
-#include "nsIObserver.h"
-#include "mozilla/Services.h"
-#include "nsThreadUtils.h"
-#include "nsAutoPtr.h"
-#include "nsNetUtil.h"
-#ifdef MOZ_PEERCONNECTION
-#include "mtransport/runnable_utils.h"
-#endif
-#include "DataChannel.h"
-#include "DataChannelProtocol.h"
-
-#ifdef PR_LOGGING
-PRLogModuleInfo* dataChannelLog = PR_NewLogModule("DataChannel");
-#endif
-
-static bool sctp_initialized;
-
-namespace mozilla {
-
-class DataChannelShutdown;
-nsCOMPtr<DataChannelShutdown> gDataChannelShutdown;
-
-class DataChannelShutdown : public nsIObserver
-{
-public:
-  // This needs to be tied to some form object that is guaranteed to be
-  // around (singleton likely) unless we want to shutdown sctp whenever
-  // we're not using it (and in which case we'd keep a refcnt'd object
-  // ref'd by each DataChannelConnection to release the SCTP usrlib via
-  // sctp_finish)
-
-  NS_DECL_ISUPPORTS
-
-  DataChannelShutdown() {}
-
-  void Init() 
-    {
-      nsCOMPtr<nsIObserverService> observerService =
-        mozilla::services::GetObserverService();
-      if (!observerService)
-        return;
-
-      nsresult rv = observerService->AddObserver(this,
-                                                 "profile-change-net-teardown",
-                                                 false);
-      MOZ_ASSERT(rv == NS_OK);
-      (void) rv;
-    }
-
-  virtual ~DataChannelShutdown()
-    {
-      nsCOMPtr<nsIObserverService> observerService =
-        mozilla::services::GetObserverService();
-      if (observerService)
-        observerService->RemoveObserver(this, "profile-change-net-teardown");
-    }
-
-  NS_IMETHODIMP Observe(nsISupports* aSubject, const char* aTopic,
-                        const PRUnichar* aData) {
-    if (strcmp(aTopic, "profile-change-net-teardown") == 0) {
-      LOG(("Shutting down SCTP"));
-      if (sctp_initialized) {
-        usrsctp_finish();
-        sctp_initialized = false;
-      }
-    }
-    return NS_OK;
-  }
-};
-
-NS_IMPL_ISUPPORTS1(DataChannelShutdown, nsIObserver);
-
-
-BufferedMsg::BufferedMsg(struct sctp_sendv_spa &spa, const char *data,
-                         uint32_t length) : mLength(length)
-{
-  mSpa = new sctp_sendv_spa;
-  *mSpa = spa;
-  char *tmp = new char[length]; // infallible malloc!
-  memcpy(tmp, data, length);
-  mData = tmp;
-}
-
-BufferedMsg::~BufferedMsg()
-{
-  delete mSpa;
-  delete mData;
-}
-
-static int
-receive_cb(struct socket* sock, union sctp_sockstore addr,
-           void *data, size_t datalen,
-           struct sctp_rcvinfo rcv, int flags, void *ulp_info)
-{
-  DataChannelConnection *connection = static_cast<DataChannelConnection*>(ulp_info);
-  return connection->ReceiveCallback(sock, data, datalen, rcv, flags);
-}
-
-DataChannelConnection::DataChannelConnection(DataConnectionListener *listener) :
-   mLock("netwerk::sctp::DataChannel")
-{
-  mState = CLOSED;
-  mSocket = nullptr;
-  mMasterSocket = nullptr;
-  mListener = listener;
-  mLocalPort = 0;
-  mRemotePort = 0;
-  mDeferTimeout = 10;
-  mTimerRunning = false;
-  LOG(("Constructor DataChannelConnection=%p, listener=%p", this, mListener));
-}
-
-DataChannelConnection::~DataChannelConnection()
-{
-  // XXX Move CloseAll() to a Destroy() call
-  // Though it's probably ok to do this and close the sockets;
-  // if we really want it to do true clean shutdowns it can
-  // create a dependant Internal object that would remain around
-  // until the network shut down the association or timed out.
-  CloseAll();
-  if (mSocket && mSocket != mMasterSocket)
-    usrsctp_close(mSocket);
-  if (mMasterSocket)
-    usrsctp_close(mMasterSocket);
-}
-
-NS_IMPL_THREADSAFE_ISUPPORTS1(DataChannelConnection,
-                              nsITimerCallback)
-
-bool
-DataChannelConnection::Init(unsigned short aPort, uint16_t aNumStreams, bool aUsingDtls)
-{
-  struct sctp_initmsg initmsg;
-  struct sctp_udpencaps encaps;
-  struct sctp_assoc_value av;
-  struct sctp_event event;
-  socklen_t len;
-
-  uint16_t event_types[] = {SCTP_ASSOC_CHANGE,
-                            SCTP_PEER_ADDR_CHANGE,
-                            SCTP_REMOTE_ERROR,
-                            SCTP_SHUTDOWN_EVENT,
-                            SCTP_ADAPTATION_INDICATION,
-                            SCTP_SEND_FAILED_EVENT,
-                            SCTP_STREAM_RESET_EVENT,
-                            SCTP_STREAM_CHANGE_EVENT};
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-
-    // MutexAutoLock lock(mLock); Not needed since we're on mainthread always
-    if (!sctp_initialized) {
-      if (aUsingDtls) {
-        LOG(("sctp_init(DTLS)"));
-#ifdef MOZ_PEERCONNECTION
-        usrsctp_init(0, DataChannelConnection::SctpDtlsOutput);
-#else
-        NS_ASSERTION(!aUsingDtls, "Trying to use SCTP/DTLS without mtransport");
-#endif
-      } else {
-        LOG(("sctp_init(%d)", aPort));
-        usrsctp_init(aPort, nullptr);
-      }
-
-      usrsctp_sysctl_set_sctp_debug_on(0 /* SCTP_DEBUG_ALL */);
-      usrsctp_sysctl_set_sctp_blackhole(2);
-      sctp_initialized = true;
-
-      gDataChannelShutdown = new DataChannelShutdown();
-      gDataChannelShutdown->Init();
-    }
-  }
-
-  // Open sctp association across tunnel
-  if ((mMasterSocket = usrsctp_socket(
-         aUsingDtls ? AF_CONN : AF_INET,
-         SOCK_STREAM, IPPROTO_SCTP, receive_cb, nullptr, 0, this)) == nullptr) {
-    return false;
-  }
-
-  if (!aUsingDtls) {
-    memset(&encaps, 0, sizeof(encaps));
-    encaps.sue_address.ss_family = AF_INET;
-    encaps.sue_port = htons(aPort);
-    if (usrsctp_setsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT,
-                           (const void*)&encaps,
-                           (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
-      LOG(("*** failed encaps errno %d", errno));
-      goto error_cleanup;
-    }
-    LOG(("SCTP encapsulation local port %d", aPort));
-  }
-
-  av.assoc_id = SCTP_ALL_ASSOC;
-  av.assoc_value = SCTP_ENABLE_RESET_STREAM_REQ | SCTP_ENABLE_CHANGE_ASSOC_REQ;
-  if (usrsctp_setsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_ENABLE_STREAM_RESET, &av,
-                         (socklen_t)sizeof(struct sctp_assoc_value)) < 0) {
-    LOG(("*** failed enable stream reset errno %d", errno));
-    goto error_cleanup;
-  }
-
-  /* Enable the events of interest. */
-  memset(&event, 0, sizeof(event));
-  event.se_assoc_id = SCTP_ALL_ASSOC;
-  event.se_on = 1;
-  for (uint32_t i = 0; i < sizeof(event_types)/sizeof(event_types[0]); ++i) {
-    event.se_type = event_types[i];
-    if (usrsctp_setsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_EVENT, &event, sizeof(event)) < 0) {
-      LOG(("*** failed setsockopt SCTP_EVENT errno %d", errno));
-      goto error_cleanup;
-    }
-  }
-
-  // Update number of streams
-  mStreamsOut.AppendElements(aNumStreams);
-  mStreamsIn.AppendElements(aNumStreams); // make sure both are the same length
-  for (uint32_t i = 0; i < aNumStreams; ++i) {
-    mStreamsOut[i] = nullptr;
-    mStreamsIn[i]  = nullptr;
-  }
-  memset(&initmsg, 0, sizeof(initmsg));
-  len = sizeof(initmsg);
-  if (usrsctp_getsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, &len) < 0) {
-    LOG(("*** failed getsockopt SCTP_INITMSG"));
-    goto error_cleanup;
-  }
-  LOG(("Setting number of SCTP streams to %u, was %u/%u", aNumStreams,
-       initmsg.sinit_num_ostreams, initmsg.sinit_max_instreams));
-  initmsg.sinit_num_ostreams  = aNumStreams;
-  initmsg.sinit_max_instreams = MAX_NUM_STREAMS;
-  if (usrsctp_setsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
-                         (socklen_t)sizeof(initmsg)) < 0) {
-    LOG(("*** failed setsockopt SCTP_INITMSG, errno %d", errno));
-    goto error_cleanup;
-  }
-
-  mSocket = nullptr;
-  return true;
-
-error_cleanup:
-  usrsctp_close(mMasterSocket);
-  mMasterSocket = nullptr;
-  return false;
-}
-
-void
-DataChannelConnection::StartDefer()
-{
-  nsresult rv;
-  if (!NS_IsMainThread()) {
-    NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                            DataChannelOnMessageAvailable::START_DEFER,
-                            this, nullptr));
-    return;
-  }
-
-  MOZ_ASSERT(NS_IsMainThread());
-  if (!mDeferredTimer) {
-    mDeferredTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
-    MOZ_ASSERT(mDeferredTimer);
-  }
-
-  if (!mTimerRunning) {
-    rv = mDeferredTimer->InitWithCallback(this, mDeferTimeout,
-                                          nsITimer::TYPE_ONE_SHOT);
-    NS_ENSURE_TRUE(rv == NS_OK, /* */);
-
-    mTimerRunning = true;
-  }
-}
-
-// nsITimerCallback
-
-NS_IMETHODIMP
-DataChannelConnection::Notify(nsITimer *timer)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  LOG(("%s: %p [%p] (%dms), sending deferred messages", __FUNCTION__, this, timer, mDeferTimeout));
-
-  if (timer == mDeferredTimer) {
-    if (SendDeferredMessages()) {
-      // Still blocked
-      // we don't need a lock, since this must be main thread...
-      nsresult rv = mDeferredTimer->InitWithCallback(this, mDeferTimeout,
-                                                     nsITimer::TYPE_ONE_SHOT);
-      if (NS_FAILED(rv)) {
-        LOG(("%s: cannot initialize open timer", __FUNCTION__));
-        // XXX and do....?
-        return rv;
-      }
-      mTimerRunning = true;
-    } else {
-      LOG(("Turned off deferred send timer"));
-      mTimerRunning = false;
-    }
-  }
-  return NS_OK;
-}
-
-#ifdef MOZ_PEERCONNECTION
-bool
-DataChannelConnection::ConnectDTLS(TransportFlow *aFlow, uint16_t localport, uint16_t remoteport)
-{
-  LOG(("Connect DTLS local %d, remote %d", localport, remoteport));
-
-  NS_PRECONDITION(mMasterSocket, "SCTP wasn't initialized before ConnectDTLS!");
-  NS_ENSURE_TRUE(aFlow, false);
-
-  mTransportFlow = aFlow;
-  mTransportFlow->SignalPacketReceived.connect(this, &DataChannelConnection::PacketReceived);
-  mLocalPort = localport;
-  mRemotePort = remoteport;
-
-  PR_CreateThread(
-    PR_SYSTEM_THREAD,
-    DataChannelConnection::DTLSConnectThread, this,
-    PR_PRIORITY_NORMAL,
-    PR_GLOBAL_THREAD,
-    PR_JOINABLE_THREAD, 0
-  );
-
-  return true; // not finished yet
-}
-
-/* static */
-void
-DataChannelConnection::DTLSConnectThread(void *data)
-{
-  DataChannelConnection *_this = static_cast<DataChannelConnection*>(data);
-  struct sockaddr_conn addr;
-
-  memset(&addr, 0, sizeof(addr));
-  addr.sconn_family = AF_CONN;
-#if !defined(__Userspace_os_Linux) && !defined(__Userspace_os_Windows)
-  addr.sconn_len = sizeof(addr);
-#endif
-  addr.sconn_port = htons(_this->mLocalPort);
-
-  int r = usrsctp_bind(_this->mMasterSocket, reinterpret_cast<struct sockaddr *>(&addr),
-                       sizeof(addr));
-  if (r < 0) {
-    LOG(("usrsctp_bind failed: %d", r));
-    return;
-  }
-
-  // This is the remote addr
-  addr.sconn_port = htons(_this->mRemotePort);
-  addr.sconn_addr = static_cast<void *>(_this);
-  r = usrsctp_connect(_this->mMasterSocket, reinterpret_cast<struct sockaddr *>(&addr),
-                      sizeof(addr));
-  if (r < 0) {
-    LOG(("usrsctp_connect failed: %d", r));
-    return;
-  }
-
-  // Notify Connection open
-  LOG(("%s: sending ON_CONNECTION for %p", __FUNCTION__, _this));
-  _this->mSocket = _this->mMasterSocket;
-  _this->mState = OPEN;
-  LOG(("DTLS connect() succeeded!  Entering connected mode"));
-
-  NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                            DataChannelOnMessageAvailable::ON_CONNECTION,
-                            _this, nullptr));
-}
-
-void
-DataChannelConnection::PacketReceived(TransportFlow *flow,
-                                      const unsigned char *data, size_t len)
-{
-  //LOG(("%p: SCTP/DTLS received %ld bytes", this, len));
-
-  // Pass the data to SCTP
-  usrsctp_conninput(static_cast<void *>(this), data, len, 0);
-}
-
-// XXX Merge with SctpDtlsOutput?
-int
-DataChannelConnection::SendPacket(const unsigned char *data, size_t len)
-{
-  //LOG(("%p: SCTP/DTLS sent %ld bytes", this, len));
-  return mTransportFlow->SendPacket(data, len) < 0 ? 1 : 0;
-}
-
-/* static */
-int
-DataChannelConnection::SctpDtlsOutput(void *addr, void *buffer, size_t length,
-                                      uint8_t tos, uint8_t set_df)
-{
-  DataChannelConnection *peer = static_cast<DataChannelConnection *>(addr);
-
-  return peer->SendPacket(static_cast<unsigned char *>(buffer), length);
-}
-#endif
-
-// listen for incoming associations
-// Blocks! - Don't call this from main thread!
-bool
-DataChannelConnection::Listen(unsigned short port)
-{
-  struct sockaddr_in addr;
-  socklen_t addr_len;
-
-  NS_WARN_IF_FALSE(!NS_IsMainThread(), "Blocks, do not call from main thread!!!");
-
-  /* Acting as the 'server' */
-  memset((void *)&addr, 0, sizeof(addr));
-#ifdef HAVE_SIN_LEN
-  addr.sin_len = sizeof(struct sockaddr_in);
-#endif
-  addr.sin_family = AF_INET;
-  addr.sin_port = htons(port);
-  addr.sin_addr.s_addr = htonl(INADDR_ANY);
-  LOG(("Waiting for connections on port %d", ntohs(addr.sin_port)));
-  mState = CONNECTING;
-  if (usrsctp_bind(mMasterSocket, reinterpret_cast<struct sockaddr *>(&addr), sizeof(struct sockaddr_in)) < 0) {
-    LOG(("***Failed userspace_bind"));
-    return false;
-  }
-  if (usrsctp_listen(mMasterSocket, 1) < 0) {
-    LOG(("***Failed userspace_listen"));
-    return false;
-  }
-
-  LOG(("Accepting connection"));
-  addr_len = 0;
-  if ((mSocket = usrsctp_accept(mMasterSocket, nullptr, &addr_len)) == nullptr) {
-    LOG(("***Failed accept"));
-    return false;
-  }
-  mState = OPEN;
-
-  // Notify Connection open
-  // XXX We need to make sure connection sticks around until the message is delivered
-  LOG(("%s: sending ON_CONNECTION for %p", __FUNCTION__, this));
-  NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                            DataChannelOnMessageAvailable::ON_CONNECTION,
-                            this, nullptr));
-  return true;
-}
-
-// Blocks! - Don't call this from main thread!
-bool
-DataChannelConnection::Connect(const char *addr, unsigned short port)
-{
-  struct sockaddr_in addr4;
-  struct sockaddr_in6 addr6;
-
-  NS_WARN_IF_FALSE(!NS_IsMainThread(), "Blocks, do not call from main thread!!!");
-
-  /* Acting as the connector */
-  LOG(("Connecting to %s, port %u", addr, port));
-  memset((void *)&addr4, 0, sizeof(struct sockaddr_in));
-  memset((void *)&addr6, 0, sizeof(struct sockaddr_in6));
-#ifdef HAVE_SIN_LEN
-  addr4.sin_len = sizeof(struct sockaddr_in);
-#endif
-#ifdef HAVE_SIN6_LEN
-  addr6.sin6_len = sizeof(struct sockaddr_in6);
-#endif
-  addr4.sin_family = AF_INET;
-  addr6.sin6_family = AF_INET6;
-  addr4.sin_port = htons(port);
-  addr6.sin6_port = htons(port);
-  mState = CONNECTING;
-
-#if !defined(__Userspace_os_Windows)
-  if (inet_pton(AF_INET6, addr, &addr6.sin6_addr) == 1) {
-    if (usrsctp_connect(mMasterSocket, reinterpret_cast<struct sockaddr *>(&addr6), sizeof(struct sockaddr_in6)) < 0) {
-      LOG(("*** Failed userspace_connect"));
-      return false;
-    }
-  } else if (inet_pton(AF_INET, addr, &addr4.sin_addr) == 1) {
-    if (usrsctp_connect(mMasterSocket, reinterpret_cast<struct sockaddr *>(&addr4), sizeof(struct sockaddr_in)) < 0) {
-      LOG(("*** Failed userspace_connect"));
-      return false;
-    }
-  } else {
-    LOG(("*** Illegal destination address."));
-  }
-#else
-  {
-    struct sockaddr_storage ss;
-    int sslen = sizeof(ss);
-
-    if (!WSAStringToAddressA(const_cast<char *>(addr), AF_INET6, nullptr, (struct sockaddr*)&ss, &sslen)) {
-      addr6.sin6_addr = (reinterpret_cast<struct sockaddr_in6 *>(&ss))->sin6_addr;
-      if (usrsctp_connect(mMasterSocket, reinterpret_cast<struct sockaddr *>(&addr6), sizeof(struct sockaddr_in6)) < 0) {
-        LOG(("*** Failed userspace_connect"));
-        return false;
-      }
-    } else if (!WSAStringToAddressA(const_cast<char *>(addr), AF_INET, nullptr, (struct sockaddr*)&ss, &sslen)) {
-      addr4.sin_addr = (reinterpret_cast<struct sockaddr_in *>(&ss))->sin_addr;
-      if (usrsctp_connect(mMasterSocket, reinterpret_cast<struct sockaddr *>(&addr4), sizeof(struct sockaddr_in)) < 0) {
-        LOG(("*** Failed userspace_connect"));
-        return false;
-      }
-    } else {
-      LOG(("*** Illegal destination address."));
-    }
-  }
-#endif
-
-  mSocket = mMasterSocket;
-
-  LOG(("connect() succeeded!  Entering connected mode"));
-  mState = OPEN;
-
-  // Notify Connection open
-  // XXX We need to make sure connection sticks around until the message is delivered
-  LOG(("%s: sending ON_CONNECTION for %p", __FUNCTION__, this));
-  NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                            DataChannelOnMessageAvailable::ON_CONNECTION,
-                            this, nullptr));
-  return true;
-}
-
-DataChannel *
-DataChannelConnection::FindChannelByStreamIn(uint16_t streamIn)
-{
-  // Auto-extend mStreamsIn as needed
-  if (((uint32_t) streamIn) + 1 > mStreamsIn.Length()) {
-    uint32_t old_len = mStreamsIn.Length();
-    LOG(("Extending mStreamsIn[] to %d elements", ((int32_t) streamIn)+1));
-    mStreamsIn.AppendElements((streamIn+1) - mStreamsIn.Length());
-    for (uint32_t i = old_len; i < mStreamsIn.Length(); ++i)
-      mStreamsIn[i] = nullptr;
-  }
-  // Should always be safe in practice
-  return mStreamsIn.SafeElementAt(streamIn);
-}
-
-DataChannel *
-DataChannelConnection::FindChannelByStreamOut(uint16_t streamOut)
-{
-  return mStreamsOut.SafeElementAt(streamOut);
-}
-
-uint16_t
-DataChannelConnection::FindFreeStreamOut()
-{
-  uint32_t i, limit;
-
-  limit = mStreamsOut.Length();
-  if (limit > MAX_NUM_STREAMS)
-    limit = MAX_NUM_STREAMS;
-  for (i = 0; i < limit; ++i) {
-    if (!mStreamsOut[i]) {
-      break;
-    }
-  }
-  if (i == limit) {
-    return INVALID_STREAM;
-  }
-  return i;
-}
-
-bool
-DataChannelConnection::RequestMoreStreamsOut(int32_t aNeeded)
-{
-  struct sctp_status status;
-  struct sctp_add_streams sas;
-  uint32_t outStreamsNeeded;
-  socklen_t len;
-
-  if (aNeeded + mStreamsOut.Length() > MAX_NUM_STREAMS)
-    aNeeded = MAX_NUM_STREAMS - mStreamsOut.Length();
-  if (aNeeded <= 0)
-    return false;
-
-  len = (socklen_t)sizeof(struct sctp_status);
-  if (usrsctp_getsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_STATUS, &status, &len) < 0) {
-    LOG(("***failed: getsockopt SCTP_STATUS"));
-    return false;
-  }
-  outStreamsNeeded = aNeeded; // number to add
-
-  memset(&sas, 0, sizeof(struct sctp_add_streams));
-  sas.sas_instrms = 0;
-  sas.sas_outstrms = (uint16_t)outStreamsNeeded; /* XXX error handling */
-  // Doesn't block, we get an event when it succeeds or fails
-  if (usrsctp_setsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_ADD_STREAMS, &sas,
-                         (socklen_t) sizeof(struct sctp_add_streams)) < 0) {
-    if (errno == EALREADY)
-      return true;
-
-    LOG(("***failed: setsockopt ADD errno=%d", errno));
-    return false;
-  }
-  LOG(("Requested %u more streams", outStreamsNeeded));
-  return true;
-}
-
-int32_t
-DataChannelConnection::SendControlMessage(void *msg, uint32_t len, uint16_t streamOut)
-{
-  struct sctp_sndinfo sndinfo;
-
-  // Note: Main-thread IO, but doesn't block
-  memset(&sndinfo, 0, sizeof(struct sctp_sndinfo));
-  sndinfo.snd_sid = streamOut;
-  sndinfo.snd_ppid = htonl(DATA_CHANNEL_PPID_CONTROL);
-  if (usrsctp_sendv(mSocket, msg, len, nullptr, 0,
-                    &sndinfo, (socklen_t)sizeof(struct sctp_sndinfo),
-                    SCTP_SENDV_SNDINFO, 0) < 0) {
-    //LOG(("***failed: sctp_sendv")); don't log because errno is a return!
-    return (0);
-  }
-  return (1);
-}
-
-int32_t
-DataChannelConnection::SendOpenResponseMessage(uint16_t streamOut, uint16_t streamIn)
-{
-  struct rtcweb_datachannel_open_response rsp;
-
-  memset(&rsp, 0, sizeof(struct rtcweb_datachannel_open_response));
-  rsp.msg_type = DATA_CHANNEL_OPEN_RESPONSE;
-  rsp.reverse_stream = htons(streamIn);
-
-  return SendControlMessage(&rsp, sizeof(rsp), streamOut);
-}
-
-
-int32_t
-DataChannelConnection::SendOpenAckMessage(uint16_t streamOut)
-{
-  struct rtcweb_datachannel_ack ack;
-
-  memset(&ack, 0, sizeof(struct rtcweb_datachannel_ack));
-  ack.msg_type = DATA_CHANNEL_ACK;
-
-  return SendControlMessage(&ack, sizeof(ack), streamOut);
-}
-
-int32_t
-DataChannelConnection::SendOpenRequestMessage(const nsACString& label,
-                                              uint16_t streamOut, bool unordered,
-                                              uint16_t prPolicy, uint32_t prValue)
-{
-  int len = label.Length(); // not including nul
-  struct rtcweb_datachannel_open_request *req =
-    (struct rtcweb_datachannel_open_request*) moz_xmalloc(sizeof(*req)+len);
-   // careful - ok because request includes 1 char label
-
-  memset(req, 0, sizeof(struct rtcweb_datachannel_open_request));
-  req->msg_type = DATA_CHANNEL_OPEN_REQUEST;
-  switch (prPolicy) {
-  case SCTP_PR_SCTP_NONE:
-    req->channel_type = DATA_CHANNEL_RELIABLE;
-    break;
-  case SCTP_PR_SCTP_TTL:
-    req->channel_type = DATA_CHANNEL_PARTIAL_RELIABLE_TIMED;
-    break;
-  case SCTP_PR_SCTP_RTX:
-    req->channel_type = DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT;
-    break;
-  default:
-    // FIX! need to set errno!  Or make all these SendXxxx() funcs return 0 or errno!
-    moz_free(req);
-    return (0);
-  }
-  req->flags = htons(0);
-  if (unordered) {
-    req->flags |= htons(DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED);
-  }
-  req->reliability_params = htons((uint16_t)prValue); /* XXX Why 16-bit */
-  req->priority = htons(0); /* XXX: add support */
-  strcpy(&req->label[0], PromiseFlatCString(label).get());
-
-  int32_t result = SendControlMessage(req, sizeof(*req)+len, streamOut);
-
-  moz_free(req);
-  return result;
-}
-
-// XXX This should use a separate thread (outbound queue) which should
-// select() to know when to *try* to send data to the socket again.
-// Alternatively, it can use a timeout, but that's guaranteed to be wrong
-// (just not sure in what direction).  We could re-implement NSPR's
-// PR_POLL_WRITE/etc handling... with a lot of work.
-
-// returns if we're still blocked or not
-bool
-DataChannelConnection::SendDeferredMessages()
-{
-  uint32_t i;
-  DataChannel *channel;
-  bool still_blocked = false;
-  bool sent = false;
-
-  // This may block while something is modifying channels, but should not block for IO
-  MutexAutoLock lock(mLock);
-
-  // XXX For total fairness, on a still_blocked we'd start next time at the
-  // same index.  Sorry, not going to bother for now.
-  for (i = 0; i < mStreamsOut.Length(); ++i) {
-    channel = mStreamsOut[i];
-    if (!channel)
-      continue;
-
-    // Only one of these should be set....
-    if (channel->mFlags & DATA_CHANNEL_FLAGS_SEND_REQ) {
-      if (SendOpenRequestMessage(channel->mLabel, channel->mStreamOut,
-                                 channel->mFlags & DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED,
-                                 channel->mPrPolicy, channel->mPrValue)) {
-        channel->mFlags &= ~DATA_CHANNEL_FLAGS_SEND_REQ;
-        sent = true;
-      } else {
-        if (errno == EAGAIN) {
-          still_blocked = true;
-        } else {
-          // Close the channel, inform the user
-          mStreamsOut[channel->mStreamOut] = nullptr;
-          channel->mState = CLOSED;
-          // Don't need to reset; we didn't open it
-          NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                                    DataChannelOnMessageAvailable::ON_CHANNEL_CLOSED, this,
-                                    channel));
-        }
-      }
-    }
-    if (still_blocked)
-      break;
-
-    if (channel->mFlags & DATA_CHANNEL_FLAGS_SEND_RSP) {
-      if (SendOpenResponseMessage(channel->mStreamOut, channel->mStreamIn)) {
-        channel->mFlags &= ~DATA_CHANNEL_FLAGS_SEND_RSP;
-        sent = true;
-      } else {
-        if (errno == EAGAIN) {
-          still_blocked = true;
-        } else {
-          // Close the channel
-          // Don't need to reset; we didn't open it
-          // The other side may be left with a hanging Open.  Our inability to
-          // send the open response means we can't easily tell them about it
-          // We haven't informed the user/DOM of the creation yet, so just
-          // delete the channel.
-          mStreamsIn[channel->mStreamIn]   = nullptr;
-          mStreamsOut[channel->mStreamOut] = nullptr;
-          delete channel;
-        }
-      }
-    }
-    if (still_blocked)
-      break;
-
-    if (channel->mFlags & DATA_CHANNEL_FLAGS_SEND_ACK) {
-      if (SendOpenAckMessage(channel->mStreamOut)) {
-        channel->mFlags &= ~DATA_CHANNEL_FLAGS_SEND_ACK;
-        sent = true;
-      } else {
-        if (errno == EAGAIN) {
-          still_blocked = true;
-        } else {
-          // Close the channel, inform the user
-          Close(channel->mStreamOut);
-        }
-      }
-    }
-    if (still_blocked)
-      break;
-
-    if (channel->mFlags & DATA_CHANNEL_FLAGS_SEND_DATA) {
-      bool failed_send = false;
-      int32_t result;
-
-      if (channel->mState == CLOSED || channel->mState == CLOSING) {
-        channel->mBufferedData.Clear();
-      }
-      while (!channel->mBufferedData.IsEmpty() &&
-             !failed_send) {
-        struct sctp_sendv_spa *spa = channel->mBufferedData[0]->mSpa;
-        const char *data           = channel->mBufferedData[0]->mData;
-        uint32_t len               = channel->mBufferedData[0]->mLength;
-
-        // SCTP will return EMSGSIZE if the message is bigger than the buffer
-        // size (or EAGAIN if there isn't space)
-        if ((result = usrsctp_sendv(mSocket, data, len,
-                                    nullptr, 0,
-                                    (void *)spa, (socklen_t)sizeof(struct sctp_sendv_spa),
-                                    SCTP_SENDV_SPA,
-                                    spa->sendv_sndinfo.snd_flags) < 0)) {
-          if (errno == EAGAIN) {
-            // leave queued for resend
-            failed_send = true;
-            LOG(("queue full again when resending %d bytes (%d)", len, result));
-          } else {
-            LOG(("error %d re-sending string", errno));
-            failed_send = true;
-          }
-        } else {
-          LOG(("Resent buffer of %d bytes (%d)", len, result));
-          sent = true;
-          channel->mBufferedData.RemoveElementAt(0);
-        }
-      }
-      if (channel->mBufferedData.IsEmpty())
-        channel->mFlags &= ~DATA_CHANNEL_FLAGS_SEND_DATA;
-      else
-        still_blocked = true;
-    }
-    if (still_blocked)
-      break;
-  }
-
-  if (!still_blocked) {
-    // mDeferTimeout becomes an estimate of how long we need to wait next time we block
-    return false;
-  }
-  // adjust time?  More time for next wait if we didn't send anything, less if did
-  // Pretty crude, but better than nothing; just to keep CPU use down
-  if (!sent && mDeferTimeout < 50)
-    mDeferTimeout++;
-  else if (sent && mDeferTimeout > 10)
-    mDeferTimeout--;
-
-  return true;
-}
-
-void
-DataChannelConnection::HandleOpenRequestMessage(const struct rtcweb_datachannel_open_request *req,
-                                                size_t length,
-                                                uint16_t streamIn)
-{
-  DataChannel *channel;
-  uint32_t prValue;
-  uint16_t prPolicy;
-  uint32_t flags;
-  nsCString label(nsDependentCString(req->label));
-
-  mLock.AssertCurrentThreadOwns();
-
-  if ((channel = FindChannelByStreamIn(streamIn))) {
-    LOG(("ERROR: HandleOpenRequestMessage: channel for stream %d is in state %d instead of CLOSED.",
-         streamIn, channel->mState));
-    /* XXX: some error handling */
-    return;
-  }
-  switch (req->channel_type) {
-    case DATA_CHANNEL_RELIABLE:
-      prPolicy = SCTP_PR_SCTP_NONE;
-      break;
-    case DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT:
-      prPolicy = SCTP_PR_SCTP_RTX;
-      break;
-    case DATA_CHANNEL_PARTIAL_RELIABLE_TIMED:
-      prPolicy = SCTP_PR_SCTP_TTL;
-      break;
-    default:
-      /* XXX error handling */
-      return;
-  }
-  prValue = ntohs(req->reliability_params);
-  flags = ntohs(req->flags) & DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED;
-  channel = new DataChannel(this, INVALID_STREAM, streamIn,
-                            DataChannel::CONNECTING,
-                            label,
-                            prPolicy, prValue,
-                            flags,
-                            nullptr, nullptr);
-  mStreamsIn[streamIn] = channel;
-
-  OpenResponseFinish(channel);
-}
-
-void
-DataChannelConnection::OpenResponseFinish(DataChannel *channel)
-{
-  uint16_t streamOut = FindFreeStreamOut(); // may be INVALID_STREAM!
-
-  mLock.AssertCurrentThreadOwns();
-
-  LOG(("Finished response: channel %p, streamOut = %u", channel, streamOut));
-
-  if (streamOut == INVALID_STREAM) {
-    if (!RequestMoreStreamsOut()) {
-      /* XXX: Signal error to the other end. */
-      mStreamsIn[channel->mStreamIn] = nullptr;
-      // we can do this with the lock held because mStreamOut is INVALID_STREAM,
-      // so there's no outbound channel to reset
-      delete channel;
-      return;
-    }
-    LOG(("Queuing channel %p to finish response", channel));
-    channel->mFlags |= DATA_CHANNEL_FLAGS_FINISH_RSP;
-    mPending.Push(channel);
-    // can't notify the user until we can send an OpenResponse
-  } else {
-    channel->mStreamOut = streamOut;
-    mStreamsOut[streamOut] = channel;
-    if (SendOpenResponseMessage(streamOut, channel->mStreamIn)) {
-      LOG(("successful incoming open of '%s' in: %u, out: %u\n",
-           channel->mLabel.get(), channel->mStreamIn, streamOut));
-
-      /* Notify ondatachannel */
-      // XXX We need to make sure connection sticks around until the message is delivered
-      LOG(("%s: sending ON_CHANNEL_CREATED for %p", __FUNCTION__, channel));
-      NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                                DataChannelOnMessageAvailable::ON_CHANNEL_CREATED,
-                                this, channel));
-    } else {
-      if (errno == EAGAIN) {
-        channel->mFlags |= DATA_CHANNEL_FLAGS_SEND_RSP;
-        StartDefer();
-      } else {
-        /* XXX: Signal error to the other end. */
-        mStreamsIn[channel->mStreamIn] = nullptr;
-        mStreamsOut[streamOut] = nullptr;
-        channel->mStreamOut = INVALID_STREAM;
-        // we can do this with the lock held because mStreamOut is INVALID_STREAM,
-        // so there's no outbound channel to reset (we failed to send on it)
-        delete channel;
-        return; // paranoia against future changes since we unlocked
-      }
-    }
-  }
-}
-
-
-void
-DataChannelConnection::HandleOpenResponseMessage(const struct rtcweb_datachannel_open_response *rsp,
-                                                 size_t length, uint16_t streamIn)
-{
-  uint16_t streamOut;
-  DataChannel *channel;
-
-  mLock.AssertCurrentThreadOwns();
-
-  streamOut = ntohs(rsp->reverse_stream);
-  channel = FindChannelByStreamOut(streamOut);
-
-  NS_ENSURE_TRUE(channel != nullptr, /* */);
-  NS_ENSURE_TRUE(channel->mState == CONNECTING, /* */);
-
-  if (rsp->error) {
-    LOG(("%s: error in response to open of channel %d (%s)",
-         __FUNCTION__, streamOut, channel->mLabel.get()));
-
-  } else {
-    NS_ENSURE_TRUE(!FindChannelByStreamIn(streamIn), /* */);
-
-    channel->mStreamIn = streamIn;
-    channel->mState = OPEN;
-    channel->mReady = true;
-    mStreamsIn[streamIn] = channel;
-    if (SendOpenAckMessage(streamOut)) {
-      channel->mFlags = 0;
-    } else {
-      // XXX Only on EAGAIN!?  And if not, then close the channel??
-      channel->mFlags |= DATA_CHANNEL_FLAGS_SEND_ACK;
-      StartDefer();
-    }
-    LOG(("%s: sending ON_CHANNEL_OPEN for %p", __FUNCTION__, channel));
-    NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                              DataChannelOnMessageAvailable::ON_CHANNEL_OPEN, this,
-                              channel));
-  }
-}
-
-void
-DataChannelConnection::HandleOpenAckMessage(const struct rtcweb_datachannel_ack *ack,
-                                            size_t length, uint16_t streamIn)
-{
-  DataChannel *channel;
-
-  mLock.AssertCurrentThreadOwns();
-
-  channel = FindChannelByStreamIn(streamIn);
-
-  NS_ENSURE_TRUE(channel != nullptr, /* */);
-  NS_ENSURE_TRUE(channel->mState == CONNECTING, /* */);
-
-  channel->mState = channel->mReady ? DataChannel::OPEN : DataChannel::WAITING_TO_OPEN;
-  if (channel->mState == OPEN) {
-    LOG(("%s: sending ON_CHANNEL_OPEN for %p", __FUNCTION__, channel));
-    NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                              DataChannelOnMessageAvailable::ON_CHANNEL_OPEN, this,
-                              channel));
-  } else {
-    LOG(("%s: deferring sending ON_CHANNEL_OPEN for %p", __FUNCTION__, channel));
-  }
-}
-
-void
-DataChannelConnection::HandleUnknownMessage(uint32_t ppid, size_t length, uint16_t streamIn)
-{
-  /* XXX: Send an error message? */
-  LOG(("unknown DataChannel message received: %u, len %ld on stream %lu", ppid, length, streamIn));
-  // XXX Log to JS error console if possible
-}
-
-void
-DataChannelConnection::HandleDataMessage(uint32_t ppid,
-                                         const void *data, size_t length,
-                                         uint16_t streamIn)
-{
-  DataChannel *channel;
-  const char *buffer = (const char *) data;
-
-  mLock.AssertCurrentThreadOwns();
-
-  channel = FindChannelByStreamIn(streamIn);
-
-  // XXX A closed channel may trip this... check
-  NS_ENSURE_TRUE(channel != nullptr, /* */);
-  NS_ENSURE_TRUE(channel->mState != CONNECTING, /* */);
-
-  // XXX should this be a simple if, no warnings/debugbreaks?
-  NS_ENSURE_TRUE(channel->mState != CLOSED, /* */);
-
-  {
-    nsAutoCString recvData(buffer, length);
-
-    switch (ppid) {
-      case DATA_CHANNEL_PPID_DOMSTRING:
-        LOG(("DataChannel: String message received of length %lu on channel %d: %.*s",
-             length, channel->mStreamOut, (int)PR_MIN(length, 80), buffer));
-        length = -1; // Flag for DOMString
-
-        // WebSockets checks IsUTF8() here; we can try to deliver it
-
-        NS_WARN_IF_FALSE(channel->mBinaryBuffer.IsEmpty(), "Binary message aborted by text message!");
-        if (!channel->mBinaryBuffer.IsEmpty())
-          channel->mBinaryBuffer.Truncate(0);
-        break;
-
-      case DATA_CHANNEL_PPID_BINARY:
-        channel->mBinaryBuffer += recvData;
-        LOG(("DataChannel: Received binary message of length %lu (total %u) on channel id %d",
-             length, channel->mBinaryBuffer.Length(), channel->mStreamOut));
-        return; // Not ready to notify application
-
-      case DATA_CHANNEL_PPID_BINARY_LAST:
-        LOG(("DataChannel: Received binary message of length %lu on channel id %d",
-             length, channel->mStreamOut));
-        if (!channel->mBinaryBuffer.IsEmpty()) {
-          channel->mBinaryBuffer += recvData;
-          LOG(("%s: sending ON_DATA (binary fragmented) for %p", __FUNCTION__, channel));
-          SendOrQueue(channel,
-                      new DataChannelOnMessageAvailable(
-                        DataChannelOnMessageAvailable::ON_DATA, this,
-                        channel, channel->mBinaryBuffer,
-                        channel->mBinaryBuffer.Length()));
-          channel->mBinaryBuffer.Truncate(0);
-          return;
-        }
-        // else send using recvData normally
-        break;
-
-      default:
-        NS_ERROR("Unknown data PPID");
-        return;
-    }
-    /* Notify onmessage */
-    LOG(("%s: sending ON_DATA for %p", __FUNCTION__, channel));
-    SendOrQueue(channel,
-                new DataChannelOnMessageAvailable(
-                  DataChannelOnMessageAvailable::ON_DATA, this,
-                  channel, recvData, length));
-  }
-}
-
-// Called with mLock locked!
-void
-DataChannelConnection::SendOrQueue(DataChannel *aChannel, 
-                                   DataChannelOnMessageAvailable *aMessage)
-{
-  mLock.AssertCurrentThreadOwns();
-
-  if (!aChannel->mReady &&
-      (aChannel->mState == DataChannel::CONNECTING || 
-       aChannel->mState == DataChannel::WAITING_TO_OPEN)) {
-    aChannel->mQueuedMessages.AppendElement(aMessage);
-  } else {
-    NS_DispatchToMainThread(aMessage);
-  }
-}
-
-// Called with mLock locked!
-void
-DataChannelConnection::HandleMessage(const void *buffer, size_t length, uint32_t ppid, uint16_t streamIn)
-{
-  const struct rtcweb_datachannel_open_request *req;
-  const struct rtcweb_datachannel_open_response *rsp;
-  const struct rtcweb_datachannel_ack *ack, *msg;
-
-  mLock.AssertCurrentThreadOwns();
-
-  switch (ppid) {
-    case DATA_CHANNEL_PPID_CONTROL:
-      NS_ENSURE_TRUE(length >= sizeof(*ack), /* */); // Ack is the smallest
-
-      msg = static_cast<const struct rtcweb_datachannel_ack *>(buffer);
-      switch (msg->msg_type) {
-        case DATA_CHANNEL_OPEN_REQUEST:
-          LOG(("length %u, sizeof(*req) = %u", length, sizeof(*req)));
-          NS_ENSURE_TRUE(length >= sizeof(*req), /* */);
-
-          req = static_cast<const struct rtcweb_datachannel_open_request *>(buffer);
-          HandleOpenRequestMessage(req, length, streamIn);
-          break;
-        case DATA_CHANNEL_OPEN_RESPONSE:
-          NS_ENSURE_TRUE(length >= sizeof(*rsp), /* */);
-
-          rsp = static_cast<const struct rtcweb_datachannel_open_response *>(buffer);
-          HandleOpenResponseMessage(rsp, length, streamIn);
-          break;
-        case DATA_CHANNEL_ACK:
-          // >= sizeof(*ack) checked above
-
-          ack = static_cast<const struct rtcweb_datachannel_ack *>(buffer);
-          HandleOpenAckMessage(ack, length, streamIn);
-          break;
-        default:
-          HandleUnknownMessage(ppid, length, streamIn);
-          break;
-      }
-      break;
-    case DATA_CHANNEL_PPID_DOMSTRING:
-    case DATA_CHANNEL_PPID_BINARY:
-    case DATA_CHANNEL_PPID_BINARY_LAST:
-      HandleDataMessage(ppid, buffer, length, streamIn);
-      break;
-    default:
-      LOG(("Message of length %lu, PPID %u on stream %u received.",
-           length, ppid, streamIn));
-      break;
-  }
-}
-
-void
-DataChannelConnection::HandleAssociationChangeEvent(const struct sctp_assoc_change *sac)
-{
-  uint32_t i, n;
-
-  switch (sac->sac_state) {
-  case SCTP_COMM_UP:
-    LOG(("Association change: SCTP_COMM_UP"));
-    break;
-  case SCTP_COMM_LOST:
-    LOG(("Association change: SCTP_COMM_LOST"));
-    break;
-  case SCTP_RESTART:
-    LOG(("Association change: SCTP_RESTART"));
-    break;
-  case SCTP_SHUTDOWN_COMP:
-    LOG(("Association change: SCTP_SHUTDOWN_COMP"));
-    break;
-  case SCTP_CANT_STR_ASSOC:
-    LOG(("Association change: SCTP_CANT_STR_ASSOC"));
-    break;
-  default:
-    LOG(("Association change: UNKNOWN"));
-    break;
-  }
-  LOG(("Association change: streams (in/out) = (%u/%u)",
-       sac->sac_inbound_streams, sac->sac_outbound_streams));
-
-  NS_ENSURE_TRUE(sizeof(*sac) >= sac->sac_length, /* */);
-  n = sac->sac_length - sizeof(*sac);
-  if (((sac->sac_state == SCTP_COMM_UP) ||
-        (sac->sac_state == SCTP_RESTART)) && (n > 0)) {
-    for (i = 0; i < n; ++i) {
-      switch (sac->sac_info[i]) {
-      case SCTP_ASSOC_SUPPORTS_PR:
-        LOG(("Supports: PR"));
-        break;
-      case SCTP_ASSOC_SUPPORTS_AUTH:
-        LOG(("Supports: AUTH"));
-        break;
-      case SCTP_ASSOC_SUPPORTS_ASCONF:
-        LOG(("Supports: ASCONF"));
-        break;
-      case SCTP_ASSOC_SUPPORTS_MULTIBUF:
-        LOG(("Supports: MULTIBUF"));
-        break;
-      case SCTP_ASSOC_SUPPORTS_RE_CONFIG:
-        LOG(("Supports: RE-CONFIG"));
-        break;
-      default:
-        LOG(("Supports: UNKNOWN(0x%02x)", sac->sac_info[i]));
-        break;
-      }
-    }
-  } else if (((sac->sac_state == SCTP_COMM_LOST) ||
-              (sac->sac_state == SCTP_CANT_STR_ASSOC)) && (n > 0)) {
-    LOG(("Association: ABORT ="));
-    for (i = 0; i < n; ++i) {
-      LOG((" 0x%02x", sac->sac_info[i]));
-    }
-  }
-  if ((sac->sac_state == SCTP_CANT_STR_ASSOC) ||
-      (sac->sac_state == SCTP_SHUTDOWN_COMP) ||
-      (sac->sac_state == SCTP_COMM_LOST)) {
-    return;
-  }
-}
-
-void
-DataChannelConnection::HandlePeerAddressChangeEvent(const struct sctp_paddr_change *spc)
-{
-  char addr_buf[INET6_ADDRSTRLEN];
-  const char *addr = "";
-  struct sockaddr_in *sin;
-  struct sockaddr_in6 *sin6;
-#if defined(__Userspace_os_Windows)
-  DWORD addr_len = INET6_ADDRSTRLEN;
-#endif
-
-  switch (spc->spc_aaddr.ss_family) {
-  case AF_INET:
-    sin = (struct sockaddr_in *)&spc->spc_aaddr;
-#if !defined(__Userspace_os_Windows)
-    addr = inet_ntop(AF_INET, &sin->sin_addr, addr_buf, INET6_ADDRSTRLEN);
-#else
-    if (WSAAddressToStringA((LPSOCKADDR)sin, sizeof(sin->sin_addr), nullptr,
-                            addr_buf, &addr_len)) {
-      return;
-    }
-#endif
-    break;
-  case AF_INET6:
-    sin6 = (struct sockaddr_in6 *)&spc->spc_aaddr;
-#if !defined(__Userspace_os_Windows)
-    addr = inet_ntop(AF_INET6, &sin6->sin6_addr, addr_buf, INET6_ADDRSTRLEN);
-#else
-    if (WSAAddressToStringA((LPSOCKADDR)sin6, sizeof(sin6), nullptr,
-                            addr_buf, &addr_len)) {
-      return;
-    }
-#endif
-  case AF_CONN:
-    addr = "DTLS connection";
-    break;
-  default:
-    break;
-  }
-  LOG(("Peer address %s is now ", addr));
-  switch (spc->spc_state) {
-  case SCTP_ADDR_AVAILABLE:
-    LOG(("SCTP_ADDR_AVAILABLE"));
-    break;
-  case SCTP_ADDR_UNREACHABLE:
-    LOG(("SCTP_ADDR_UNREACHABLE"));
-    break;
-  case SCTP_ADDR_REMOVED:
-    LOG(("SCTP_ADDR_REMOVED"));
-    break;
-  case SCTP_ADDR_ADDED:
-    LOG(("SCTP_ADDR_ADDED"));
-    break;
-  case SCTP_ADDR_MADE_PRIM:
-    LOG(("SCTP_ADDR_MADE_PRIM"));
-    break;
-  case SCTP_ADDR_CONFIRMED:
-    LOG(("SCTP_ADDR_CONFIRMED"));
-    break;
-  default:
-    LOG(("UNKNOWN"));
-    break;
-  }
-  LOG((" (error = 0x%08x).\n", spc->spc_error));
-}
-
-void
-DataChannelConnection::HandleRemoteErrorEvent(const struct sctp_remote_error *sre)
-{
-  size_t i, n;
-
-  n = sre->sre_length - sizeof(struct sctp_remote_error);
-  LOG(("Remote Error (error = 0x%04x): ", sre->sre_error));
-  for (i = 0; i < n; ++i) {
-    LOG((" 0x%02x", sre-> sre_data[i]));
-  }
-}
-
-void
-DataChannelConnection::HandleShutdownEvent(const struct sctp_shutdown_event *sse)
-{
-  LOG(("Shutdown event."));
-  /* XXX: notify all channels. */
-  // Attempts to actually send anything will fail
-}
-
-void
-DataChannelConnection::HandleAdaptationIndication(const struct sctp_adaptation_event *sai)
-{
-  LOG(("Adaptation indication: %x.", sai-> sai_adaptation_ind));
-}
-
-void
-DataChannelConnection::HandleSendFailedEvent(const struct sctp_send_failed_event *ssfe)
-{
-  size_t i, n;
-
-  if (ssfe->ssfe_flags & SCTP_DATA_UNSENT) {
-    LOG(("Unsent "));
-  }
-   if (ssfe->ssfe_flags & SCTP_DATA_SENT) {
-    LOG(("Sent "));
-  }
-  if (ssfe->ssfe_flags & ~(SCTP_DATA_SENT | SCTP_DATA_UNSENT)) {
-    LOG(("(flags = %x) ", ssfe->ssfe_flags));
-  }
-  LOG(("message with PPID = %d, SID = %d, flags: 0x%04x due to error = 0x%08x",
-       ntohl(ssfe->ssfe_info.snd_ppid), ssfe->ssfe_info.snd_sid,
-       ssfe->ssfe_info.snd_flags, ssfe->ssfe_error));
-  n = ssfe->ssfe_length - sizeof(struct sctp_send_failed_event);
-  for (i = 0; i < n; ++i) {
-    LOG((" 0x%02x", ssfe->ssfe_data[i]));
-  }
-}
-
-void
-DataChannelConnection::ResetOutgoingStream(uint16_t streamOut)
-{
-  uint32_t i;
-
-  mLock.AssertCurrentThreadOwns();
-  // Rarely has more than a couple items and only for a short time
-  for (i = 0; i < mStreamsResetting.Length(); ++i) {
-    if (mStreamsResetting[i] == streamOut) {
-      return;
-    }
-  }
-  mStreamsResetting.AppendElement(streamOut);
-}
-
-void
-DataChannelConnection::SendOutgoingStreamReset()
-{
-  struct sctp_reset_streams *srs;
-  uint32_t i;
-  size_t len;
-
-  mLock.AssertCurrentThreadOwns();
-  if (mStreamsResetting.IsEmpty() == 0) {
-    return;
-  }
-  len = sizeof(sctp_assoc_t) + (2 + mStreamsResetting.Length()) * sizeof(uint16_t);
-  srs = static_cast<struct sctp_reset_streams *> (moz_xmalloc(len)); // infallible malloc
-  memset(srs, 0, len);
-  srs->srs_flags = SCTP_STREAM_RESET_OUTGOING;
-  srs->srs_number_streams = mStreamsResetting.Length();
-  for (i = 0; i < mStreamsResetting.Length(); ++i) {
-    srs->srs_stream_list[i] = mStreamsResetting[i];
-  }
-  if (usrsctp_setsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_RESET_STREAMS, srs, (socklen_t)len) < 0) {
-    LOG(("***failed: setsockopt RESET, errno %d", errno));
-  } else {
-    mStreamsResetting.Clear();
-  }
-  moz_free(srs);
-}
-
-void
-DataChannelConnection::HandleStreamResetEvent(const struct sctp_stream_reset_event *strrst)
-{
-  uint32_t n, i;
-  DataChannel *channel;
-
-  if (!(strrst->strreset_flags & SCTP_STREAM_RESET_DENIED) &&
-      !(strrst->strreset_flags & SCTP_STREAM_RESET_FAILED)) {
-    n = (strrst->strreset_length - sizeof(struct sctp_stream_reset_event)) / sizeof(uint16_t);
-    for (i = 0; i < n; ++i) {
-      if (strrst->strreset_flags & SCTP_STREAM_RESET_INCOMING_SSN) {
-        channel = FindChannelByStreamIn(strrst->strreset_stream_list[i]);
-        if (channel != nullptr) {
-          mStreamsIn[channel->mStreamIn] = nullptr;
-          channel->mStreamIn = INVALID_STREAM;
-          if (channel->mStreamOut == INVALID_STREAM) {
-            channel->mPrPolicy = SCTP_PR_SCTP_NONE;
-            channel->mPrValue = 0;
-            channel->mFlags = 0;
-            channel->mState = CLOSED;
-            NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                                      DataChannelOnMessageAvailable::ON_CHANNEL_CLOSED, this,
-                                      channel));
-          } else {
-            ResetOutgoingStream(channel->mStreamOut);
-            channel->mState = CLOSING;
-          }
-        }
-      }
-      if (strrst->strreset_flags & SCTP_STREAM_RESET_OUTGOING_SSN) {
-        channel = FindChannelByStreamOut(strrst->strreset_stream_list[i]);
-        if (channel != nullptr && channel->mStreamOut != INVALID_STREAM) {
-          mStreamsOut[channel->mStreamOut] = nullptr;
-          channel->mStreamOut = INVALID_STREAM;
-          if (channel->mStreamIn == INVALID_STREAM) {
-            channel->mPrPolicy = SCTP_PR_SCTP_NONE;
-            channel->mPrValue = 0;
-            channel->mFlags = 0;
-            channel->mState = CLOSED;
-            NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                                      DataChannelOnMessageAvailable::ON_CHANNEL_CLOSED, this,
-                                      channel));
-          }
-        }
-      }
-    }
-  }
-}
-
-void
-DataChannelConnection::HandleStreamChangeEvent(const struct sctp_stream_change_event *strchg)
-{
-  uint16_t streamOut;
-  uint32_t i;
-  DataChannel *channel;
-
-  if (strchg->strchange_flags == SCTP_STREAM_CHANGE_DENIED) {
-    LOG(("*** Failed increasing number of streams from %u (%u/%u)",
-         mStreamsOut.Length(),
-         strchg->strchange_instrms,
-         strchg->strchange_outstrms));
-    // XXX FIX! notify pending opens of failure
-    return;
-  } else {
-    if (strchg->strchange_instrms > mStreamsIn.Length()) {
-      LOG(("Other side increased streamds from %u to %u",
-           mStreamsIn.Length(), strchg->strchange_instrms));
-    }
-    if (strchg->strchange_outstrms > mStreamsOut.Length()) {
-      uint16_t old_len = mStreamsOut.Length();
-      LOG(("Increasing number of streams from %u to %u - adding %u (in: %u)",
-           old_len,
-           strchg->strchange_outstrms,
-           strchg->strchange_outstrms - old_len,
-           strchg->strchange_instrms));
-      // make sure both are the same length
-      mStreamsOut.AppendElements(strchg->strchange_outstrms - old_len);
-      LOG(("New length = %d (was %d)", mStreamsOut.Length(), old_len));
-      for (uint32_t i = old_len; i < mStreamsOut.Length(); ++i) {
-        mStreamsOut[i] = nullptr;
-      }
-      // Re-process any channels waiting for streams.
-      // Linear search, but we don't increase channels often and
-      // the array would only get long in case of an app error normally
-
-      // Make sure we request enough streams if there's a big jump in streams
-      // Could make a more complex API for OpenXxxFinish() and avoid this loop
-      int32_t num_needed = mPending.GetSize();
-      LOG(("%d of %d new streams already needed", num_needed,
-           strchg->strchange_outstrms - old_len));
-      num_needed -= (strchg->strchange_outstrms - old_len); // number we added
-      if (num_needed > 0) {
-        if (num_needed < 16)
-          num_needed = 16;
-        LOG(("Not enough new streams, asking for %d more", num_needed));
-        RequestMoreStreamsOut(num_needed);
-      }
-
-      // Can't copy nsDeque's.  Move into temp array since any that fail will
-      // go back to mPending
-      nsDeque temp;
-      while (nullptr != (channel = static_cast<DataChannel *>(mPending.PopFront()))) {
-        temp.Push(channel);
-      }
-
-      // Now assign our new streams
-      while (nullptr != (channel = static_cast<DataChannel *>(temp.PopFront()))) {
-        if (channel->mFlags & DATA_CHANNEL_FLAGS_FINISH_RSP) {
-          channel->mFlags &= ~DATA_CHANNEL_FLAGS_FINISH_RSP;
-          OpenResponseFinish(channel); // may reset the flag and re-push
-        } else if (channel->mFlags & DATA_CHANNEL_FLAGS_FINISH_OPEN) {
-          channel->mFlags &= ~DATA_CHANNEL_FLAGS_FINISH_OPEN;
-          OpenFinish(channel); // may reset the flag and re-push
-        }
-      }
-    }
-    // else probably not a change in # of streams
-  }
-
-  for (i = 0; i < mStreamsOut.Length(); ++i) {
-    channel = mStreamsOut[i];
-    if (!channel)
-      continue;
-
-    if ((channel->mState == CONNECTING) &&
-        (channel->mStreamOut == INVALID_STREAM)) {
-      if ((strchg->strchange_flags & SCTP_STREAM_CHANGE_DENIED) ||
-          (strchg->strchange_flags & SCTP_STREAM_CHANGE_FAILED)) {
-        /* XXX: Signal to the other end. */
-        if (channel->mStreamIn != INVALID_STREAM) {
-          mStreamsIn[channel->mStreamIn] = nullptr;
-        }
-        channel->mState = CLOSED;
-        // inform user!
-        // XXX delete channel;
-      } else {
-        streamOut = FindFreeStreamOut();
-        if (streamOut != INVALID_STREAM) {
-          channel->mStreamOut = streamOut;
-          mStreamsOut[streamOut] = channel;
-          if (channel->mStreamIn == INVALID_STREAM) {
-            channel->mFlags |= DATA_CHANNEL_FLAGS_SEND_REQ;
-          } else {
-            channel->mFlags |= DATA_CHANNEL_FLAGS_SEND_RSP;
-          }
-          StartDefer();
-        } else {
-          /* We will not find more ... */
-          break;
-        }
-      }
-    }
-  }
-}
-
-
-// Called with mLock locked!
-void
-DataChannelConnection::HandleNotification(const union sctp_notification *notif, size_t n)
-{
-  mLock.AssertCurrentThreadOwns();
-  if (notif->sn_header.sn_length != (uint32_t)n) {
-    return;
-  }
-  switch (notif->sn_header.sn_type) {
-  case SCTP_ASSOC_CHANGE:
-    HandleAssociationChangeEvent(&(notif->sn_assoc_change));
-    break;
-  case SCTP_PEER_ADDR_CHANGE:
-    HandlePeerAddressChangeEvent(&(notif->sn_paddr_change));
-    break;
-  case SCTP_REMOTE_ERROR:
-    HandleRemoteErrorEvent(&(notif->sn_remote_error));
-    break;
-  case SCTP_SHUTDOWN_EVENT:
-    HandleShutdownEvent(&(notif->sn_shutdown_event));
-    break;
-  case SCTP_ADAPTATION_INDICATION:
-    HandleAdaptationIndication(&(notif->sn_adaptation_event));
-    break;
-  case SCTP_PARTIAL_DELIVERY_EVENT:
-    LOG(("SCTP_PARTIAL_DELIVERY_EVENT"));
-    break;
-  case SCTP_AUTHENTICATION_EVENT:
-    LOG(("SCTP_AUTHENTICATION_EVENT"));
-    break;
-  case SCTP_SENDER_DRY_EVENT:
-    //LOG(("SCTP_SENDER_DRY_EVENT"));
-    break;
-  case SCTP_NOTIFICATIONS_STOPPED_EVENT:
-    LOG(("SCTP_NOTIFICATIONS_STOPPED_EVENT"));
-    break;
-  case SCTP_SEND_FAILED_EVENT:
-    HandleSendFailedEvent(&(notif->sn_send_failed_event));
-    break;
-  case SCTP_STREAM_RESET_EVENT:
-    HandleStreamResetEvent(&(notif->sn_strreset_event));
-    break;
-  case SCTP_ASSOC_RESET_EVENT:
-    LOG(("SCTP_ASSOC_RESET_EVENT"));
-    break;
-  case SCTP_STREAM_CHANGE_EVENT:
-    HandleStreamChangeEvent(&(notif->sn_strchange_event));
-    break;
-  default:
-    LOG(("unknown SCTP event: %u", (uint32_t)notif->sn_header.sn_type));
-    break;
-   }
- }
-
-int
-DataChannelConnection::ReceiveCallback(struct socket* sock, void *data, size_t datalen,
-                                       struct sctp_rcvinfo rcv, int32_t flags)
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  if (!data) {
-    usrsctp_close(sock); // SCTP has finished shutting down
-  } else {
-    MutexAutoLock lock(mLock);
-    if (flags & MSG_NOTIFICATION) {
-      HandleNotification(static_cast<union sctp_notification *>(data), datalen);
-    } else {
-      HandleMessage(data, datalen, ntohl(rcv.rcv_ppid), rcv.rcv_sid);
-    }
-  }
-  // usrsctp defines the callback as returning an int, but doesn't use it
-  return 1;
-}
-
-DataChannel *
-DataChannelConnection::Open(const nsACString& label, Type type, bool inOrder,
-                            uint32_t prValue, DataChannelListener *aListener,
-                            nsISupports *aContext)
-{
-  DataChannel *channel;
-  uint16_t prPolicy = SCTP_PR_SCTP_NONE;
-  uint32_t flags;
-
-  LOG(("DC Open: label %s, type %u, inorder %d, prValue %u, listener %p, context %p",
-       PromiseFlatCString(label).get(), type, inOrder, prValue, aListener, aContext));
-  switch (type) {
-    case DATA_CHANNEL_RELIABLE:
-      prPolicy = SCTP_PR_SCTP_NONE;
-      break;
-    case DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT:
-      prPolicy = SCTP_PR_SCTP_RTX;
-      break;
-    case DATA_CHANNEL_PARTIAL_RELIABLE_TIMED:
-      prPolicy = SCTP_PR_SCTP_TTL;
-      break;
-  }
-  if ((prPolicy == SCTP_PR_SCTP_NONE) && (prValue != 0)) {
-    return nullptr;
-  }
-
-  flags = !inOrder ? DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED : 0;
-  channel = new DataChannel(this, INVALID_STREAM, INVALID_STREAM,
-                            DataChannel::CONNECTING,
-                            label, type, prValue,
-                            flags,
-                            aListener, aContext); // infallible malloc
-
-  MutexAutoLock lock(mLock); // OpenFinish assumes this
-  return OpenFinish(channel);
-}
-
-// Separate routine so we can also call it to finish up from pending opens
-DataChannel *
-DataChannelConnection::OpenFinish(DataChannel *channel)
-{
-  uint16_t streamOut = FindFreeStreamOut(); // may be INVALID_STREAM!
-
-  mLock.AssertCurrentThreadOwns();
-
-  LOG(("Finishing open: channel %p, streamOut = %u", channel, streamOut));
-
-  if (streamOut == INVALID_STREAM) {
-    if (!RequestMoreStreamsOut()) {
-      if (channel->mFlags &= DATA_CHANNEL_FLAGS_FINISH_OPEN) {
-        // We already returned the channel to the app.  Mark it closed
-        channel->mState = CLOSED;
-        NS_ERROR("Failed to request more streams");
-        return channel;
-      }
-      // we can do this with the lock held because mStreamOut is INVALID_STREAM,
-      // so there's no outbound channel to reset
-      delete channel;
-      return nullptr;
-    }
-    LOG(("Queuing channel %p to finish open", channel));
-    // Also serves to mark we told the app
-    channel->mFlags |= DATA_CHANNEL_FLAGS_FINISH_OPEN;
-    mPending.Push(channel);
-    return channel;
-  }
-  mStreamsOut[streamOut] = channel;
-  channel->mStreamOut = streamOut;
-
-  if (!SendOpenRequestMessage(channel->mLabel, streamOut,
-                              !!(channel->mFlags & DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED),
-                              channel->mPrPolicy, channel->mPrValue)) {
-    LOG(("SendOpenRequest failed, errno = %d", errno));
-    if (errno == EAGAIN) {
-      channel->mFlags |= DATA_CHANNEL_FLAGS_SEND_REQ;
-      StartDefer();
-    } else {
-      // XXX FIX! can't do this if we previously returned it!  Need to internally mark it dead
-      // and file onerror
-      mStreamsOut[streamOut] = nullptr;
-      channel->mStreamOut = INVALID_STREAM;
-      // we can do this with the lock held because mStreamOut is INVALID_STREAM,
-      // so there's no outbound channel to reset (we didn't sent anything)
-      delete channel;
-      return nullptr;
-    }
-  }
-  return channel;
-}
-
-int32_t
-DataChannelConnection::SendMsgInternal(DataChannel *channel, const char *data,
-                                       uint32_t length, uint32_t ppid)
-{
-  uint16_t flags;
-  struct sctp_sendv_spa spa;
-  int32_t result;
-
-  NS_ENSURE_TRUE(channel->mState == OPEN || channel->mState == CONNECTING, 0);
-  NS_WARN_IF_FALSE(length > 0, "Length is 0?!");
-
-  flags = (channel->mFlags & DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED) ? SCTP_UNORDERED : 0;
-
-  // To avoid problems where an in-order OPEN_RESPONSE is lost and an
-  // out-of-order data message "beats" it, require data to be in-order
-  // until we get an ACK.
-  if (channel->mState == CONNECTING) {
-    flags &= ~SCTP_UNORDERED;
-  }
-  spa.sendv_sndinfo.snd_ppid = htonl(ppid);
-  spa.sendv_sndinfo.snd_sid = channel->mStreamOut;
-  spa.sendv_sndinfo.snd_flags = flags;
-  spa.sendv_sndinfo.snd_context = 0;
-  spa.sendv_sndinfo.snd_assoc_id = 0;
-
-  spa.sendv_prinfo.pr_policy = SCTP_PR_SCTP_TTL;
-  spa.sendv_prinfo.pr_value = channel->mPrValue;
-
-  spa.sendv_flags = SCTP_SEND_SNDINFO_VALID | SCTP_SEND_PRINFO_VALID;
-
-  // Note: Main-thread IO, but doesn't block!
-  // XXX FIX!  to deal with heavy overruns of JS trying to pass data in
-  // (more than the buffersize) queue data onto another thread to do the
-  // actual sends.  See netwerk/protocol/websocket/WebSocketChannel.cpp
-
-  // SCTP will return EMSGSIZE if the message is bigger than the buffer
-  // size (or EAGAIN if there isn't space)
-  if (channel->mBufferedData.IsEmpty()) {
-    result = usrsctp_sendv(mSocket, data, length,
-                           nullptr, 0,
-                           (void *)&spa, (socklen_t)sizeof(struct sctp_sendv_spa),
-                           SCTP_SENDV_SPA, flags);
-    LOG(("Sent buffer (len=%u), result=%d", length, result));
-  } else {
-    // Fake EAGAIN if we're already buffering data
-    result = -1;
-    errno = EAGAIN;
-  }
-  if (result < 0) {
-    if (errno == EAGAIN) {
-      // queue data for resend!  And queue any further data for the stream until it is...
-      BufferedMsg *buffered = new BufferedMsg(spa, data, length); // infallible malloc
-      channel->mBufferedData.AppendElement(buffered); // owned by mBufferedData array
-      channel->mFlags |= DATA_CHANNEL_FLAGS_SEND_DATA;
-      LOG(("Queued %u buffers (len=%u)", channel->mBufferedData.Length(), length));
-      StartDefer();
-      return 0;
-    }
-    LOG(("error %d sending string", errno));
-  }
-  return result;
-}
-
-// Handles fragmenting binary messages
-int32_t
-DataChannelConnection::SendBinary(DataChannel *channel, const char *data,
-                                  uint32_t len)
-{
-  // Since there's a limit on network buffer size and no limits on message
-  // size, and we don't want to use EOR mode (multiple writes for a
-  // message, but all other streams are blocked until you finish sending
-  // this message), we need to add application-level fragmentation of large
-  // messages.  On a reliable channel, these can be simply rebuilt into a
-  // large message.  On an unreliable channel, we can't and don't know how
-  // long to wait, and there are no retransmissions, and no easy way to
-  // tell the user "this part is missing", so on unreliable channels we
-  // need to return an error if sending more bytes than the network buffers
-  // can hold, and perhaps a lower number.
-
-  // We *really* don't want to do this from main thread! - and SendMsgInternal
-  // avoids blocking.
-  if (len > DATA_CHANNEL_MAX_BINARY_FRAGMENT &&
-      channel->mPrPolicy == DATA_CHANNEL_RELIABLE) {
-    int32_t sent=0;
-    uint32_t origlen = len;
-    LOG(("Sending binary message length %u in chunks", len));
-    // XXX check flags for out-of-order, or force in-order for large binary messages
-    while (len > 0) {
-      uint32_t sendlen = PR_MIN(len, DATA_CHANNEL_MAX_BINARY_FRAGMENT);
-      uint32_t ppid;
-      len -= sendlen;
-      ppid = len > 0 ? DATA_CHANNEL_PPID_BINARY : DATA_CHANNEL_PPID_BINARY_LAST;
-      LOG(("Send chunk of %d bytes, ppid %d", sendlen, ppid));
-      // Note that these might end up being deferred and queued.
-      sent += SendMsgInternal(channel, data, sendlen, ppid);
-      data += sendlen;
-    }
-    LOG(("Sent %d buffers for %u bytes, %d sent immediately, % buffers queued",
-         (origlen+DATA_CHANNEL_MAX_BINARY_FRAGMENT-1)/DATA_CHANNEL_MAX_BINARY_FRAGMENT,
-         origlen, sent,
-         channel->mBufferedData.Length()));
-    return sent;
-  }
-  NS_WARN_IF_FALSE(len <= DATA_CHANNEL_MAX_BINARY_FRAGMENT,
-                   "Sending too-large data on unreliable channel!");
-
-  // This will fail if the message is too large
-  return SendMsgInternal(channel, data, len, DATA_CHANNEL_PPID_BINARY_LAST);
-}
-
-int32_t
-DataChannelConnection::SendBlob(uint16_t stream, nsIInputStream *aBlob)
-{
-  DataChannel *channel = mStreamsOut[stream];
-  NS_ENSURE_TRUE(channel, 0);
-  // Spawn a thread to send the data
-
-  LOG(("Sending blob to stream %u", stream));
-
-  // XXX to do this safely, we must enqueue these atomically onto the
-  // output socket.  We need a sender thread(s?) to enque data into the
-  // socket and to avoid main-thread IO that might block.  Even on a
-  // background thread, we may not want to block on one stream's data.
-  // I.e. run non-blocking and service multiple channels.
-
-  // For now as a hack, send as a single blast of queued packets which may
-  // be deferred until buffer space is available.
-  nsAutoPtr<nsCString> temp(new nsCString());
-  uint64_t len;
-  aBlob->Available(&len);
-  nsresult rv = NS_ReadInputStreamToString(aBlob, *temp, len);
-
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  aBlob->Close();
-  //aBlob->Release(); We didn't AddRef() the way WebSocket does in OutboundMessage (yet)
-
-  // Consider if it makes sense to split the message ourselves for
-  // transmission, at least on RELIABLE channels.  Sending large blobs via
-  // unreliable channels requires some level of application involvement, OR
-  // sending them at big, single messages, which if large will probably not
-  // get through.
-
-  // XXX For now, send as one large binary message.  We should also signal
-  // (via PPID) that it's a blob.
-  const char *data = temp.get()->BeginReading();
-  len              = temp.get()->Length();
-
-  return SendBinary(channel, data, len);
-}
-
-int32_t
-DataChannelConnection::SendMsgCommon(uint16_t stream, const nsACString &aMsg,
-                                     bool isBinary)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  // We really could allow this from other threads, so long as we deal with
-  // asynchronosity issues with channels closing, in particular access to
-  // mStreamsOut, and issues with the association closing (access to mSocket).
-
-  const char *data = aMsg.BeginReading();
-  uint32_t len     = aMsg.Length();
-  DataChannel *channel;
-
-  if (isBinary)
-    LOG(("Sending to stream %u: %u bytes", stream, len));
-  else
-    LOG(("Sending to stream %u: %s", stream, data));
-  // XXX if we want more efficiency, translate flags once at open time
-  channel = mStreamsOut[stream];
-  NS_ENSURE_TRUE(channel, 0);
-
-  if (isBinary)
-    return SendBinary(channel, data, len);
-  return SendMsgInternal(channel, data, len, DATA_CHANNEL_PPID_DOMSTRING);
-}
-
-void
-DataChannelConnection::Close(uint16_t streamOut)
-{
-  DataChannel *channel;
-
-  MutexAutoLock lock(mLock);
-  LOG(("Closing stream %d",streamOut));
-  channel = FindChannelByStreamOut(streamOut);
-  if (channel) {
-    channel->mBufferedData.Clear();
-    ResetOutgoingStream(channel->mStreamOut);
-    SendOutgoingStreamReset();
-    channel->mState = CLOSING;
-  }
-}
-
-void DataChannelConnection::CloseAll()
-{
-  LOG(("Closing all channels"));
-  // Don't need to lock here
-
-  // Make sure no more channels will be opened
-  mState = CLOSED;
-
-  // Close current channels
-  // FIX! if there are runnables, they must use weakrefs or hold a strong
-  // ref and keep the channel and/or connection alive
-  for (uint32_t i = 0; i < mStreamsOut.Length(); ++i) {
-    if (mStreamsOut[i]) {
-      mStreamsOut[i]->Close();
-    }
-  }
-
-  // Clean up any pending opens for channels
-  DataChannel *channel;
-  while (nullptr != (channel = static_cast<DataChannel *>(mPending.PopFront())))
-    channel->Close();
-}
-
-void
-DataChannel::Close()
-{ 
-  if (mState == CLOSING || mState == CLOSED ||
-      mStreamOut == INVALID_STREAM) {
-    return;
-  }
-  mState = CLOSING;
-  mConnection->Close(mStreamOut);
-  mStreamOut = INVALID_STREAM;
-  mStreamIn  = INVALID_STREAM;
-}
-
-void
-DataChannel::SetListener(DataChannelListener *aListener, nsISupports *aContext)
-{
-  MOZ_ASSERT(!mListener); // only should be set once, avoids races w/o locking
-  mContext = aContext;
-  mListener = aListener;
-}
-
-// May be called from another (i.e. Main) thread!
-void
-DataChannel::AppReady()
-{
-  MutexAutoLock lock(mConnection->mLock);
-
-  mReady = true;
-  if (mState == WAITING_TO_OPEN) {
-    mState = OPEN;
-    NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
-                              DataChannelOnMessageAvailable::ON_CHANNEL_OPEN, mConnection,
-                              this));
-    for (uint32_t i = 0; i < mQueuedMessages.Length(); ++i) {
-      nsCOMPtr<nsIRunnable> runnable = mQueuedMessages[i];
-      MOZ_ASSERT(runnable);
-      NS_DispatchToMainThread(runnable);
-    }
-  } else {
-    NS_ASSERTION(mQueuedMessages.IsEmpty(), "Shouldn't have queued messages if not WAITING_TO_OPEN");
-  }
-  mQueuedMessages.Clear();
-  mQueuedMessages.Compact();
-  // We never use it again...  We could even allocate the array in the odd
-  // cases we need it.
-}
-
-uint32_t
-DataChannel::GetBufferedAmount()
-{
-  uint32_t buffered = 0;
-  for (uint32_t i = 0; i < mBufferedData.Length(); ++i) {
-    buffered += mBufferedData[i]->mLength;
-  }
-  return buffered;
-}
-
-} // namespace mozilla
-
deleted file mode 100644
--- a/netwerk/sctp/datachannel/DataChannel.h
+++ /dev/null
@@ -1,456 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#ifndef NETWERK_SCTP_DATACHANNEL_DATACHANNEL_H_
-#define NETWERK_SCTP_DATACHANNEL_DATACHANNEL_H_
-
-#include <string>
-#include "nsISupports.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsThreadUtils.h"
-#include "nsTArray.h"
-#include "nsDeque.h"
-#include "nsIInputStream.h"
-#include "nsITimer.h"
-#include "mozilla/Mutex.h"
-#include "DataChannelProtocol.h"
-#ifdef SCTP_DTLS_SUPPORTED
-#include "talk/base/sigslot.h"
-#include "mtransport/transportflow.h"
-#include "mtransport/transportlayer.h"
-#include "mtransport/transportlayerprsock.h"
-#endif
-
-extern "C" {
-  struct socket;
-  struct sctp_rcvinfo;
-}
-
-namespace mozilla {
-
-class DTLSConnection;
-class DataChannelConnection;
-class DataChannel;
-class DataChannelOnMessageAvailable;
-
-class BufferedMsg
-{
-public:
-  BufferedMsg(struct sctp_sendv_spa &spa,const char *data,
-              uint32_t length);
-  ~BufferedMsg();
-
-  struct sctp_sendv_spa *mSpa;
-  const char *mData;
-  uint32_t mLength;
-};
-
-// Implemented by consumers of a Channel to receive messages.
-// Can't nest it in DataChannelConnection because C++ doesn't allow forward
-// refs to embedded classes
-class DataChannelListener {
-public:
-  virtual ~DataChannelListener() {}
-
-  // Called when a DOMString message is received.
-  virtual nsresult OnMessageAvailable(nsISupports *aContext,
-                                  const nsACString& message) = 0;
-
-  // Called when a binary message is received.
-  virtual nsresult OnBinaryMessageAvailable(nsISupports *aContext,
-                                        const nsACString& message) = 0;
-
-  // Called when the channel is connected
-  virtual nsresult OnChannelConnected(nsISupports *aContext) = 0;
-
-  // Called when the channel is closed
-  virtual nsresult OnChannelClosed(nsISupports *aContext) = 0;
-};
-
-
-// One per PeerConnection
-class DataChannelConnection: public nsITimerCallback
-#ifdef SCTP_DTLS_SUPPORTED
-                             , public sigslot::has_slots<>
-#endif
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSITIMERCALLBACK
-
-  class DataConnectionListener {
-  public:
-    virtual ~DataConnectionListener() {}
-
-    // Called when a the connection is open
-    virtual void NotifyConnection() = 0;
-
-    // Called when a the connection is lost/closed
-    virtual void NotifyClosedConnection() = 0;
-
-    // Called when a new DataChannel has been opened by the other side.
-    virtual void NotifyDataChannel(DataChannel *channel) = 0;
-  };
-
-  DataChannelConnection(DataConnectionListener *listener);
-  virtual ~DataChannelConnection();
-
-  bool Init(unsigned short aPort, uint16_t aNumStreams, bool aUsingDtls);
-
-  // These block; they require something to decide on listener/connector
-  // (though you can do simultaneous Connect()).  Do not call these from
-  // the main thread!
-  bool Listen(unsigned short port);
-  bool Connect(const char *addr, unsigned short port);
-
-#ifdef SCTP_DTLS_SUPPORTED
-  // Connect using a TransportFlow (DTLS) channel
-  bool ConnectDTLS(TransportFlow *aFlow, uint16_t localport, uint16_t remoteport);
-#endif
-
-  typedef enum {
-    RELIABLE=0,
-    PARTIAL_RELIABLE_REXMIT = 1,
-    PARTIAL_RELIABLE_TIMED = 2
-  } Type;
-    
-  DataChannel *Open(const nsACString& label,
-                    Type type, bool inOrder, 
-                    uint32_t prValue, DataChannelListener *aListener,
-                    nsISupports *aContext);
-
-  void Close(uint16_t stream);
-  void CloseAll();
-
-  int32_t SendMsg(uint16_t stream, const nsACString &aMsg)
-    {
-      return SendMsgCommon(stream, aMsg, false);
-    }
-  int32_t SendBinaryMsg(uint16_t stream, const nsACString &aMsg)
-    {
-      return SendMsgCommon(stream, aMsg, true);
-    }
-  int32_t SendBlob(uint16_t stream, nsIInputStream *aBlob);
-
-  // Called on data reception from the SCTP library
-  // must(?) be public so my c->c++ tramploine can call it
-  int ReceiveCallback(struct socket* sock, void *data, size_t datalen, 
-                      struct sctp_rcvinfo rcv, int32_t flags);
-
-  // Find out state
-  enum {
-    CONNECTING = 0U,
-    OPEN = 1U,
-    CLOSING = 2U,
-    CLOSED = 3U
-  };
-  uint16_t GetReadyState() { return mState; }
-
-  friend class DataChannel;
-  Mutex  mLock;
-
-protected:
-  friend class DataChannelOnMessageAvailable;
-  DataConnectionListener *mListener;
-
-private:
-#ifdef SCTP_DTLS_SUPPORTED
-  static void DTLSConnectThread(void *data);
-  int SendPacket(const unsigned char* data, size_t len);
-  void PacketReceived(TransportFlow *flow, const unsigned char *data, size_t len);
-  static int SctpDtlsOutput(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df);
-#endif
-  DataChannel* FindChannelByStreamIn(uint16_t streamIn);
-  DataChannel* FindChannelByStreamOut(uint16_t streamOut);
-  uint16_t FindFreeStreamOut();
-  bool RequestMoreStreamsOut(int32_t aNeeded = 16);
-  int32_t SendControlMessage(void *msg, uint32_t len, uint16_t streamOut);
-  int32_t SendOpenRequestMessage(const nsACString& label,uint16_t streamOut,
-                                 bool unordered, uint16_t prPolicy, uint32_t prValue);
-  int32_t SendOpenResponseMessage(uint16_t streamOut, uint16_t streamIn);
-  int32_t SendOpenAckMessage(uint16_t streamOut);
-  int32_t SendMsgInternal(DataChannel *channel, const char *data,
-                          uint32_t length, uint32_t ppid);
-  int32_t SendBinary(DataChannel *channel, const char *data,
-                     uint32_t len);
-  int32_t SendMsgCommon(uint16_t stream, const nsACString &aMsg, bool isBinary);
-
-  DataChannel *OpenFinish(DataChannel *channel);
-
-  void SendOrQueue(DataChannel *aChannel, DataChannelOnMessageAvailable *aMessage);
-  void StartDefer();
-  bool SendDeferredMessages();
-  void SendOutgoingStreamReset();
-  void ResetOutgoingStream(uint16_t streamOut);
-  void HandleOpenRequestMessage(const struct rtcweb_datachannel_open_request *req,
-                                size_t length,
-                                uint16_t streamIn);
-  void OpenResponseFinish(DataChannel *channel);
-  void HandleOpenResponseMessage(const struct rtcweb_datachannel_open_response *rsp,
-                                 size_t length, uint16_t streamIn);
-  void HandleOpenAckMessage(const struct rtcweb_datachannel_ack *ack,
-                            size_t length, uint16_t streamIn);
-  void HandleUnknownMessage(uint32_t ppid, size_t length, uint16_t streamIn);
-  void HandleDataMessage(uint32_t ppid, const void *buffer, size_t length, uint16_t streamIn);
-  void HandleMessage(const void *buffer, size_t length, uint32_t ppid, uint16_t streamIn);
-  void HandleAssociationChangeEvent(const struct sctp_assoc_change *sac);
-  void HandlePeerAddressChangeEvent(const struct sctp_paddr_change *spc);
-  void HandleRemoteErrorEvent(const struct sctp_remote_error *sre);
-  void HandleShutdownEvent(const struct sctp_shutdown_event *sse);
-  void HandleAdaptationIndication(const struct sctp_adaptation_event *sai);
-  void HandleSendFailedEvent(const struct sctp_send_failed_event *ssfe);
-  void HandleStreamResetEvent(const struct sctp_stream_reset_event *strrst);
-  void HandleStreamChangeEvent(const struct sctp_stream_change_event *strchg);
-  void HandleNotification(const union sctp_notification *notif, size_t n);
-
-  // NOTE: while these arrays will auto-expand, increases in the number of
-  // channels available from the stack must be negotiated!
-  nsAutoTArray<DataChannel*,16> mStreamsOut;
-  nsAutoTArray<DataChannel*,16> mStreamsIn;
-  nsDeque mPending; // Holds DataChannels
-
-  // Streams pending reset
-  nsAutoTArray<uint16_t,4> mStreamsResetting;
-
-  struct socket *mMasterSocket;
-  struct socket *mSocket;
-  uint16_t mState;
-
-#ifdef SCTP_DTLS_SUPPORTED
-  nsRefPtr<TransportFlow> mTransportFlow;
-#endif
-  uint16_t mLocalPort;
-  uint16_t mRemotePort;
-
-  // Timer to control when we try to resend blocked messages
-  nsCOMPtr<nsITimer> mDeferredTimer;
-  uint32_t mDeferTimeout; // in ms
-  bool mTimerRunning;
-};
-
-class DataChannel {
-public:
-  enum {
-    CONNECTING = 0U,
-    OPEN = 1U,
-    CLOSING = 2U,
-    CLOSED = 3U,
-    WAITING_TO_OPEN = 4U
-  };
-
-  DataChannel(DataChannelConnection *connection,
-              uint16_t streamOut, uint16_t streamIn, 
-              uint16_t state,
-              const nsACString& label,
-              uint16_t policy, uint32_t value,
-              uint32_t flags,
-              DataChannelListener *aListener,
-              nsISupports *aContext)
-    : mListener(aListener)
-    , mConnection(connection)
-    , mLabel(label)
-    , mState(state)
-    , mReady(false)
-    , mStreamOut(streamOut)
-    , mStreamIn(streamIn)
-    , mPrPolicy(policy)
-    , mPrValue(value)
-    , mFlags(0)
-    , mContext(aContext)
-    {
-      NS_ASSERTION(mConnection,"NULL connection");
-    }
-
-  ~DataChannel()
-    {
-      Close();
-    }
-
-  // Close this DataChannel.  Can be called multiple times.
-  void Close();
-
-  // Set the listener (especially for channels created from the other side)
-  // Note: The Listener and Context should only be set once
-  void SetListener(DataChannelListener *aListener, nsISupports *aContext);
-
-  // Send a string
-  bool SendMsg(const nsACString &aMsg)
-    {
-      if (mStreamOut != INVALID_STREAM)
-        return (mConnection->SendMsg(mStreamOut, aMsg) > 0);
-      else
-        return false;
-    }
-
-  // Send a binary message (TypedArray)
-  bool SendBinaryMsg(const nsACString &aMsg)
-    {
-      if (mStreamOut != INVALID_STREAM)
-        return (mConnection->SendBinaryMsg(mStreamOut, aMsg) > 0);
-      else
-        return false;
-    }
-
-  // Send a binary blob
-  bool SendBinaryStream(nsIInputStream *aBlob, uint32_t msgLen)
-    {
-      if (mStreamOut != INVALID_STREAM)
-        return (mConnection->SendBlob(mStreamOut, aBlob) > 0);
-      else
-        return false;
-    }
-
-  uint16_t GetType() { return mPrPolicy; }
-
-  bool GetOrdered() { return !(mFlags & DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED); }
-
-  // Amount of data buffered to send
-  uint32_t GetBufferedAmount();
-
-  // Find out state
-  uint16_t GetReadyState()
-    {
-      if (mState == WAITING_TO_OPEN)
-        return CONNECTING;
-      return mState;
-    }
-
-  void SetReadyState(uint16_t aState) { mState = aState; }
-
-  void GetLabel(nsAString& aLabel) { CopyUTF8toUTF16(mLabel, aLabel); }
-
-  void AppReady();
-
-protected:
-  DataChannelListener *mListener;
-
-private:
-  friend class DataChannelOnMessageAvailable;
-  friend class DataChannelConnection;
-
-  nsresult AddDataToBinaryMsg(const char *data, uint32_t size);
-
-  nsRefPtr<DataChannelConnection> mConnection;
-  nsCString mLabel;
-  uint16_t mState;
-  bool     mReady;
-  uint16_t mStreamOut;
-  uint16_t mStreamIn;
-  uint16_t mPrPolicy;
-  uint32_t mPrValue;
-  uint32_t mFlags;
-  uint32_t mId;
-  nsCOMPtr<nsISupports> mContext;
-  nsCString mBinaryBuffer;
-  nsTArray<nsAutoPtr<BufferedMsg> > mBufferedData;
-  nsTArray<nsCOMPtr<nsIRunnable> > mQueuedMessages;
-};
-
-// used to dispatch notifications of incoming data to the main thread
-// Patterned on CallOnMessageAvailable in WebSockets
-// Also used to proxy other items to MainThread
-class DataChannelOnMessageAvailable : public nsRunnable
-{
-public:
-  enum {
-    ON_CONNECTION,
-    ON_DISCONNECTED,
-    ON_CHANNEL_CREATED,
-    ON_CHANNEL_OPEN,
-    ON_CHANNEL_CLOSED,
-    ON_DATA,
-    START_DEFER,
-  };  /* types */
-
-  DataChannelOnMessageAvailable(int32_t     aType,
-                                DataChannelConnection *aConnection,
-                                DataChannel *aChannel,
-                                nsCString   &aData,  // XXX this causes inefficiency
-                                int32_t     aLen)
-    : mType(aType),
-      mChannel(aChannel),
-      mConnection(aConnection), 
-      mData(aData),
-      mLen(aLen) {}
-
-  DataChannelOnMessageAvailable(int32_t     aType,
-                                DataChannel *aChannel)
-    : mType(aType),
-      mChannel(aChannel) {}
-  // XXX is it safe to leave mData/mLen uninitialized?  This should only be
-  // used for notifications that don't use them, but I'd like more
-  // bulletproof compile-time checking.
-
-  DataChannelOnMessageAvailable(int32_t     aType,
-                                DataChannelConnection *aConnection,
-                                DataChannel *aChannel)
-    : mType(aType),
-      mChannel(aChannel),
-      mConnection(aConnection) {}
-
-  NS_IMETHOD Run()
-  {
-    switch (mType) {
-      case ON_DATA:
-      case ON_CHANNEL_OPEN:
-      case ON_CHANNEL_CLOSED:
-        if (!mChannel->mListener)
-          return NS_OK;
-        break;
-      case ON_CHANNEL_CREATED:
-      case ON_CONNECTION:
-      case ON_DISCONNECTED:
-        if (!mConnection->mListener)
-          return NS_OK;
-        break;
-      case START_DEFER:
-        break;
-    }
-    switch (mType) {
-      case ON_DATA:
-        if (mLen < 0) {
-          mChannel->mListener->OnMessageAvailable(mChannel->mContext, mData);
-        } else {
-          mChannel->mListener->OnBinaryMessageAvailable(mChannel->mContext, mData);
-        }
-        break;
-      case ON_CHANNEL_OPEN:
-        mChannel->mListener->OnChannelConnected(mChannel->mContext);
-        break;
-      case ON_CHANNEL_CLOSED:
-        mChannel->mListener->OnChannelClosed(mChannel->mContext);
-        break;
-      case ON_CHANNEL_CREATED:
-        mConnection->mListener->NotifyDataChannel(mChannel);
-        break;
-      case ON_CONNECTION:
-        mConnection->mListener->NotifyConnection();
-        break;
-      case ON_DISCONNECTED:
-        mConnection->mListener->NotifyClosedConnection();
-        break;
-      case START_DEFER:
-        mConnection->StartDefer();
-        break;
-    }
-    return NS_OK;
-  }
-
-private:
-  ~DataChannelOnMessageAvailable() {}
-
-  int32_t                           mType;
-  // XXX should use union
-  DataChannel                       *mChannel;    // XXX careful of ownership! 
-  nsRefPtr<DataChannelConnection>   mConnection;
-  nsCString                         mData;
-  int32_t                           mLen;
-};
-
-}
-
-#endif  // NETWERK_SCTP_DATACHANNEL_DATACHANNEL_H_
deleted file mode 100644
--- a/netwerk/sctp/datachannel/DataChannelLog.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#ifndef DataChannelLog_h
-#define DataChannelLog_h
-
-#ifdef MOZ_LOGGING
-#define FORCE_PR_LOG
-#endif
-
-#if defined(PR_LOG)
-#error "This file must be #included before any IPDL-generated files or other files that #include prlog.h"
-#endif
-
-#include "base/basictypes.h"
-#include "prlog.h"
-
-#ifdef PR_LOGGING
-extern PRLogModuleInfo* dataChannelLog;
-#endif
-
-#undef LOG
-#define LOG(args) PR_LOG(dataChannelLog, PR_LOG_DEBUG, args)
-
-#endif
deleted file mode 100644
--- a/netwerk/sctp/datachannel/DataChannelProtocol.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#ifndef NETWERK_SCTP_DATACHANNEL_DATACHANNELPROTOCOL_H_
-#define NETWERK_SCTP_DATACHANNEL_DATACHANNELPROTOCOL_H_
-
-#if defined(__GNUC__)
-#define SCTP_PACKED __attribute__((packed))
-#elif defined(_MSC_VER)
-#pragma pack (push, 1)
-#define SCTP_PACKED
-#else
-#error "Unsupported compiler"
-#endif
-
-#define DATA_CHANNEL_PPID_CONTROL   50
-#define DATA_CHANNEL_PPID_DOMSTRING 51
-#define DATA_CHANNEL_PPID_BINARY    52
-#define DATA_CHANNEL_PPID_BINARY_LAST 53
-
-#define DATA_CHANNEL_MAX_BINARY_FRAGMENT 0x4000
-
-#define DATA_CHANNEL_FLAGS_SEND_REQ             0x00000001
-#define DATA_CHANNEL_FLAGS_SEND_RSP             0x00000002
-#define DATA_CHANNEL_FLAGS_SEND_ACK             0x00000004
-#define DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED 0x00000008
-#define DATA_CHANNEL_FLAGS_SEND_DATA            0x00000010
-#define DATA_CHANNEL_FLAGS_FINISH_OPEN          0x00000020
-#define DATA_CHANNEL_FLAGS_FINISH_RSP           0x00000040
-
-#define INVALID_STREAM (0xFFFF)
-// max is 0xFFFF: Streams 0 to 0xFFFE = 0xFFFF streams
-#define MAX_NUM_STREAMS (2048)
-
-struct rtcweb_datachannel_open_request {
-  uint8_t  msg_type; // DATA_CHANNEL_OPEN
-  uint8_t  channel_type;  
-  uint16_t flags;
-  uint16_t reliability_params;
-  int16_t  priority;
-  char     label[1]; // keep VC++ happy...  UTF8 null-terminated string
-} SCTP_PACKED;
-
-struct rtcweb_datachannel_open_response {
-  uint8_t  msg_type; // DATA_CHANNEL_OPEN_RESPONSE
-  uint8_t  error;    // 0 == no error
-  uint16_t flags;
-  uint16_t reverse_stream;
-} SCTP_PACKED;
-
-struct rtcweb_datachannel_ack {
-  uint8_t  msg_type; // DATA_CHANNEL_ACK
-} SCTP_PACKED;
-
-/* msg_type values: */
-#define DATA_CHANNEL_OPEN_REQUEST             0
-#define DATA_CHANNEL_OPEN_RESPONSE            1
-#define DATA_CHANNEL_ACK                      2
-
-/* channel_type values: */
-#define DATA_CHANNEL_RELIABLE                 0
-#define DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT  1
-#define DATA_CHANNEL_PARTIAL_RELIABLE_TIMED   2
-
-/* flags values: */
-#define DATA_CHANNEL_FLAG_OUT_OF_ORDER_ALLOWED 0x0001
-/* all other bits reserved and should be set to 0 */
-
-
-#define ERR_DATA_CHANNEL_ALREADY_OPEN   1
-#define ERR_DATA_CHANNEL_NONE_AVAILABLE 2
-
-#if defined(_MSC_VER)
-#pragma pack (pop)
-#undef SCTP_PACKED
-#endif
-
-#endif
deleted file mode 100644
--- a/netwerk/sctp/datachannel/Makefile.in
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# 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/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE         = necko
-LIBRARY_NAME   = nkdatachan_s
-LIBXUL_LIBRARY = 1
-XPIDL_MODULE   = necko_datachan
-GRE_MODULE     = 1
-FORCE_STATIC_LIB = 1
-
-EXPORTS_NAMESPACES = mozilla/net
-
-CPPSRCS = \
-  DataChannel.cpp \
-  $(NULL)
-
-EXPORTS_mozilla/net = \
-  DataChannel.h \
-  DataChannelProtocol.h \
-  $(NULL)
-
-LOCAL_INCLUDES = \
-  -I$(topsrcdir)/xpcom/ds \
-  -I$(srcdir)/../src \
-  -I$(DEPTH)/dist/include/mozilla/net \
-  -I$(topsrcdir)/media/webrtc/trunk/third_party/libjingle/source \
-  -I$(topsrcdir)/media/mtransport \
-  $(NULL)
-
-DEFINES = \
-  -DINET=1 \
-  -DINET6=1 \
-  -DSCTP_DEBUG=1 \
-  $(NULL)
-
-ifeq ($(OS_TARGET),WINNT)
-DEFINES += -D__Userspace_os_Windows=1
-else
-ifeq ($(OS_TARGET),Darwin)
-DEFINES += -D__Userspace_os_Darwin=1
-else
-ifeq ($(OS_TARGET),Linux)
-DEFINES += -D__Userspace_os_Linux=1
-else
-ifeq ($(OS_TARGET),FreeBSD)
-DEFINES += -D__Userspace_os_FreeBSD=1
-else
-#default_fallback; probably doesn't work
-DEFINES += -D__Userspace_os_$(OS_TARGET)=1
-endif
-endif
-endif
-endif
-
-
-include $(topsrcdir)/config/config.mk
-include $(topsrcdir)/ipc/chromium/chromium-config.mk
-include $(topsrcdir)/config/rules.mk
-
-DEFINES += -DIMPL_NS_NET