Backed out 8 changesets (bug 1161020) for b2g ics emulator debug mochitest memory leaks on a CLOSED TREE
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 18 May 2015 15:01:27 +0200
changeset 263892 b0784c6cf4399d3b482b9364e5501e17ea02bed1
parent 263891 a72fa9e82843cf65feb4e06328e80036648fcaa0
child 263893 4e0dd9b21f4331e85b74984354dd60c638012f59
push id8157
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:36:23 +0000
treeherdermozilla-aurora@d480e05bd276 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1161020
milestone41.0a1
backs out976e19eac8b53df0702af23f56a9f25411be149d
4f782be31f873e311f3ef5817c074756351ec6f4
384de663084c72523ce4e9ef874f246b21920822
a8f42d85ce3f9938982a915ce61fa207d246afd0
ac23206e80bdc56b851defef69177699ffcbc2ab
34a20b05af6c5b6f5d0426a9602d19ed1db36c4a
13753f9043f72975ad483ae1564dc955c19f95e7
f90b8d3d6b709896b1a8b106ba84743610876ad3
Backed out 8 changesets (bug 1161020) for b2g ics emulator debug mochitest memory leaks on a CLOSED TREE Backed out changeset 976e19eac8b5 (bug 1161020) Backed out changeset 4f782be31f87 (bug 1161020) Backed out changeset 384de663084c (bug 1161020) Backed out changeset a8f42d85ce3f (bug 1161020) Backed out changeset ac23206e80bd (bug 1161020) Backed out changeset 34a20b05af6c (bug 1161020) Backed out changeset 13753f9043f7 (bug 1161020) Backed out changeset f90b8d3d6b70 (bug 1161020)
dom/bluetooth/bluedroid/BluetoothDaemonConnector.cpp
dom/bluetooth/bluedroid/BluetoothDaemonConnector.h
dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
dom/bluetooth/bluez/BluetoothSocket.cpp
dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp
dom/bluetooth/bluez/BluetoothUnixSocketConnector.h
dom/bluetooth/moz.build
dom/nfc/gonk/NfcService.cpp
ipc/keystore/KeyStore.cpp
ipc/keystore/KeyStore.h
ipc/keystore/KeyStoreConnector.cpp
ipc/keystore/KeyStoreConnector.h
ipc/keystore/moz.build
ipc/nfc/Nfc.cpp
ipc/nfc/Nfc.h
ipc/nfc/NfcConnector.cpp
ipc/nfc/NfcConnector.h
ipc/nfc/moz.build
ipc/ril/Ril.cpp
ipc/ril/RilConnector.cpp
ipc/ril/RilConnector.h
ipc/ril/moz.build
ipc/unixsocket/ListenSocket.cpp
ipc/unixsocket/StreamSocket.cpp
ipc/unixsocket/UnixSocketConnector.cpp
ipc/unixsocket/UnixSocketConnector.h
deleted file mode 100644
--- a/dom/bluetooth/bluedroid/BluetoothDaemonConnector.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 "BluetoothDaemonConnector.h"
-#include <fcntl.h>
-#include "nsISupportsImpl.h"
-
-BEGIN_BLUETOOTH_NAMESPACE
-
-BluetoothDaemonConnector::BluetoothDaemonConnector(
-  const nsACString& aSocketName)
-  : mSocketName(aSocketName)
-{
-  MOZ_COUNT_CTOR_INHERITED(BluetoothDaemonConnector, UnixSocketConnector);
-}
-
-BluetoothDaemonConnector::~BluetoothDaemonConnector()
-{
-  MOZ_COUNT_DTOR_INHERITED(BluetoothDaemonConnector, UnixSocketConnector);
-}
-
-nsresult
-BluetoothDaemonConnector::CreateSocket(int& aFd) const
-{
-  aFd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-  if (aFd < 0) {
-    BT_WARNING("Could not open Bluetooth daemon socket!");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-BluetoothDaemonConnector::SetSocketFlags(int aFd) const
-{
-  static const int sReuseAddress = 1;
-
-  // Set close-on-exec bit.
-  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= FD_CLOEXEC;
-  int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set non-blocking status flag.
-  flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= O_NONBLOCK;
-  res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set socket addr to be reused even if kernel is still waiting to close.
-  res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
-                   sizeof(sReuseAddress));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-BluetoothDaemonConnector::CreateAddress(struct sockaddr& aAddress,
-                                        socklen_t& aAddressLength) const
-{
-  static const size_t sNameOffset = 1;
-
-  struct sockaddr_un* address =
-    reinterpret_cast<struct sockaddr_un*>(&aAddress);
-
-  size_t namesiz = mSocketName.Length() + 1; // include trailing '\0'
-
-  if (NS_WARN_IF((sNameOffset + namesiz) > sizeof(address->sun_path))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  address->sun_family = AF_UNIX;
-  memset(address->sun_path, '\0', sNameOffset); // abstract socket
-  memcpy(address->sun_path + sNameOffset, mSocketName.get(), namesiz);
-
-  aAddressLength =
-    offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
-
-  return NS_OK;
-}
-
-// |UnixSocketConnector|
-
-nsresult
-BluetoothDaemonConnector::ConvertAddressToString(
-  const struct sockaddr& aAddress, socklen_t aAddressLength,
-  nsACString& aAddressString)
-{
-  MOZ_ASSERT(aAddress.sa_family == AF_UNIX);
-
-  const struct sockaddr_un* un =
-    reinterpret_cast<const struct sockaddr_un*>(&aAddress);
-
-  size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
-
-  aAddressString.Assign(un->sun_path, len);
-
-  return NS_OK;
-}
-
-nsresult
-BluetoothDaemonConnector::CreateListenSocket(struct sockaddr* aAddress,
-                                             socklen_t* aAddressLength,
-                                             int& aListenFd)
-{
-  ScopedClose fd;
-
-  nsresult rv = CreateSocket(fd.rwget());
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  if (aAddress && aAddressLength) {
-    rv = CreateAddress(*aAddress, *aAddressLength);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  aListenFd = fd.forget();
-
-  return NS_OK;
-}
-
-nsresult
-BluetoothDaemonConnector::AcceptStreamSocket(int aListenFd,
-                                             struct sockaddr* aAddress,
-                                             socklen_t* aAddressLength,
-                                             int& aStreamFd)
-{
-  ScopedClose fd(
-    TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
-  if (fd < 0) {
-    NS_WARNING("Cannot accept file descriptor!");
-    return NS_ERROR_FAILURE;
-  }
-  nsresult rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  aStreamFd = fd.forget();
-
-  return NS_OK;
-}
-
-nsresult
-BluetoothDaemonConnector::CreateStreamSocket(struct sockaddr* aAddress,
-                                             socklen_t* aAddressLength,
-                                             int& aStreamFd)
-{
-  MOZ_CRASH("|BluetoothDaemonConnector| does not support "
-            "creating stream sockets.");
-  return NS_ERROR_ABORT;
-}
-
-END_BLUETOOTH_NAMESPACE
deleted file mode 100644
--- a/dom/bluetooth/bluedroid/BluetoothDaemonConnector.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 mozilla_dom_bluetooth_bluedroid_bluetoothdaemonconnector_h
-#define mozilla_dom_bluetooth_bluedroid_bluetoothdaemonconnector_h
-
-#include "mozilla/dom/bluetooth/BluetoothCommon.h"
-#include "mozilla/ipc/UnixSocketConnector.h"
-
-BEGIN_BLUETOOTH_NAMESPACE
-
-class BluetoothDaemonConnector final
-  : public mozilla::ipc::UnixSocketConnector
-{
-public:
-  BluetoothDaemonConnector(const nsACString& aSocketName);
-  ~BluetoothDaemonConnector();
-
-  // Methods for |UnixSocketConnector|
-  //
-
-  nsresult ConvertAddressToString(const struct sockaddr& aAddress,
-                                  socklen_t aAddressLength,
-                                  nsACString& aAddressString) override;
-
-  nsresult CreateListenSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aListenFd) override;
-
-  nsresult AcceptStreamSocket(int aListenFd,
-                              struct sockaddr* aAddress,
-                              socklen_t* aAddressLen,
-                              int& aStreamFd) override;
-
-  nsresult CreateStreamSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aStreamFd) override;
-
-private:
-  nsresult CreateSocket(int& aFd) const;
-  nsresult SetSocketFlags(int aFd) const;
-  nsresult CreateAddress(struct sockaddr& aAddress,
-                         socklen_t& aAddressLength) const;
-
-  nsCString mSocketName;
-};
-
-END_BLUETOOTH_NAMESPACE
-
-#endif
--- a/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothDaemonInterface.cpp
@@ -5,23 +5,23 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "BluetoothDaemonInterface.h"
 #include <cutils/properties.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include "BluetoothDaemonA2dpInterface.h"
 #include "BluetoothDaemonAvrcpInterface.h"
-#include "BluetoothDaemonConnector.h"
 #include "BluetoothDaemonHandsfreeInterface.h"
 #include "BluetoothDaemonHelpers.h"
 #include "BluetoothDaemonSetupInterface.h"
 #include "BluetoothDaemonSocketInterface.h"
 #include "BluetoothInterfaceHelpers.h"
 #include "mozilla/ipc/ListenSocket.h"
+#include "mozilla/ipc/UnixSocketConnector.h"
 #include "mozilla/unused.h"
 #include "prrng.h"
 
 using namespace mozilla::ipc;
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 static const int sRetryInterval = 100; // ms
@@ -2013,16 +2013,88 @@ BluetoothDaemonInterface::OnDisconnect(e
       // Assume daemon crashed during regular service; notify
       // BluetoothServiceBluedroid to prepare restart-daemon procedure
       sNotificationHandler->BackendErrorNotification(true);
       sNotificationHandler = nullptr;
     }
   }
 }
 
+class BluetoothDaemonSocketConnector final
+  : public mozilla::ipc::UnixSocketConnector
+{
+public:
+  BluetoothDaemonSocketConnector(const nsACString& aSocketName)
+    : mSocketName(aSocketName)
+  { }
+
+  int
+  Create() override
+  {
+    MOZ_ASSERT(!NS_IsMainThread());
+
+    int fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+    if (fd < 0) {
+      BT_WARNING("Could not open socket!");
+      return -1;
+    }
+    return fd;
+  }
+
+  bool
+  CreateAddr(bool aIsServer,
+             socklen_t& aAddrSize,
+             sockaddr_any& aAddr,
+             const char* aAddress) override
+  {
+    static const size_t sNameOffset = 1;
+
+    size_t namesiz = mSocketName.Length() + 1; /* include trailing '\0' */
+
+    if ((sNameOffset + namesiz) > sizeof(aAddr.un.sun_path)) {
+      BT_WARNING("Address too long for socket struct!");
+      return false;
+    }
+
+    memset(aAddr.un.sun_path, '\0', sNameOffset); // abstract socket
+    memcpy(aAddr.un.sun_path + sNameOffset, mSocketName.get(), namesiz);
+    aAddr.un.sun_family = AF_UNIX;
+
+    aAddrSize = offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
+
+    return true;
+  }
+
+  bool
+  SetUp(int aFd) override
+  {
+    if (TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, O_NONBLOCK)) < 0) {
+      BT_WARNING("Failed to set non-blocking I/O.");
+      return false;
+    }
+    return true;
+  }
+
+  bool
+  SetUpListenSocket(int aFd) override
+  {
+    return true;
+  }
+
+  void
+  GetSocketAddr(const sockaddr_any& aAddr, nsAString& aAddrStr) override
+  {
+    // Unused.
+    MOZ_CRASH("This should never be called!");
+  }
+
+private:
+  nsCString mSocketName;
+};
+
 nsresult
 BluetoothDaemonInterface::CreateRandomAddressString(
   const nsACString& aPrefix, unsigned long aPostfixLength,
   nsACString& aAddress)
 {
   static const char sHexChar[16] = {
     [0x0] = '0', [0x1] = '1', [0x2] = '2', [0x3] = '3',
     [0x4] = '4', [0x5] = '5', [0x6] = '6', [0x7] = '7',
@@ -2132,17 +2204,17 @@ BluetoothDaemonInterface::Init(
   nsresult rv = CreateRandomAddressString(NS_LITERAL_CSTRING(BASE_SOCKET_NAME),
                                           POSTFIX_LENGTH,
                                           mListenSocketName);
   if (NS_FAILED(rv)) {
     mListenSocketName.AssignLiteral(BASE_SOCKET_NAME);
   }
 
   bool success = mListenSocket->Listen(
-    new BluetoothDaemonConnector(mListenSocketName), mCmdChannel);
+    new BluetoothDaemonSocketConnector(mListenSocketName), mCmdChannel);
   if (!success) {
     OnConnectError(CMD_CHANNEL);
     return;
   }
 
   // The protocol implementation needs a command channel for
   // sending commands to the daemon. We set it here, because
   // this is the earliest time when it's available.
--- a/dom/bluetooth/bluez/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluez/BluetoothSocket.cpp
@@ -25,20 +25,21 @@ static const size_t MAX_READ_SIZE = 1 <<
 
 class BluetoothSocket::BluetoothSocketIO final
   : public UnixSocketWatcher
   , public DataSocketIO
 {
 public:
   BluetoothSocketIO(MessageLoop* mIOLoop,
                     BluetoothSocket* aConsumer,
-                    UnixSocketConnector* aConnector);
+                    UnixSocketConnector* aConnector,
+                    const nsACString& aAddress);
   ~BluetoothSocketIO();
 
-  void GetSocketAddr(nsAString& aAddrStr) const;
+  void        GetSocketAddr(nsAString& aAddrStr) const;
 
   BluetoothSocket* GetBluetoothSocket();
   DataSocket* GetDataSocket();
 
   // Delayed-task handling
   //
 
   void SetDelayedConnectTask(CancelableTask* aTask);
@@ -88,16 +89,19 @@ public:
   void ShutdownOnMainThread() override;
   void ShutdownOnIOThread() override;
 
 private:
   class ReceiveRunnable;
 
   void FireSocketError();
 
+  // Set up flags on file descriptor.
+  static bool SetSocketFlags(int aFd);
+
   /**
    * Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
    * directly from main thread. All non-main-thread accesses should happen with
    * mIO as container.
    */
   RefPtr<BluetoothSocket> mConsumer;
 
   /**
@@ -106,45 +110,51 @@ private:
   nsAutoPtr<UnixSocketConnector> mConnector;
 
   /**
    * If true, do not requeue whatever task we're running
    */
   bool mShuttingDownOnIOThread;
 
   /**
-   * Number of valid bytes in |mAddress|
+   * Address we are connecting to, assuming we are creating a client connection.
    */
-  socklen_t mAddressLength;
+  nsCString mAddress;
 
   /**
-   * Address structure of the socket currently in use
+   * Size of the socket address struct
    */
-  struct sockaddr_storage mAddress;
+  socklen_t mAddrSize;
+
+  /**
+   * Address struct of the socket currently in use
+   */
+  sockaddr_any mAddr;
 
   /**
    * Task member for delayed connect task. Should only be access on main thread.
    */
   CancelableTask* mDelayedConnectTask;
 
   /**
    * I/O buffer for received data
    */
   nsAutoPtr<UnixSocketRawData> mBuffer;
 };
 
 BluetoothSocket::BluetoothSocketIO::BluetoothSocketIO(
   MessageLoop* mIOLoop,
   BluetoothSocket* aConsumer,
-  UnixSocketConnector* aConnector)
+  UnixSocketConnector* aConnector,
+  const nsACString& aAddress)
   : UnixSocketWatcher(mIOLoop)
   , mConsumer(aConsumer)
   , mConnector(aConnector)
   , mShuttingDownOnIOThread(false)
-  , mAddressLength(0)
+  , mAddress(aAddress)
   , mDelayedConnectTask(nullptr)
 {
   MOZ_ASSERT(mConsumer);
   MOZ_ASSERT(mConnector);
 }
 
 BluetoothSocket::BluetoothSocketIO::~BluetoothSocketIO()
 {
@@ -155,27 +165,17 @@ BluetoothSocket::BluetoothSocketIO::~Blu
 void
 BluetoothSocket::BluetoothSocketIO::GetSocketAddr(nsAString& aAddrStr) const
 {
   if (!mConnector) {
     NS_WARNING("No connector to get socket address from!");
     aAddrStr.Truncate();
     return;
   }
-
-  nsCString addressString;
-  nsresult rv = mConnector->ConvertAddressToString(
-    *reinterpret_cast<const struct sockaddr*>(&mAddress), mAddressLength,
-    addressString);
-  if (NS_FAILED(rv)) {
-    aAddrStr.Truncate();
-    return;
-  }
-
-  aAddrStr.Assign(NS_ConvertUTF8toUTF16(addressString));
+  mConnector->GetSocketAddr(mAddr, aAddrStr);
 }
 
 BluetoothSocket*
 BluetoothSocket::BluetoothSocketIO::GetBluetoothSocket()
 {
   return mConsumer.get();
 }
 
@@ -216,56 +216,82 @@ BluetoothSocket::BluetoothSocketIO::Canc
 
 void
 BluetoothSocket::BluetoothSocketIO::Listen()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(mConnector);
 
   if (!IsOpen()) {
-    mAddressLength = sizeof(mAddress);
-
-    int fd;
-    nsresult rv = mConnector->CreateListenSocket(
-      reinterpret_cast<struct sockaddr*>(&mAddress), &mAddressLength, fd);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
+    int fd = mConnector->Create();
+    if (fd < 0) {
+      NS_WARNING("Cannot create socket fd!");
+      FireSocketError();
+      return;
+    }
+    if (!SetSocketFlags(fd)) {
+      NS_WARNING("Cannot set socket flags!");
+      FireSocketError();
+      return;
+    }
+    if (!mConnector->SetUpListenSocket(fd)) {
+      NS_WARNING("Could not set up listen socket!");
+      FireSocketError();
+      return;
+    }
+    // This will set things we don't particularly care about, but it will hand
+    // back the correct structure size which is what we do care about.
+    if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) {
+      NS_WARNING("Cannot create socket address!");
       FireSocketError();
       return;
     }
     SetFd(fd);
 
     // calls OnListening on success, or OnError otherwise
-    rv = UnixSocketWatcher::Listen(
-      reinterpret_cast<struct sockaddr*>(&mAddress), mAddressLength);
+    nsresult rv = UnixSocketWatcher::Listen(
+      reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
     NS_WARN_IF(NS_FAILED(rv));
   }
 }
 
 void
 BluetoothSocket::BluetoothSocketIO::Connect()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(mConnector);
 
   if (!IsOpen()) {
-    mAddressLength = sizeof(mAddress);
-
-    int fd;
-    nsresult rv = mConnector->CreateStreamSocket(
-      reinterpret_cast<struct sockaddr*>(&mAddress), &mAddressLength, fd);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
+    int fd = mConnector->Create();
+    if (fd < 0) {
+      NS_WARNING("Cannot create socket fd!");
+      FireSocketError();
+      return;
+    }
+    if (!SetSocketFlags(fd)) {
+      NS_WARNING("Cannot set socket flags!");
+      FireSocketError();
+      return;
+    }
+    if (!mConnector->SetUp(fd)) {
+      NS_WARNING("Could not set up socket!");
+      FireSocketError();
+      return;
+    }
+    if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) {
+      NS_WARNING("Cannot create socket address!");
       FireSocketError();
       return;
     }
     SetFd(fd);
   }
 
   // calls OnConnected() on success, or OnError() otherwise
   nsresult rv = UnixSocketWatcher::Connect(
-    reinterpret_cast<struct sockaddr*>(&mAddress), mAddressLength);
+    reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
   NS_WARN_IF(NS_FAILED(rv));
 }
 
 void
 BluetoothSocket::BluetoothSocketIO::Send(UnixSocketIOBuffer* aBuffer)
 {
   EnqueueData(aBuffer);
   AddWatchers(WRITE_WATCHER, false);
@@ -307,24 +333,28 @@ BluetoothSocket::BluetoothSocketIO::OnEr
 void
 BluetoothSocket::BluetoothSocketIO::OnSocketCanAcceptWithoutBlocking()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING);
 
   RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
 
-  mAddressLength = sizeof(mAddress);
-
-  int fd;
-  nsresult rv = mConnector->AcceptStreamSocket(
-    GetFd(),
-    reinterpret_cast<struct sockaddr*>(&mAddress), &mAddressLength, fd);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    FireSocketError();
+  socklen_t mAddrSize = sizeof(mAddr);
+  int fd = TEMP_FAILURE_RETRY(accept(GetFd(),
+    reinterpret_cast<struct sockaddr*>(&mAddr), &mAddrSize));
+  if (fd < 0) {
+    OnError("accept", errno);
+    return;
+  }
+  if (!SetSocketFlags(fd)) {
+    return;
+  }
+  if (!mConnector->SetUp(fd)) {
+    NS_WARNING("Could not set up socket!");
     return;
   }
 
   Close();
   SetSocket(fd, SOCKET_IS_CONNECTED);
 
   NS_DispatchToMainThread(
     new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
@@ -376,16 +406,48 @@ BluetoothSocket::BluetoothSocketIO::Fire
   Close();
 
   // Tell the main thread we've errored
   NS_DispatchToMainThread(
     new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR));
 
 }
 
+bool
+BluetoothSocket::BluetoothSocketIO::SetSocketFlags(int aFd)
+{
+  // Set socket addr to be reused even if kernel is still waiting to close
+  int n = 1;
+  if (setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) < 0) {
+    return false;
+  }
+
+  // Set close-on-exec bit.
+  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
+  if (-1 == flags) {
+    return false;
+  }
+  flags |= FD_CLOEXEC;
+  if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) {
+    return false;
+  }
+
+  // Set non-blocking status flag.
+  flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
+  if (-1 == flags) {
+    return false;
+  }
+  flags |= O_NONBLOCK;
+  if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) {
+    return false;
+  }
+
+  return true;
+}
+
 // |DataSocketIO|
 
 nsresult
 BluetoothSocket::BluetoothSocketIO::QueryReceiveBuffer(
   UnixSocketIOBuffer** aBuffer)
 {
   MOZ_ASSERT(aBuffer);
 
@@ -579,18 +641,17 @@ bool
 BluetoothSocket::Connect(const nsAString& aDeviceAddress,
                          const BluetoothUuid& aServiceUuid,
                          int aChannel)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aDeviceAddress.IsEmpty());
 
   nsAutoPtr<BluetoothUnixSocketConnector> c(
-    new BluetoothUnixSocketConnector(NS_ConvertUTF16toUTF8(aDeviceAddress),
-                                     mType, aChannel, mAuth, mEncrypt));
+    new BluetoothUnixSocketConnector(mType, aChannel, mAuth, mEncrypt));
 
   if (!ConnectSocket(c.forget(),
                      NS_ConvertUTF16toUTF8(aDeviceAddress).BeginReading())) {
     nsAutoString addr;
     GetAddress(addr);
     BT_LOGD("%s failed. Current connected device address: %s",
            __FUNCTION__, NS_ConvertUTF16toUTF8(addr).get());
     return false;
@@ -602,18 +663,17 @@ BluetoothSocket::Connect(const nsAString
 bool
 BluetoothSocket::Listen(const nsAString& aServiceName,
                         const BluetoothUuid& aServiceUuid,
                         int aChannel)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsAutoPtr<BluetoothUnixSocketConnector> c(
-    new BluetoothUnixSocketConnector(NS_LITERAL_CSTRING(BLUETOOTH_ADDRESS_NONE),
-                                     mType, aChannel, mAuth, mEncrypt));
+    new BluetoothUnixSocketConnector(mType, aChannel, mAuth, mEncrypt));
 
   if (!ListenSocket(c.forget())) {
     nsAutoString addr;
     GetAddress(addr);
     BT_LOGD("%s failed. Current connected device address: %s",
            __FUNCTION__, NS_ConvertUTF16toUTF8(addr).get());
     return false;
   }
@@ -663,18 +723,19 @@ BluetoothSocket::ConnectSocket(Bluetooth
 
   nsAutoPtr<UnixSocketConnector> connector(aConnector);
 
   if (mIO) {
     NS_WARNING("Socket already connecting/connected!");
     return false;
   }
 
+  nsCString addr(aAddress);
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
-  mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
+  mIO = new BluetoothSocketIO(ioLoop, this, connector.forget(), addr);
   SetConnectionStatus(SOCKET_CONNECTING);
   if (aDelayMs > 0) {
     DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
     mIO->SetDelayedConnectTask(connectTask);
     MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
   } else {
     ioLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
   }
@@ -689,22 +750,20 @@ BluetoothSocket::ListenSocket(BluetoothU
 
   nsAutoPtr<UnixSocketConnector> connector(aConnector);
 
   if (mIO) {
     NS_WARNING("Socket already connecting/connected!");
     return false;
   }
 
-  MessageLoop* ioLoop = XRE_GetIOMessageLoop();
-
-  mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
+  mIO = new BluetoothSocketIO(
+    XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString());
   SetConnectionStatus(SOCKET_LISTENING);
-  ioLoop->PostTask(FROM_HERE, new ListenTask(mIO));
-
+  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ListenTask(mIO));
   return true;
 }
 
 // |DataSocket|
 
 void
 BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
 {
--- a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp
+++ b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.cpp
@@ -1,415 +1,285 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
-
 /*
  * Copyright 2009, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- * NOTE: Due to being based on the D-Bus compatibility layer for
- * Android's Bluetooth implementation, this file is licensed under the
- * Apache License instead of MPL.
+ * NOTE: Due to being based on the dbus compatibility layer for
+ * android's bluetooth implementation, this file is licensed under the
+ * apache license instead of MPL.
+ *
  */
 
-#include "BluetoothUnixSocketConnector.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#ifdef MOZ_B2G_BT_BLUEZ
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/l2cap.h>
 #include <bluetooth/rfcomm.h>
 #include <bluetooth/sco.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include "nsISupportsImpl.h" // For MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
+#endif
+#include "BluetoothUnixSocketConnector.h"
+#include "nsThreadUtils.h"
 
 using namespace mozilla::ipc;
-
-BEGIN_BLUETOOTH_NAMESPACE
+USING_BLUETOOTH_NAMESPACE
 
 static const int RFCOMM_SO_SNDBUF = 70 * 1024;  // 70 KB send buffer
 static const int L2CAP_SO_SNDBUF = 400 * 1024;  // 400 KB send buffer
 static const int L2CAP_SO_RCVBUF = 400 * 1024;  // 400 KB receive buffer
 static const int L2CAP_MAX_MTU = 65000;
 
+#ifdef MOZ_B2G_BT_BLUEZ
+static
+int get_bdaddr(const char *str, bdaddr_t *ba)
+{
+  char *d = ((char*)ba) + 5, *endp;
+  for (int i = 0; i < 6; i++) {
+    *d-- = strtol(str, &endp, 16);
+    MOZ_ASSERT(!(*endp != ':' && i != 5));
+    str = endp + 1;
+  }
+  return 0;
+}
+
+static
+void get_bdaddr_as_string(const bdaddr_t *ba, char *str) {
+    const uint8_t *b = (const uint8_t *)ba;
+    sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+            b[5], b[4], b[3], b[2], b[1], b[0]);
+}
+
+#endif
+
 BluetoothUnixSocketConnector::BluetoothUnixSocketConnector(
-  const nsACString& aAddressString,
   BluetoothSocketType aType,
   int aChannel,
   bool aAuth,
-  bool aEncrypt)
-  : mAddressString(aAddressString)
-  , mType(aType)
-  , mChannel(aChannel)
-  , mAuth(aAuth)
-  , mEncrypt(aEncrypt)
-{
-  MOZ_COUNT_CTOR_INHERITED(BluetoothUnixSocketConnector, UnixSocketConnector);
-}
-
-BluetoothUnixSocketConnector::~BluetoothUnixSocketConnector()
-{
-  MOZ_COUNT_DTOR_INHERITED(BluetoothUnixSocketConnector, UnixSocketConnector);
-}
-
-nsresult
-BluetoothUnixSocketConnector::CreateSocket(int& aFd) const
+  bool aEncrypt) : mType(aType)
+                 , mChannel(aChannel)
+                 , mAuth(aAuth)
+                 , mEncrypt(aEncrypt)
 {
-  static const int sType[] = {
-    [0] = 0,
-    [BluetoothSocketType::RFCOMM] = SOCK_STREAM,
-    [BluetoothSocketType::SCO] = SOCK_SEQPACKET,
-    [BluetoothSocketType::L2CAP] = SOCK_SEQPACKET,
-    [BluetoothSocketType::EL2CAP] = SOCK_STREAM
-  };
-  static const int sProtocol[] = {
-    [0] = 0,
-    [BluetoothSocketType::RFCOMM] = BTPROTO_RFCOMM,
-    [BluetoothSocketType::SCO] = BTPROTO_SCO,
-    [BluetoothSocketType::L2CAP] = BTPROTO_L2CAP,
-    [BluetoothSocketType::EL2CAP] = BTPROTO_L2CAP
-  };
-
-  MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sType));
-  MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sProtocol));
-
-  aFd = socket(AF_BLUETOOTH, sType[mType], sProtocol[mType]);
-  if (aFd < 0) {
-    BT_LOGR("Could not open Bluetooth socket!");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
 }
 
-nsresult
-BluetoothUnixSocketConnector::SetSocketFlags(int aFd) const
+bool
+BluetoothUnixSocketConnector::SetUp(int aFd)
 {
-  static const int sReuseAddress = 1;
-
-  // Set close-on-exec bit.
-  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= FD_CLOEXEC;
-  int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
+#ifdef MOZ_B2G_BT_BLUEZ
+  int lm = 0;
+  int sndbuf, rcvbuf;
 
-  // Set non-blocking status flag.
-  flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= O_NONBLOCK;
-  res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set socket addr to be reused even if kernel is still waiting to close.
-  res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
-                   sizeof(sReuseAddress));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  int lm;
-
+  /* kernel does not yet support LM for SCO */
   switch (mType) {
-    case BluetoothSocketType::RFCOMM:
-      lm |= mAuth ? RFCOMM_LM_AUTH : 0;
-      lm |= mEncrypt ? RFCOMM_LM_ENCRYPT : 0;
-      break;
-    case BluetoothSocketType::L2CAP:
-    case BluetoothSocketType::EL2CAP:
-      lm |= mAuth ? L2CAP_LM_AUTH : 0;
-      lm |= mEncrypt ? L2CAP_LM_ENCRYPT : 0;
-      break;
-    default:
-      // kernel does not yet support LM for SCO
-      lm = 0;
-      break;
+  case BluetoothSocketType::RFCOMM:
+    lm |= mAuth ? RFCOMM_LM_AUTH : 0;
+    lm |= mEncrypt ? RFCOMM_LM_ENCRYPT : 0;
+    break;
+  case BluetoothSocketType::L2CAP:
+  case BluetoothSocketType::EL2CAP:
+    lm |= mAuth ? L2CAP_LM_AUTH : 0;
+    lm |= mEncrypt ? L2CAP_LM_ENCRYPT : 0;
+    break;
+  case BluetoothSocketType::SCO:
+    break;
+  default:
+    MOZ_CRASH("Unknown socket type!");
   }
 
   if (lm) {
-    static const int sLevel[] = {
-      [0] = 0,
-      [BluetoothSocketType::RFCOMM] = SOL_RFCOMM,
-      [BluetoothSocketType::SCO] = 0,
-      [BluetoothSocketType::L2CAP] = SOL_L2CAP,
-      [BluetoothSocketType::EL2CAP] = SOL_L2CAP
-    };
-    static const int sOptname[] = {
-      [0] = 0,
-      [BluetoothSocketType::RFCOMM] = RFCOMM_LM,
-      [BluetoothSocketType::SCO] = 0,
-      [BluetoothSocketType::L2CAP] = L2CAP_LM,
-      [BluetoothSocketType::EL2CAP] = L2CAP_LM
-    };
-
-    MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sLevel));
-    MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sOptname));
-
-    if (setsockopt(aFd, sLevel[mType], sOptname[mType], &lm, sizeof(lm)) < 0) {
-      BT_LOGR("setsockopt(RFCOMM_LM) failed, throwing");
-      return NS_ERROR_FAILURE;
+    if (mType == BluetoothSocketType::RFCOMM) {
+      if (setsockopt(aFd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
+        BT_WARNING("setsockopt(RFCOMM_LM) failed, throwing");
+        return false;
+      }
+    } else if (mType == BluetoothSocketType::L2CAP ||
+               mType == BluetoothSocketType::EL2CAP) {
+      if (setsockopt(aFd, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm))) {
+        BT_WARNING("setsockopt(L2CAP_LM) failed, throwing");
+        return false;
+      }
     }
   }
 
   if (mType == BluetoothSocketType::RFCOMM) {
-
-    /* Setting RFCOMM socket options */
-
-    int sndbuf = RFCOMM_SO_SNDBUF;
+    sndbuf = RFCOMM_SO_SNDBUF;
     if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
       BT_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
-      return NS_ERROR_FAILURE;
+      return false;
     }
   }
 
+  /* Setting L2CAP socket options */
   if (mType == BluetoothSocketType::L2CAP ||
       mType == BluetoothSocketType::EL2CAP) {
-
-    /* Setting L2CAP/EL2CAP socket options */
-
     struct l2cap_options opts;
     socklen_t optlen = sizeof(opts);
-    int res = getsockopt(aFd, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen);
-    if (!res) {
+    int err;
+    err = getsockopt(aFd, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen);
+    if (!err) {
       /* setting MTU for [E]L2CAP */
       opts.omtu = opts.imtu = L2CAP_MAX_MTU;
 
       /* Enable ERTM for [E]L2CAP */
       if (mType == BluetoothSocketType::EL2CAP) {
         opts.flush_to = 0xffff; /* infinite */
         opts.mode = L2CAP_MODE_ERTM;
         opts.fcs = 1;
         opts.txwin_size = 64;
         opts.max_tx = 10;
       }
 
-      setsockopt(aFd, SOL_L2CAP, L2CAP_OPTIONS, &opts, optlen);
+      err = setsockopt(aFd, SOL_L2CAP, L2CAP_OPTIONS, &opts, optlen);
     }
 
+    /* Set larger SNDBUF & RCVBUF for EL2CAP connections */
     if (mType == BluetoothSocketType::EL2CAP) {
-
-      /* Set larger SNDBUF and RCVBUF for EL2CAP connections */
-
-      int sndbuf = L2CAP_SO_SNDBUF;
-      if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
-        BT_LOGR("setsockopt(SO_SNDBUF) failed, throwing");
-        return NS_ERROR_FAILURE;
+      sndbuf = L2CAP_SO_SNDBUF;
+      if (setsockopt(aFd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
+        BT_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
+        return false;
       }
 
-      int rcvbuf = L2CAP_SO_RCVBUF;
-      if (setsockopt(aFd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0) {
-        BT_LOGR("setsockopt(SO_RCVBUF) failed, throwing");
-        return NS_ERROR_FAILURE;
+      rcvbuf = L2CAP_SO_RCVBUF;
+      if (setsockopt(aFd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf))) {
+        BT_WARNING("setsockopt(SO_RCVBUF) failed, throwing");
+        return false;
       }
     }
   }
+#endif
+  return true;
+}
+
+bool
+BluetoothUnixSocketConnector::SetUpListenSocket(int aFd)
+{
+  // Nothing to do here.
+  return true;
+}
+
+int
+BluetoothUnixSocketConnector::Create()
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+  int fd = -1;
+
+#ifdef MOZ_B2G_BT_BLUEZ
+  switch (mType) {
+  case BluetoothSocketType::RFCOMM:
+    fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+    break;
+  case BluetoothSocketType::SCO:
+    fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
+    break;
+  case BluetoothSocketType::L2CAP:
+    fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+    break;
+  case BluetoothSocketType::EL2CAP:
+    fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP);
+    break;
+  default:
+    MOZ_CRASH();
+  }
+
+  if (fd < 0) {
+    BT_WARNING("Could not open bluetooth socket!");
+    return -1;
+  }
+
+  if (!SetUp(fd)) {
+    BT_WARNING("Could not set up socket!");
+    return -1;
+  }
+#endif
+  return fd;
+}
+
+bool
+BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
+                                         socklen_t& aAddrSize,
+                                         sockaddr_any& aAddr,
+                                         const char* aAddress)
+{
+#ifdef MOZ_B2G_BT_BLUEZ
+  // Set to BDADDR_ANY, if it's not a server, we'll reset.
+  bdaddr_t bd_address_obj = {{0, 0, 0, 0, 0, 0}};
+
+  if (!aIsServer && aAddress && strlen(aAddress) > 0) {
+    if (get_bdaddr(aAddress, &bd_address_obj)) {
+      BT_WARNING("Can't get bluetooth address!");
+      return false;
+    }
+  }
 
-  return NS_OK;
-}
-
-nsresult
-BluetoothUnixSocketConnector::CreateAddress(struct sockaddr& aAddress,
-                                            socklen_t& aAddressLength) const
-{
-  switch (mType) {
-    case BluetoothSocketType::RFCOMM: {
-        struct sockaddr_rc* rc =
-          reinterpret_cast<struct sockaddr_rc*>(&aAddress);
-        rc->rc_family = AF_BLUETOOTH;
-        nsresult rv = ConvertAddressString(mAddressString.get(),
-                                           rc->rc_bdaddr);
-        if (NS_FAILED(rv)) {
-          return rv;
-        }
-        rc->rc_channel = mChannel;
-        aAddressLength = sizeof(*rc);
-      }
-      break;
-    case BluetoothSocketType::L2CAP:
-    case BluetoothSocketType::EL2CAP: {
-        struct sockaddr_l2* l2 =
-          reinterpret_cast<struct sockaddr_l2*>(&aAddress);
-        l2->l2_family = AF_BLUETOOTH;
-        l2->l2_psm = mChannel;
-        nsresult rv = ConvertAddressString(mAddressString.get(),
-                                           l2->l2_bdaddr);
-        if (NS_FAILED(rv)) {
-          return rv;
-        }
-        l2->l2_cid = 0;
-        aAddressLength = sizeof(*l2);
-      }
-      break;
-    case BluetoothSocketType::SCO: {
-        struct sockaddr_sco* sco =
-          reinterpret_cast<struct sockaddr_sco*>(&aAddress);
-        sco->sco_family = AF_BLUETOOTH;
-        nsresult rv = ConvertAddressString(mAddressString.get(),
-                                           sco->sco_bdaddr);
-        if (NS_FAILED(rv)) {
-          return rv;
-        }
-        sco->sco_pkt_type = 0;
-        aAddressLength = sizeof(*sco);
-      }
-      break;
-    default:
-      MOZ_CRASH("Socket type unknown!");
-      return NS_ERROR_ABORT;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-BluetoothUnixSocketConnector::ConvertAddressString(const char* aAddressString,
-                                                   bdaddr_t& aAddress)
-{
-  char* d = reinterpret_cast<char*>(aAddress.b) + 5;
-
-  for (size_t i = 0; i < MOZ_ARRAY_LENGTH(aAddress.b); ++i) {
-    char* endp;
-    *d-- = strtoul(aAddressString, &endp, 16);
-    MOZ_ASSERT(!(*endp != ':' && i != 5));
-    aAddressString = endp + 1;
-  }
-  return NS_OK;
-}
-
-// |UnixSocketConnector|
-
-nsresult
-BluetoothUnixSocketConnector::ConvertAddressToString(
-  const struct sockaddr& aAddress, socklen_t aAddressLength,
-  nsACString& aAddressString)
-{
-  MOZ_ASSERT(aAddress.sa_family == AF_BLUETOOTH);
-
-  const uint8_t* b;
+  // Initialize
+  memset(&aAddr, 0, sizeof(aAddr));
 
   switch (mType) {
-    case BluetoothSocketType::RFCOMM: {
-        const struct sockaddr_rc* rc =
-          reinterpret_cast<const struct sockaddr_rc*>(&aAddress);
-        b = rc->rc_bdaddr.b;
-      }
-      break;
-    case BluetoothSocketType::SCO: {
-        const struct sockaddr_sco* sco =
-          reinterpret_cast<const struct sockaddr_sco*>(&aAddress);
-        b = sco->sco_bdaddr.b;
-      }
-      break;
-    case BluetoothSocketType::L2CAP:
-    case BluetoothSocketType::EL2CAP: {
-        const struct sockaddr_l2* l2 =
-          reinterpret_cast<const struct sockaddr_l2*>(&aAddress);
-        b = l2->l2_bdaddr.b;
-      }
-      break;
+  case BluetoothSocketType::RFCOMM:
+    struct sockaddr_rc addr_rc;
+    aAddrSize = sizeof(addr_rc);
+    aAddr.rc.rc_family = AF_BLUETOOTH;
+    aAddr.rc.rc_channel = mChannel;
+    memcpy(&aAddr.rc.rc_bdaddr, &bd_address_obj, sizeof(bd_address_obj));
+    break;
+  case BluetoothSocketType::L2CAP:
+  case BluetoothSocketType::EL2CAP:
+    struct sockaddr_l2 addr_l2;
+    aAddrSize = sizeof(addr_l2);
+    aAddr.l2.l2_family = AF_BLUETOOTH;
+    aAddr.l2.l2_psm = mChannel;
+    memcpy(&aAddr.l2.l2_bdaddr, &bd_address_obj, sizeof(bdaddr_t));
+    break;
+  case BluetoothSocketType::SCO:
+    struct sockaddr_sco addr_sco;
+    aAddrSize = sizeof(addr_sco);
+    aAddr.sco.sco_family = AF_BLUETOOTH;
+    memcpy(&aAddr.sco.sco_bdaddr, &bd_address_obj, sizeof(bd_address_obj));
+    break;
+  default:
+    BT_WARNING("Socket type unknown!");
+    return false;
   }
-
-  char str[32];
-  snprintf(str, sizeof(str), "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-           b[5], b[4], b[3], b[2], b[1], b[0]);
-
-  aAddressString.Assign(str);
-
-  return NS_OK;
+#endif
+  return true;
 }
 
-nsresult
-BluetoothUnixSocketConnector::CreateListenSocket(struct sockaddr* aAddress,
-                                                 socklen_t* aAddressLength,
-                                                 int& aListenFd)
+void
+BluetoothUnixSocketConnector::GetSocketAddr(const sockaddr_any& aAddr,
+                                            nsAString& aAddrStr)
 {
-  ScopedClose fd;
-
-  nsresult rv = CreateSocket(fd.rwget());
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  if (aAddress && aAddressLength) {
-    rv = CreateAddress(*aAddress, *aAddressLength);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  aListenFd = fd.forget();
-
-  return NS_OK;
-}
-
-nsresult
-BluetoothUnixSocketConnector::AcceptStreamSocket(int aListenFd,
-                                                 struct sockaddr* aAddress,
-                                                 socklen_t* aAddressLength,
-                                                 int& aStreamFd)
-{
-  ScopedClose fd(
-    TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
-  if (fd < 0) {
-    NS_WARNING("Cannot accept file descriptor!");
-    return NS_ERROR_FAILURE;
+#ifdef MOZ_B2G_BT_BLUEZ
+  char addr[18];
+  switch (mType) {
+  case BluetoothSocketType::RFCOMM:
+    get_bdaddr_as_string((bdaddr_t*)(&aAddr.rc.rc_bdaddr), addr);
+    break;
+  case BluetoothSocketType::SCO:
+    get_bdaddr_as_string((bdaddr_t*)(&aAddr.sco.sco_bdaddr), addr);
+    break;
+  case BluetoothSocketType::L2CAP:
+  case BluetoothSocketType::EL2CAP:
+    get_bdaddr_as_string((bdaddr_t*)(&aAddr.l2.l2_bdaddr), addr);
+    break;
+  default:
+    MOZ_CRASH("Socket should be either RFCOMM or SCO!");
   }
-  nsresult rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  aStreamFd = fd.forget();
-
-  return NS_OK;
+  aAddrStr.AssignASCII(addr);
+#endif
 }
-
-nsresult
-BluetoothUnixSocketConnector::CreateStreamSocket(struct sockaddr* aAddress,
-                                                 socklen_t* aAddressLength,
-                                                 int& aStreamFd)
-{
-  ScopedClose fd;
-
-  nsresult rv = CreateSocket(fd.rwget());
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  if (aAddress && aAddressLength) {
-    rv = CreateAddress(*aAddress, *aAddressLength);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  aStreamFd = fd.forget();
-
-  return NS_OK;
-}
-
-END_BLUETOOTH_NAMESPACE
--- a/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h
+++ b/dom/bluetooth/bluez/BluetoothUnixSocketConnector.h
@@ -3,58 +3,39 @@
 /* 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 mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
 #define mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
 
 #include "BluetoothCommon.h"
-#include "mozilla/ipc/UnixSocketConnector.h"
+#include <sys/socket.h>
+#include <mozilla/ipc/UnixSocketConnector.h>
 
 BEGIN_BLUETOOTH_NAMESPACE
 
-class BluetoothUnixSocketConnector final
-  : public mozilla::ipc::UnixSocketConnector
+class BluetoothUnixSocketConnector : public mozilla::ipc::UnixSocketConnector
 {
 public:
-  BluetoothUnixSocketConnector(const nsACString& aAddressString,
-                               BluetoothSocketType aType,
-                               int aChannel, bool aAuth, bool aEncrypt);
-  ~BluetoothUnixSocketConnector();
-
-  // Methods for |UnixSocketConnector|
-  //
-
-  nsresult ConvertAddressToString(const struct sockaddr& aAddress,
-                                  socklen_t aAddressLength,
-                                  nsACString& aAddressString) override;
-
-  nsresult CreateListenSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aListenFd) override;
-
-  nsresult AcceptStreamSocket(int aListenFd,
-                              struct sockaddr* aAddress,
-                              socklen_t* aAddressLen,
-                              int& aStreamFd) override;
-
-  nsresult CreateStreamSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aStreamFd) override;
+  BluetoothUnixSocketConnector(BluetoothSocketType aType, int aChannel,
+                               bool aAuth, bool aEncrypt);
+  virtual ~BluetoothUnixSocketConnector()
+  {}
+  virtual int Create() override;
+  virtual bool CreateAddr(bool aIsServer,
+                          socklen_t& aAddrSize,
+                          mozilla::ipc::sockaddr_any& aAddr,
+                          const char* aAddress) override;
+  virtual bool SetUp(int aFd) override;
+  virtual bool SetUpListenSocket(int aFd) override;
+  virtual void GetSocketAddr(const mozilla::ipc::sockaddr_any& aAddr,
+                             nsAString& aAddrStr) override;
 
 private:
-  nsresult CreateSocket(int& aFd) const;
-  nsresult SetSocketFlags(int aFd) const;
-  nsresult CreateAddress(struct sockaddr& aAddress,
-                         socklen_t& aAddressLength) const;
-  static nsresult ConvertAddressString(const char* aAddressString,
-                                       bdaddr_t& aAddress);
-
-  nsCString mAddressString;
   BluetoothSocketType mType;
   int mChannel;
   bool mAuth;
   bool mEncrypt;
 };
 
 END_BLUETOOTH_NAMESPACE
 
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -89,17 +89,16 @@ if CONFIG['MOZ_B2G_BT']:
             DEFINES['MOZ_B2G_BT_BLUEZ'] = True
         elif CONFIG['MOZ_B2G_BT_BLUEDROID']:
             SOURCES += [
                 'bluedroid/BluetoothA2dpHALInterface.cpp',
                 'bluedroid/BluetoothA2dpManager.cpp',
                 'bluedroid/BluetoothAvrcpHALInterface.cpp',
                 'bluedroid/BluetoothDaemonA2dpInterface.cpp',
                 'bluedroid/BluetoothDaemonAvrcpInterface.cpp',
-                'bluedroid/BluetoothDaemonConnector.cpp',
                 'bluedroid/BluetoothDaemonHandsfreeInterface.cpp',
                 'bluedroid/BluetoothDaemonHelpers.cpp',
                 'bluedroid/BluetoothDaemonInterface.cpp',
                 'bluedroid/BluetoothDaemonSetupInterface.cpp',
                 'bluedroid/BluetoothDaemonSocketInterface.cpp',
                 'bluedroid/BluetoothGattHALInterface.cpp',
                 'bluedroid/BluetoothHALHelpers.cpp',
                 'bluedroid/BluetoothHALInterface.cpp',
--- a/dom/nfc/gonk/NfcService.cpp
+++ b/dom/nfc/gonk/NfcService.cpp
@@ -7,17 +7,16 @@
 #include "NfcService.h"
 #include <binder/Parcel.h>
 #include <cutils/properties.h>
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/dom/NfcOptionsBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/RootedDictionary.h"
-#include "mozilla/ipc/NfcConnector.h"
 #include "mozilla/unused.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsXULAppAPI.h"
 #include "NfcOptions.h"
 
 #define NS_NFCSERVICE_CID \
   { 0x584c9a21, 0x4e17, 0x43b7, {0xb1, 0x6a, 0x87, 0xa0, 0x42, 0xef, 0xd4, 0x64} }
@@ -308,18 +307,17 @@ NfcService::Start(nsINfcGonkEventListene
   mListener = aListener;
   mHandler = new NfcMessageHandler();
   mConsumer = new NfcConsumer(this);
 
   mListenSocketName = BASE_SOCKET_NAME;
 
   mListenSocket = new NfcListenSocket(this);
 
-  bool success = mListenSocket->Listen(new NfcConnector(mListenSocketName),
-                                       mConsumer);
+  bool success = mListenSocket->Listen(new NfcConnector(), mConsumer);
   if (!success) {
     mConsumer = nullptr;
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv = NS_NewNamedThread("NfcThread", getter_AddRefs(mThread));
   if (NS_FAILED(rv)) {
     NS_WARNING("Can't create Nfc worker thread.");
--- a/ipc/keystore/KeyStore.cpp
+++ b/ipc/keystore/KeyStore.cpp
@@ -14,17 +14,16 @@
 #include <android/log.h>
 #define KEYSTORE_LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
 #else
 #define KEYSTORE_LOG(args...)  printf(args);
 #endif
 
 #include "KeyStore.h"
 #include "jsfriendapi.h"
-#include "KeyStoreConnector.h"
 #include "MainThreadUtils.h" // For NS_IsMainThread.
 #include "nsICryptoHash.h"
 
 #include "plbase64.h"
 #include "certdb.h"
 #include "ScopedNSSTypes.h"
 
 using namespace mozilla::ipc;
@@ -300,16 +299,17 @@ void startKeyStoreService() { return; }
 
 static const char *CA_BEGIN = "-----BEGIN ",
                   *CA_END   = "-----END ",
                   *CA_TAILER = "-----\n";
 
 namespace mozilla {
 namespace ipc {
 
+static const char* KEYSTORE_SOCKET_PATH = "/dev/socket/keystore";
 static const char* KEYSTORE_ALLOWED_USERS[] = {
   "root",
   "wifi",
   NULL
 };
 static const char* KEYSTORE_ALLOWED_PREFIXES[] = {
   "WIFI_SERVERCERT_",
   "WIFI_USERCERT_",
@@ -667,16 +667,86 @@ checkPermission(uid_t uid)
     if (!strcmp(*user, userInfo->pw_name)) {
       return true;
     }
   }
 
   return false;
 }
 
+int
+KeyStoreConnector::Create()
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  int fd;
+
+  unlink(KEYSTORE_SOCKET_PATH);
+
+  fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+
+  if (fd < 0) {
+    NS_WARNING("Could not open keystore socket!");
+    return -1;
+  }
+
+  return fd;
+}
+
+bool
+KeyStoreConnector::CreateAddr(bool aIsServer,
+                              socklen_t& aAddrSize,
+                              sockaddr_any& aAddr,
+                              const char* aAddress)
+{
+  // Keystore socket must be server
+  MOZ_ASSERT(aIsServer);
+
+  aAddr.un.sun_family = AF_LOCAL;
+  if(strlen(KEYSTORE_SOCKET_PATH) > sizeof(aAddr.un.sun_path)) {
+      NS_WARNING("Address too long for socket struct!");
+      return false;
+  }
+  strcpy((char*)&aAddr.un.sun_path, KEYSTORE_SOCKET_PATH);
+  aAddrSize = strlen(KEYSTORE_SOCKET_PATH) + offsetof(struct sockaddr_un, sun_path) + 1;
+
+  return true;
+}
+
+bool
+KeyStoreConnector::SetUp(int aFd)
+{
+  // Socket permission check.
+  struct ucred userCred;
+  socklen_t len = sizeof(struct ucred);
+
+  if (getsockopt(aFd, SOL_SOCKET, SO_PEERCRED, &userCred, &len)) {
+    return false;
+  }
+
+  return ::checkPermission(userCred.uid);
+}
+
+bool
+KeyStoreConnector::SetUpListenSocket(int aFd)
+{
+  // Allow access of wpa_supplicant(different user, differnt group)
+  chmod(KEYSTORE_SOCKET_PATH, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+
+  return true;
+}
+
+void
+KeyStoreConnector::GetSocketAddr(const sockaddr_any& aAddr,
+                                 nsAString& aAddrStr)
+{
+  // Unused.
+  MOZ_CRASH("This should never be called!");
+}
+
 //
 // KeyStore::ListenSocket
 //
 
 KeyStore::ListenSocket::ListenSocket(KeyStore* aKeyStore)
 : mKeyStore(aKeyStore)
 {
   MOZ_ASSERT(mKeyStore);
@@ -743,17 +813,17 @@ void
 KeyStore::StreamSocket::ReceiveSocketData(nsAutoPtr<UnixSocketBuffer>& aBuffer)
 {
   mKeyStore->ReceiveSocketData(aBuffer);
 }
 
 ConnectionOrientedSocketIO*
 KeyStore::StreamSocket::GetIO()
 {
-  return PrepareAccept(new KeyStoreConnector(KEYSTORE_ALLOWED_USERS));
+  return PrepareAccept(new KeyStoreConnector());
 }
 
 //
 // KeyStore
 //
 
 KeyStore::KeyStore()
 : mShutdown(false)
@@ -802,18 +872,17 @@ KeyStore::Listen()
     mStreamSocket->Close();
   } else {
     mStreamSocket = new StreamSocket(this);
   }
 
   if (!mListenSocket) {
     // We only ever allocate one |ListenSocket|...
     mListenSocket = new ListenSocket(this);
-    mListenSocket->Listen(new KeyStoreConnector(KEYSTORE_ALLOWED_USERS),
-                          mStreamSocket);
+    mListenSocket->Listen(new KeyStoreConnector(), mStreamSocket);
   } else {
     // ... but keep it open.
     mListenSocket->Listen(mStreamSocket);
   }
 
   ResetHandlerInfo();
 }
 
--- a/ipc/keystore/KeyStore.h
+++ b/ipc/keystore/KeyStore.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_ipc_KeyStore_h
 #define mozilla_ipc_KeyStore_h 1
 
 #include <sys/socket.h>
 #include <sys/un.h>
 #include "cert.h"
 #include "mozilla/ipc/ListenSocket.h"
 #include "mozilla/ipc/StreamSocket.h"
+#include "mozilla/ipc/UnixSocketConnector.h"
 #include "nsNSSShutDown.h"
 
 namespace mozilla {
 namespace ipc {
 
 enum ResponseCode {
   SUCCESS           =  1,
   LOCKED            =  2,
@@ -73,16 +74,36 @@ struct ProtocolParam{
 
 typedef enum {
   STATE_IDLE,
   STATE_READ_PARAM_LEN,
   STATE_READ_PARAM_DATA,
   STATE_PROCESSING
 } ProtocolHandlerState;
 
+class KeyStoreConnector : public mozilla::ipc::UnixSocketConnector
+{
+public:
+  KeyStoreConnector()
+  {}
+
+  virtual ~KeyStoreConnector()
+  {}
+
+  virtual int Create();
+  virtual bool CreateAddr(bool aIsServer,
+                          socklen_t& aAddrSize,
+                          sockaddr_any& aAddr,
+                          const char* aAddress);
+  virtual bool SetUp(int aFd);
+  virtual bool SetUpListenSocket(int aFd);
+  virtual void GetSocketAddr(const sockaddr_any& aAddr,
+                             nsAString& aAddrStr);
+};
+
 class KeyStore final : public nsNSSShutDownObject
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(KeyStore)
 
   KeyStore();
 
   void Shutdown();
deleted file mode 100644
--- a/ipc/keystore/KeyStoreConnector.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=2 et ft=cpp: 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 "KeyStoreConnector.h"
-#include <fcntl.h>
-#include <pwd.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include "nsISupportsImpl.h" // For MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
-
-#ifdef MOZ_WIDGET_GONK
-#include <android/log.h>
-#define KEYSTORE_LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
-#else
-#define KEYSTORE_LOG(args...)  printf(args);
-#endif
-
-namespace mozilla {
-namespace ipc {
-
-static const char KEYSTORE_SOCKET_PATH[] = "/dev/socket/keystore";
-
-KeyStoreConnector::KeyStoreConnector(const char** const aAllowedUsers)
-  : mAllowedUsers(aAllowedUsers)
-{
-  MOZ_COUNT_CTOR_INHERITED(KeyStoreConnector, UnixSocketConnector);
-}
-
-KeyStoreConnector::~KeyStoreConnector()
-{
-  MOZ_COUNT_DTOR_INHERITED(KeyStoreConnector, UnixSocketConnector);
-}
-
-nsresult
-KeyStoreConnector::CreateSocket(int& aFd) const
-{
-  unlink(KEYSTORE_SOCKET_PATH);
-
-  aFd = socket(AF_LOCAL, SOCK_STREAM, 0);
-  if (aFd < 0) {
-    KEYSTORE_LOG("Could not open KeyStore socket!");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-KeyStoreConnector::SetSocketFlags(int aFd) const
-{
-  static const int sReuseAddress = 1;
-
-  // Set close-on-exec bit.
-  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= FD_CLOEXEC;
-  int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set non-blocking status flag.
-  flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= O_NONBLOCK;
-  res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set socket addr to be reused even if kernel is still waiting to close.
-  res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
-                   sizeof(sReuseAddress));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-KeyStoreConnector::CheckPermission(int aFd) const
-{
-  struct ucred userCred;
-  socklen_t len = sizeof(userCred);
-
-  if (getsockopt(aFd, SOL_SOCKET, SO_PEERCRED, &userCred, &len)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  const struct passwd* userInfo = getpwuid(userCred.uid);
-  if (!userInfo) {
-    return NS_ERROR_FAILURE;
-  }
-
-  if (!mAllowedUsers) {
-    return NS_ERROR_FAILURE;
-  }
-
-  for (const char** user = mAllowedUsers; *user; ++user) {
-    if (!strcmp(*user, userInfo->pw_name)) {
-      return NS_OK;
-    }
-  }
-
-  return NS_ERROR_FAILURE;
-}
-
-nsresult
-KeyStoreConnector::CreateAddress(struct sockaddr& aAddress,
-                                 socklen_t& aAddressLength) const
-{
-  struct sockaddr_un* address =
-    reinterpret_cast<struct sockaddr_un*>(&aAddress);
-
-  size_t namesiz = strlen(KEYSTORE_SOCKET_PATH) + 1; // include trailing '\0'
-
-  if (namesiz > sizeof(address->sun_path)) {
-      KEYSTORE_LOG("Address too long for socket struct!");
-      return NS_ERROR_FAILURE;
-  }
-
-  address->sun_family = AF_UNIX;
-  memcpy(address->sun_path, KEYSTORE_SOCKET_PATH, namesiz);
-
-  aAddressLength = offsetof(struct sockaddr_un, sun_path) + namesiz;
-
-  return NS_OK;
-}
-
-// |UnixSocketConnector|
-
-nsresult
-KeyStoreConnector::ConvertAddressToString(const struct sockaddr& aAddress,
-                                          socklen_t aAddressLength,
-                                          nsACString& aAddressString)
-{
-  MOZ_ASSERT(aAddress.sa_family == AF_UNIX);
-
-  const struct sockaddr_un* un =
-    reinterpret_cast<const struct sockaddr_un*>(&aAddress);
-
-  size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
-
-  aAddressString.Assign(un->sun_path, len);
-
-  return NS_OK;
-}
-
-nsresult
-KeyStoreConnector::CreateListenSocket(struct sockaddr* aAddress,
-                                      socklen_t* aAddressLength,
-                                      int& aListenFd)
-{
-  ScopedClose fd;
-
-  nsresult rv = CreateSocket(fd.rwget());
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  if (aAddress && aAddressLength) {
-    rv = CreateAddress(*aAddress, *aAddressLength);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  // Allow access for wpa_supplicant (different user, different group)
-  //
-  // TODO: Improve this by setting specific user/group for
-  //       wpa_supplicant by calling |fchmod| and |fchown|.
-  //
-  chmod(KEYSTORE_SOCKET_PATH, S_IRUSR|S_IWUSR|
-                              S_IRGRP|S_IWGRP|
-                              S_IROTH|S_IWOTH);
-
-  aListenFd = fd.forget();
-
-  return NS_OK;
-}
-
-nsresult
-KeyStoreConnector::AcceptStreamSocket(int aListenFd,
-                                      struct sockaddr* aAddress,
-                                      socklen_t* aAddressLength,
-                                      int& aStreamFd)
-{
-  ScopedClose fd(
-    TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
-  if (fd < 0) {
-    NS_WARNING("Cannot accept file descriptor!");
-    return NS_ERROR_FAILURE;
-  }
-  nsresult rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = CheckPermission(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  aStreamFd = fd.forget();
-
-  return NS_OK;
-}
-
-nsresult
-KeyStoreConnector::CreateStreamSocket(struct sockaddr* aAddress,
-                                      socklen_t* aAddressLength,
-                                      int& aStreamFd)
-{
-  MOZ_CRASH("|KeyStoreConnector| does not support creating stream sockets.");
-  return NS_ERROR_FAILURE;
-}
-
-}
-}
deleted file mode 100644
--- a/ipc/keystore/KeyStoreConnector.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=2 et ft=cpp: 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 mozilla_ipc_KeyStoreConnector_h
-#define mozilla_ipc_KeyStoreConnector_h
-
-#include "mozilla/ipc/UnixSocketConnector.h"
-
-namespace mozilla {
-namespace ipc {
-
-class KeyStoreConnector final : public UnixSocketConnector
-{
-public:
-  KeyStoreConnector(const char** const aAllowedUsers);
-  ~KeyStoreConnector();
-
-  // Methods for |UnixSocketConnector|
-  //
-
-  nsresult ConvertAddressToString(const struct sockaddr& aAddress,
-                                  socklen_t aAddressLength,
-                                  nsACString& aAddressString) override;
-
-  nsresult CreateListenSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aListenFd) override;
-
-  nsresult AcceptStreamSocket(int aListenFd,
-                              struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aStreamFd) override;
-
-  nsresult CreateStreamSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aStreamFd) override;
-
-private:
-  nsresult CreateSocket(int& aFd) const;
-  nsresult SetSocketFlags(int aFd) const;
-  nsresult CheckPermission(int aFd) const;
-  nsresult CreateAddress(struct sockaddr& aAddress,
-                         socklen_t& aAddressLength) const;
-
-  const char** const mAllowedUsers;
-};
-
-}
-}
-
-#endif
--- a/ipc/keystore/moz.build
+++ b/ipc/keystore/moz.build
@@ -4,17 +4,16 @@
 # 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/.
 
 EXPORTS.mozilla.ipc += [
   'KeyStore.h'
 ]
 
 SOURCES += [
-  'KeyStore.cpp',
-  'KeyStoreConnector.cpp'
+  'KeyStore.cpp'
 ]
 
 FAIL_ON_WARNINGS = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
--- a/ipc/nfc/Nfc.cpp
+++ b/ipc/nfc/Nfc.cpp
@@ -17,17 +17,16 @@
 #include <android/log.h>
 #define CHROMIUM_LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
 #else
 #define CHROMIUM_LOG(args...)
 #endif
 
 #include "jsfriendapi.h"
 #include "mozilla/ArrayUtils.h"
-#include "mozilla/ipc/NfcConnector.h"
 #include "nsThreadUtils.h" // For NS_IsMainThread.
 
 using namespace mozilla::ipc;
 
 namespace {
 
 class SendNfcSocketDataTask final : public nsRunnable
 {
@@ -57,16 +56,84 @@ private:
 };
 
 } // anonymous namespace
 
 namespace mozilla {
 namespace ipc {
 
 //
+// NfcConnector
+//
+
+int
+NfcConnector::Create()
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+  if (fd < 0) {
+    NS_WARNING("Could not open nfc socket!");
+    return -1;
+  }
+
+  if (!SetUp(fd)) {
+    NS_WARNING("Could not set up socket!");
+  }
+  return fd;
+}
+
+bool
+NfcConnector::CreateAddr(bool aIsServer,
+                         socklen_t& aAddrSize,
+                         sockaddr_any& aAddr,
+                         const char* aAddress)
+{
+  static const size_t sNameOffset = 1;
+
+  nsDependentCString socketName("nfcd");
+
+  size_t namesiz = socketName.Length() + 1; /* include trailing '\0' */
+
+  if ((sNameOffset + namesiz) > sizeof(aAddr.un.sun_path)) {
+    NS_WARNING("Address too long for socket struct!");
+    return false;
+  }
+
+  memset(aAddr.un.sun_path, '\0', sNameOffset); // abstract socket
+  memcpy(aAddr.un.sun_path + sNameOffset, socketName.get(), namesiz);
+  aAddr.un.sun_family = AF_UNIX;
+
+  aAddrSize = offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
+
+  return true;
+}
+
+bool
+NfcConnector::SetUp(int aFd)
+{
+  // Nothing to do here.
+  return true;
+}
+
+bool
+NfcConnector::SetUpListenSocket(int aFd)
+{
+  // Nothing to do here.
+  return true;
+}
+
+void
+NfcConnector::GetSocketAddr(const sockaddr_any& aAddr,
+                            nsAString& aAddrStr)
+{
+  MOZ_CRASH("This should never be called!");
+}
+
+//
 // NfcListenSocket
 //
 
 NfcListenSocket::NfcListenSocket(NfcSocketListener* aListener)
   : mListener(aListener)
 { }
 
 void
@@ -159,13 +226,13 @@ NfcConsumer::OnDisconnect()
   if (mListener) {
     mListener->OnDisconnect(NfcSocketListener::STREAM_SOCKET);
   }
 }
 
 ConnectionOrientedSocketIO*
 NfcConsumer::GetIO()
 {
-  return PrepareAccept(new NfcConnector(NS_LITERAL_CSTRING("nfcd")));
+  return PrepareAccept(new NfcConnector());
 }
 
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/nfc/Nfc.h
+++ b/ipc/nfc/Nfc.h
@@ -6,16 +6,17 @@
 
 /* Copyright © 2013, Deutsche Telekom, Inc. */
 
 #ifndef mozilla_ipc_Nfc_h
 #define mozilla_ipc_Nfc_h 1
 
 #include <mozilla/ipc/ListenSocket.h>
 #include <mozilla/ipc/StreamSocket.h>
+#include <mozilla/ipc/UnixSocketConnector.h>
 
 namespace mozilla {
 namespace ipc {
 
 class NfcSocketListener
 {
 public:
   enum SocketType {
@@ -38,16 +39,33 @@ public:
   void OnConnectSuccess() override;
   void OnConnectError() override;
   void OnDisconnect() override;
 
 private:
   NfcSocketListener* mListener;
 };
 
+class NfcConnector final : public mozilla::ipc::UnixSocketConnector
+{
+public:
+  NfcConnector()
+  { }
+
+  int Create() override;
+  bool CreateAddr(bool aIsServer,
+                  socklen_t& aAddrSize,
+                  sockaddr_any& aAddr,
+                  const char* aAddress) override;
+  bool SetUp(int aFd) override;
+  bool SetUpListenSocket(int aFd) override;
+  void GetSocketAddr(const sockaddr_any& aAddr,
+                     nsAString& aAddrStr) override;
+};
+
 class NfcConsumer final : public mozilla::ipc::StreamSocket
 {
 public:
   NfcConsumer(NfcSocketListener* aListener);
 
   void Shutdown();
   bool PostToNfcDaemon(const uint8_t* aData, size_t aSize);
 
deleted file mode 100644
--- a/ipc/nfc/NfcConnector.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=2 ts=8 et ft=cpp: */
-
-/* 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 "NfcConnector.h"
-#include <fcntl.h>
-#include <sys/un.h>
-#include "nsISupportsImpl.h" // For MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
-
-namespace mozilla {
-namespace ipc {
-
-NfcConnector::NfcConnector(const nsACString& aAddressString)
-  : mAddressString(aAddressString)
-{
-  MOZ_COUNT_CTOR_INHERITED(NfcConnector, UnixSocketConnector);
-}
-
-NfcConnector::~NfcConnector()
-{
-  MOZ_COUNT_DTOR_INHERITED(NfcConnector, UnixSocketConnector);
-}
-
-nsresult
-NfcConnector::CreateSocket(int& aFd) const
-{
-  aFd = socket(AF_LOCAL, SOCK_STREAM, 0);
-  if (aFd < 0) {
-    NS_WARNING("Could not open NFC socket!");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-NfcConnector::SetSocketFlags(int aFd) const
-{
-  static const int sReuseAddress = 1;
-
-  // Set close-on-exec bit.
-  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= FD_CLOEXEC;
-  int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set non-blocking status flag.
-  flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= O_NONBLOCK;
-  res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set socket addr to be reused even if kernel is still waiting to close.
-  res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
-                   sizeof(sReuseAddress));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-NfcConnector::CreateAddress(struct sockaddr& aAddress,
-                            socklen_t& aAddressLength) const
-{
-  static const size_t sNameOffset = 1;
-
-  struct sockaddr_un* address =
-    reinterpret_cast<struct sockaddr_un*>(&aAddress);
-
-  size_t namesiz = mAddressString.Length() + 1; // include trailing '\0'
-
-  if (NS_WARN_IF((sNameOffset + namesiz) > sizeof(address->sun_path))) {
-    return NS_ERROR_FAILURE;
-  }
-
-  address->sun_family = AF_UNIX;
-  memset(address->sun_path, '\0', sNameOffset); // abstract socket
-  memcpy(address->sun_path + sNameOffset, mAddressString.get(), namesiz);
-
-  aAddressLength =
-    offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz;
-
-  return NS_OK;
-}
-
-// |UnixSocketConnector|
-//
-
-nsresult
-NfcConnector::ConvertAddressToString(const struct sockaddr& aAddress,
-                                     socklen_t aAddressLength,
-                                     nsACString& aAddressString)
-{
-  MOZ_ASSERT(aAddress.sa_family == AF_UNIX);
-
-  const struct sockaddr_un* un =
-    reinterpret_cast<const struct sockaddr_un*>(&aAddress);
-
-  size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
-
-  aAddressString.Assign(un->sun_path, len);
-
-  return NS_OK;
-}
-
-nsresult
-NfcConnector::CreateListenSocket(struct sockaddr* aAddress,
-                                 socklen_t* aAddressLength,
-                                 int& aListenFd)
-{
-  ScopedClose fd;
-
-  nsresult rv = CreateSocket(fd.rwget());
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  if (aAddress && aAddressLength) {
-    rv = CreateAddress(*aAddress, *aAddressLength);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  aListenFd = fd.forget();
-
-  return NS_OK;
-}
-
-nsresult
-NfcConnector::AcceptStreamSocket(int aListenFd,
-                                 struct sockaddr* aAddress,
-                                 socklen_t* aAddressLength,
-                                 int& aStreamFd)
-{
-  ScopedClose fd(
-    TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength)));
-  if (fd < 0) {
-    NS_WARNING("Cannot accept file descriptor!");
-    return NS_ERROR_FAILURE;
-  }
-  nsresult rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  aStreamFd = fd.forget();
-
-  return NS_OK;
-}
-
-nsresult
-NfcConnector::CreateStreamSocket(struct sockaddr* aAddress,
-                                 socklen_t* aAddressLength,
-                                 int& aStreamFd)
-{
-  ScopedClose fd;
-
-  nsresult rv = CreateSocket(fd.rwget());
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  if (aAddress && aAddressLength) {
-    rv = CreateAddress(*aAddress, *aAddressLength);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  aStreamFd = fd.forget();
-
-  return NS_OK;
-}
-
-}
-}
deleted file mode 100644
--- a/ipc/nfc/NfcConnector.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=2 ts=8 et ft=cpp: */
-
-/* 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 mozilla_ipc_NfcConnector_h
-#define mozilla_ipc_NfcConnector_h
-
-#include "mozilla/ipc/UnixSocketConnector.h"
-
-namespace mozilla {
-namespace ipc {
-
-/**
- * |NfcConnector| creates sockets for communicating with
- * the NFC daemon.
- */
-class NfcConnector final : public UnixSocketConnector
-{
-public:
-  NfcConnector(const nsACString& aAddressString);
-  ~NfcConnector();
-
-  // Methods for |UnixSocketConnector|
-  //
-
-  nsresult ConvertAddressToString(const struct sockaddr& aAddress,
-                                  socklen_t aAddressLength,
-                                  nsACString& aAddressString) override;
-
-  nsresult CreateListenSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aListenFd) override;
-
-  nsresult AcceptStreamSocket(int aListenFd,
-                              struct sockaddr* aAddress,
-                              socklen_t* aAddressLen,
-                              int& aStreamFd) override;
-
-  nsresult CreateStreamSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aStreamFd) override;
-
-private:
-  nsresult CreateSocket(int& aFd) const;
-  nsresult SetSocketFlags(int aFd) const;
-  nsresult CreateAddress(struct sockaddr& aAddress,
-                         socklen_t& aAddressLength) const;
-
-  nsCString mAddressString;
-};
-
-}
-}
-
-#endif
--- a/ipc/nfc/moz.build
+++ b/ipc/nfc/moz.build
@@ -1,20 +1,18 @@
 # vim: set filetype=python:
 # 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/.
 
 if CONFIG['MOZ_NFC']:
     EXPORTS.mozilla.ipc += [
         'Nfc.h',
-        'NfcConnector.h',
     ]
     SOURCES += [
         'Nfc.cpp',
-        'NfcConnector.cpp',
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 FAIL_ON_WARNINGS = True
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -16,27 +16,31 @@
 #include <android/log.h>
 #define CHROMIUM_LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
 #else
 #define CHROMIUM_LOG(args...)  printf(args);
 #endif
 
 #include "jsfriendapi.h"
 #include "mozilla/ArrayUtils.h"
+#include "mozilla/ipc/UnixSocketConnector.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h" // For NS_IsMainThread.
-#include "RilConnector.h"
 
 USING_WORKERS_NAMESPACE
 using namespace mozilla::ipc;
 
 namespace {
 
 static const char RIL_SOCKET_NAME[] = "/dev/socket/rilproxy";
 
+// Network port to connect to for adb forwarded sockets when doing
+// desktop development.
+static const uint32_t RIL_TEST_PORT = 6200;
+
 static nsTArray<nsRefPtr<mozilla::ipc::RilConsumer> > sRilConsumers;
 
 class ConnectWorkerToRIL final : public WorkerTask
 {
 public:
   bool RunTask(JSContext* aCx) override;
 };
 
@@ -190,16 +194,119 @@ DispatchRILEvent::RunTask(JSContext* aCx
   JS::AutoValueArray<2> args(aCx);
   args[0].setNumber((uint32_t)mClientId);
   args[1].setObject(*array);
 
   JS::Rooted<JS::Value> rval(aCx);
   return JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
 }
 
+class RilConnector final : public mozilla::ipc::UnixSocketConnector
+{
+public:
+  RilConnector(unsigned long aClientId)
+    : mClientId(aClientId)
+  { }
+
+  int Create() override;
+  bool CreateAddr(bool aIsServer,
+                  socklen_t& aAddrSize,
+                  sockaddr_any& aAddr,
+                  const char* aAddress) override;
+  bool SetUp(int aFd) override;
+  bool SetUpListenSocket(int aFd) override;
+  void GetSocketAddr(const sockaddr_any& aAddr,
+                     nsAString& aAddrStr) override;
+
+private:
+  unsigned long mClientId;
+};
+
+int
+RilConnector::Create()
+{
+  MOZ_ASSERT(!NS_IsMainThread());
+
+  int fd = -1;
+
+#if defined(MOZ_WIDGET_GONK)
+  fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+#else
+  // If we can't hit a local loopback, fail later in connect.
+  fd = socket(AF_INET, SOCK_STREAM, 0);
+#endif
+
+  if (fd < 0) {
+    NS_WARNING("Could not open ril socket!");
+    return -1;
+  }
+
+  if (!SetUp(fd)) {
+    NS_WARNING("Could not set up socket!");
+  }
+  return fd;
+}
+
+bool
+RilConnector::CreateAddr(bool aIsServer,
+                         socklen_t& aAddrSize,
+                         sockaddr_any& aAddr,
+                         const char* aAddress)
+{
+  // We never open ril socket as server.
+  MOZ_ASSERT(!aIsServer);
+  uint32_t af;
+#if defined(MOZ_WIDGET_GONK)
+  af = AF_LOCAL;
+#else
+  af = AF_INET;
+#endif
+  switch (af) {
+  case AF_LOCAL:
+    aAddr.un.sun_family = af;
+    if(strlen(aAddress) > sizeof(aAddr.un.sun_path)) {
+      NS_WARNING("Address too long for socket struct!");
+      return false;
+    }
+    strcpy((char*)&aAddr.un.sun_path, aAddress);
+    aAddrSize = strlen(aAddress) + offsetof(struct sockaddr_un, sun_path) + 1;
+    break;
+  case AF_INET:
+    aAddr.in.sin_family = af;
+    aAddr.in.sin_port = htons(RIL_TEST_PORT + mClientId);
+    aAddr.in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    aAddrSize = sizeof(sockaddr_in);
+    break;
+  default:
+    NS_WARNING("Socket type not handled by connector!");
+    return false;
+  }
+  return true;
+}
+
+bool
+RilConnector::SetUp(int aFd)
+{
+  // Nothing to do here.
+  return true;
+}
+
+bool
+RilConnector::SetUpListenSocket(int aFd)
+{
+  // Nothing to do here.
+  return true;
+}
+
+void
+RilConnector::GetSocketAddr(const sockaddr_any& aAddr, nsAString& aAddrStr)
+{
+  MOZ_CRASH("This should never be called!");
+}
+
 } // anonymous namespace
 
 namespace mozilla {
 namespace ipc {
 
 RilConsumer::RilConsumer(unsigned long aClientId,
                          WorkerCrossThreadDispatcher* aDispatcher)
   : mDispatcher(aDispatcher)
@@ -212,17 +319,17 @@ RilConsumer::RilConsumer(unsigned long a
     mAddress = RIL_SOCKET_NAME;
   } else {
     struct sockaddr_un addr_un;
     snprintf(addr_un.sun_path, sizeof addr_un.sun_path, "%s%lu",
              RIL_SOCKET_NAME, aClientId);
     mAddress = addr_un.sun_path;
   }
 
-  Connect(new RilConnector(mAddress, mClientId), mAddress.get());
+  Connect(new RilConnector(mClientId), mAddress.get());
 }
 
 nsresult
 RilConsumer::Register(unsigned int aClientId,
                       WorkerCrossThreadDispatcher* aDispatcher)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -284,21 +391,21 @@ RilConsumer::OnConnectError()
   Close();
 }
 
 void
 RilConsumer::OnDisconnect()
 {
   CHROMIUM_LOG("RIL[%lu]: %s\n", mClientId, __FUNCTION__);
   if (!mShutdown) {
-    Connect(new RilConnector(mAddress, mClientId), mAddress.get(),
+    Connect(new RilConnector(mClientId), mAddress.get(),
             GetSuggestedConnectDelayMs());
   }
 }
 
 ConnectionOrientedSocketIO*
 RilConsumer::GetIO()
 {
-  return PrepareAccept(new RilConnector(mAddress, mClientId));
+  return PrepareAccept(new RilConnector(mClientId));
 }
 
 } // namespace ipc
 } // namespace mozilla
deleted file mode 100644
--- a/ipc/ril/RilConnector.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 "RilConnector.h"
-#include <fcntl.h>
-#include <sys/socket.h>
-#include "nsISupportsImpl.h" // For MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
-
-#ifdef AF_INET
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#endif
-#ifdef AF_UNIX
-#include <sys/un.h>
-#endif
-
-namespace mozilla {
-namespace ipc {
-
-static const uint16_t RIL_TEST_PORT = 6200;
-
-RilConnector::RilConnector(const nsACString& aAddressString,
-                           unsigned long aClientId)
-  : mAddressString(aAddressString)
-  , mClientId(aClientId)
-{
-  MOZ_COUNT_CTOR_INHERITED(RilConnector, UnixSocketConnector);
-}
-
-RilConnector::~RilConnector()
-{
-  MOZ_COUNT_DTOR_INHERITED(RilConnector, UnixSocketConnector);
-}
-
-nsresult
-RilConnector::CreateSocket(int aDomain, int& aFd) const
-{
-  aFd = socket(aDomain, SOCK_STREAM, 0);
-  if (aFd < 0) {
-    NS_WARNING("Could not open RIL socket!");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-RilConnector::SetSocketFlags(int aFd) const
-{
-  static const int sReuseAddress = 1;
-
-  // Set close-on-exec bit.
-  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= FD_CLOEXEC;
-  int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set non-blocking status flag.
-  flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
-  if (flags < 0) {
-    return NS_ERROR_FAILURE;
-  }
-  flags |= O_NONBLOCK;
-  res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // Set socket addr to be reused even if kernel is still waiting to close.
-  res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress,
-                   sizeof(sReuseAddress));
-  if (res < 0) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-RilConnector::CreateAddress(int aDomain,
-                            struct sockaddr& aAddress,
-                            socklen_t& aAddressLength) const
-{
-  switch (aDomain) {
-#ifdef AF_UNIX
-    case AF_UNIX: {
-        struct sockaddr_un* address =
-          reinterpret_cast<struct sockaddr_un*>(&aAddress);
-        address->sun_family = aDomain;
-        size_t siz = mAddressString.Length() + 1;
-        if (siz > sizeof(address->sun_path)) {
-          NS_WARNING("Address too long for socket struct!");
-          return NS_ERROR_FAILURE;
-        }
-        memcpy(address->sun_path, mAddressString.get(), siz);
-        aAddressLength = offsetof(struct sockaddr_un, sun_path) + siz;
-      }
-      break;
-#endif
-#ifdef AF_INET
-    case AF_INET: {
-        struct sockaddr_in* address =
-          reinterpret_cast<struct sockaddr_in*>(&aAddress);
-        address->sin_family = aDomain;
-        address->sin_port = htons(RIL_TEST_PORT + mClientId);
-        address->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-        aAddressLength = sizeof(*address);
-      }
-      break;
-#endif
-    default:
-      NS_WARNING("Address family not handled by connector!");
-      return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-// |UnixSocketConnector|
-
-nsresult
-RilConnector::ConvertAddressToString(const struct sockaddr& aAddress,
-                                     socklen_t aAddressLength,
-                                     nsACString& aAddressString)
-{
-#ifdef AF_UNIX
-  if (aAddress.sa_family == AF_UNIX) {
-    const struct sockaddr_un* un =
-      reinterpret_cast<const struct sockaddr_un*>(&aAddress);
-
-    size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path);
-
-    aAddressString.Assign(un->sun_path, len);
-  } else
-#endif
-#ifdef AF_INET
-  if (aAddress.sa_family == AF_INET) {
-    const struct sockaddr_in* in =
-      reinterpret_cast<const struct sockaddr_in*>(&aAddress);
-
-    aAddressString.Assign(nsDependentCString(inet_ntoa(in->sin_addr)));
-  } else
-#endif
-  {
-    NS_WARNING("Address family not handled by connector!");
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-RilConnector::CreateListenSocket(struct sockaddr* aAddress,
-                                 socklen_t* aAddressLength,
-                                 int& aListenFd)
-{
-  MOZ_CRASH("|RilConnector| does not support listening sockets.");
-}
-
-nsresult
-RilConnector::AcceptStreamSocket(int aListenFd,
-                                 struct sockaddr* aAddress,
-                                 socklen_t* aAddressLen,
-                                 int& aStreamFd)
-{
-  MOZ_CRASH("|RilConnector| does not support accepting sockets.");
-}
-
-nsresult
-RilConnector::CreateStreamSocket(struct sockaddr* aAddress,
-                                 socklen_t* aAddressLength,
-                                 int& aStreamFd)
-{
-#ifdef MOZ_WIDGET_GONK
-  static const int sDomain = AF_UNIX;
-#else
-  static const int sDomain = AF_INET;
-#endif
-
-  ScopedClose fd;
-
-  nsresult rv = CreateSocket(sDomain, fd.rwget());
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  rv = SetSocketFlags(fd);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  if (aAddress && aAddressLength) {
-    rv = CreateAddress(sDomain, *aAddress, *aAddressLength);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-  }
-
-  aStreamFd = fd.forget();
-
-  return NS_OK;
-}
-
-}
-}
deleted file mode 100644
--- a/ipc/ril/RilConnector.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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 mozilla_ipc_RilConnector_h
-#define mozilla_ipc_RilConnector_h
-
-#include "mozilla/ipc/UnixSocketConnector.h"
-
-namespace mozilla {
-namespace ipc {
-
-/**
- * |RilConnector| creates sockets for connecting to rild.
- */
-class RilConnector final : public UnixSocketConnector
-{
-public:
-  RilConnector(const nsACString& aAddressString,
-               unsigned long aClientId);
-  ~RilConnector();
-
-  // Methods for |UnixSocketConnector|
-  //
-
-  nsresult ConvertAddressToString(const struct sockaddr& aAddress,
-                                  socklen_t aAddressLength,
-                                  nsACString& aAddressString) override;
-
-  nsresult CreateListenSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aListenFd) override;
-
-  nsresult AcceptStreamSocket(int aListenFd,
-                              struct sockaddr* aAddress,
-                              socklen_t* aAddressLen,
-                              int& aStreamFd) override;
-
-  nsresult CreateStreamSocket(struct sockaddr* aAddress,
-                              socklen_t* aAddressLength,
-                              int& aStreamFd) override;
-
-private:
-  nsresult CreateSocket(int aDomain, int& aFd) const;
-  nsresult SetSocketFlags(int aFd) const;
-  nsresult CreateAddress(int aDomain,
-                         struct sockaddr& aAddress,
-                         socklen_t& aAddressLength) const;
-
-  nsCString mAddressString;
-  unsigned long mClientId;
-};
-
-}
-}
-
-#endif
--- a/ipc/ril/moz.build
+++ b/ipc/ril/moz.build
@@ -5,16 +5,15 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.ipc += [
     'Ril.h',
 ]
 
 SOURCES += [
     'Ril.cpp',
-    'RilConnector.cpp'
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 FAIL_ON_WARNINGS = True
--- a/ipc/unixsocket/ListenSocket.cpp
+++ b/ipc/unixsocket/ListenSocket.cpp
@@ -23,17 +23,18 @@ class ListenSocketIO final
   : public UnixSocketWatcher
   , public SocketIOBase
 {
 public:
   class ListenTask;
 
   ListenSocketIO(MessageLoop* mIOLoop,
                  ListenSocket* aListenSocket,
-                 UnixSocketConnector* aConnector);
+                 UnixSocketConnector* aConnector,
+                 const nsACString& aAddress);
   ~ListenSocketIO();
 
   void GetSocketAddr(nsAString& aAddrStr) const;
 
   // Task callback methods
   //
 
   /**
@@ -58,16 +59,19 @@ public:
   bool IsShutdownOnIOThread() const override;
 
   void ShutdownOnMainThread() override;
   void ShutdownOnIOThread() override;
 
 private:
   void FireSocketError();
 
+  // Set up flags on file descriptor.
+  static bool SetSocketFlags(int aFd);
+
   /**
    * Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
    * directly from main thread. All non-main-thread accesses should happen with
    * mIO as container.
    */
   RefPtr<ListenSocket> mListenSocket;
 
   /**
@@ -76,37 +80,43 @@ private:
   nsAutoPtr<UnixSocketConnector> mConnector;
 
   /**
    * If true, do not requeue whatever task we're running
    */
   bool mShuttingDownOnIOThread;
 
   /**
-   * Number of valid bytes in |mAddress|
+   * Address we are connecting to, assuming we are creating a client connection.
    */
-  socklen_t mAddressLength;
+  nsCString mAddress;
 
   /**
-   * Address structure of the socket currently in use
+   * Size of the socket address struct
    */
-  struct sockaddr_storage mAddress;
+  socklen_t mAddrSize;
+
+  /**
+   * Address struct of the socket currently in use
+   */
+  sockaddr_any mAddr;
 
   ConnectionOrientedSocketIO* mCOSocketIO;
 };
 
 ListenSocketIO::ListenSocketIO(MessageLoop* mIOLoop,
                                ListenSocket* aListenSocket,
-                               UnixSocketConnector* aConnector)
+                               UnixSocketConnector* aConnector,
+                               const nsACString& aAddress)
   : UnixSocketWatcher(mIOLoop)
   , SocketIOBase()
   , mListenSocket(aListenSocket)
   , mConnector(aConnector)
   , mShuttingDownOnIOThread(false)
-  , mAddressLength(0)
+  , mAddress(aAddress)
   , mCOSocketIO(nullptr)
 {
   MOZ_ASSERT(mListenSocket);
   MOZ_ASSERT(mConnector);
 }
 
 ListenSocketIO::~ListenSocketIO()
 {
@@ -117,53 +127,59 @@ ListenSocketIO::~ListenSocketIO()
 void
 ListenSocketIO::GetSocketAddr(nsAString& aAddrStr) const
 {
   if (!mConnector) {
     NS_WARNING("No connector to get socket address from!");
     aAddrStr.Truncate();
     return;
   }
-
-  nsCString addressString;
-  nsresult rv = mConnector->ConvertAddressToString(
-    *reinterpret_cast<const struct sockaddr*>(&mAddress), mAddressLength,
-    addressString);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  aAddrStr.Assign(NS_ConvertUTF8toUTF16(addressString));
+  mConnector->GetSocketAddr(mAddr, aAddrStr);
 }
 
 void
 ListenSocketIO::Listen(ConnectionOrientedSocketIO* aCOSocketIO)
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(mConnector);
   MOZ_ASSERT(aCOSocketIO);
 
-  struct sockaddr* address = reinterpret_cast<struct sockaddr*>(&mAddress);
-  mAddressLength = sizeof(mAddress);
-
   if (!IsOpen()) {
-    int fd;
-    nsresult rv = mConnector->CreateListenSocket(address, &mAddressLength,
-                                                 fd);
-    if (NS_FAILED(rv)) {
+    int fd = mConnector->Create();
+    if (fd < 0) {
+      NS_WARNING("Cannot create socket fd!");
+      FireSocketError();
+      return;
+    }
+    if (!SetSocketFlags(fd)) {
+      NS_WARNING("Cannot set socket flags!");
+      FireSocketError();
+      return;
+    }
+    if (!mConnector->SetUpListenSocket(GetFd())) {
+      NS_WARNING("Could not set up listen socket!");
+      FireSocketError();
+      return;
+    }
+    // This will set things we don't particularly care about, but
+    // it will hand back the correct structure size which is what
+    // we do care about.
+    if (!mConnector->CreateAddr(true, mAddrSize, mAddr, nullptr)) {
+      NS_WARNING("Cannot create socket address!");
       FireSocketError();
       return;
     }
     SetFd(fd);
   }
 
   mCOSocketIO = aCOSocketIO;
 
   // calls OnListening on success, or OnError otherwise
-  nsresult rv = UnixSocketWatcher::Listen(address, mAddressLength);
+  nsresult rv = UnixSocketWatcher::Listen(
+    reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
   NS_WARN_IF(NS_FAILED(rv));
 }
 
 void
 ListenSocketIO::OnConnected()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
 
@@ -200,41 +216,72 @@ ListenSocketIO::FireSocketError()
   // Clean up watchers, statuses, fds
   Close();
 
   // Tell the main thread we've errored
   NS_DispatchToMainThread(
     new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR));
 }
 
+bool
+ListenSocketIO::SetSocketFlags(int aFd)
+{
+  static const int reuseaddr = 1;
+
+  // Set socket addr to be reused even if kernel is still waiting to close
+  int res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR,
+                       &reuseaddr, sizeof(reuseaddr));
+  if (res < 0) {
+    return false;
+  }
+
+  // Set close-on-exec bit.
+  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
+  if (-1 == flags) {
+    return false;
+  }
+  flags |= FD_CLOEXEC;
+  if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) {
+    return false;
+  }
+
+  // Set non-blocking status flag.
+  flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
+  if (-1 == flags) {
+    return false;
+  }
+  flags |= O_NONBLOCK;
+  if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) {
+    return false;
+  }
+
+  return true;
+}
+
 void
 ListenSocketIO::OnSocketCanAcceptWithoutBlocking()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING);
   MOZ_ASSERT(mCOSocketIO);
 
-  RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
-
-  struct sockaddr_storage storage;
-  socklen_t addressLength = sizeof(storage);
-
-  int fd;
-  nsresult rv = mConnector->AcceptStreamSocket(
-    GetFd(),
-    reinterpret_cast<struct sockaddr*>(&storage), &addressLength,
-    fd);
-  if (NS_FAILED(rv)) {
-    FireSocketError();
+  struct sockaddr_storage addr;
+  socklen_t addrLen = sizeof(addr);
+  int fd = TEMP_FAILURE_RETRY(accept(GetFd(),
+    reinterpret_cast<struct sockaddr*>(&addr), &addrLen));
+  if (fd < 0) {
+    OnError("accept", errno);
     return;
   }
 
+  RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
+
   mCOSocketIO->Accept(fd,
-                      reinterpret_cast<union sockaddr_any*>(&storage),
-                      addressLength);
+                      reinterpret_cast<union sockaddr_any*>(&addr),
+                      addrLen);
 }
 
 // |SocketIOBase|
 
 SocketBase*
 ListenSocketIO::GetSocketBase()
 {
   return mListenSocket.get();
@@ -345,17 +392,18 @@ ListenSocket::Listen(UnixSocketConnector
 
   nsAutoPtr<UnixSocketConnector> connector(aConnector);
 
   if (mIO) {
     NS_WARNING("Socket already connecting/connected!");
     return false;
   }
 
-  mIO = new ListenSocketIO(XRE_GetIOMessageLoop(), this, connector.forget());
+  mIO = new ListenSocketIO(
+    XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString());
 
   // Prepared I/O object, now start listening.
   return Listen(aCOSocket);
 }
 
 bool
 ListenSocket::Listen(ConnectionOrientedSocket* aCOSocket)
 {
--- a/ipc/unixsocket/StreamSocket.cpp
+++ b/ipc/unixsocket/StreamSocket.cpp
@@ -25,21 +25,23 @@ class StreamSocketIO final
 {
 public:
   class ConnectTask;
   class DelayedConnectTask;
   class ReceiveRunnable;
 
   StreamSocketIO(MessageLoop* mIOLoop,
                  StreamSocket* aStreamSocket,
-                 UnixSocketConnector* aConnector);
+                 UnixSocketConnector* aConnector,
+                 const nsACString& aAddress);
   StreamSocketIO(MessageLoop* mIOLoop, int aFd,
                  ConnectionStatus aConnectionStatus,
                  StreamSocket* aStreamSocket,
-                 UnixSocketConnector* aConnector);
+                 UnixSocketConnector* aConnector,
+                 const nsACString& aAddress);
   ~StreamSocketIO();
 
   void GetSocketAddr(nsAString& aAddrStr) const;
 
   StreamSocket* GetStreamSocket();
   DataSocket* GetDataSocket();
 
   // Delayed-task handling
@@ -91,16 +93,19 @@ public:
   bool IsShutdownOnIOThread() const override;
 
   void ShutdownOnMainThread() override;
   void ShutdownOnIOThread() override;
 
 private:
   void FireSocketError();
 
+  // Set up flags on file descriptor.
+  static bool SetSocketFlags(int aFd);
+
   /**
    * Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
    * directly from main thread. All non-main-thread accesses should happen with
    * mIO as container.
    */
   RefPtr<StreamSocket> mStreamSocket;
 
   /**
@@ -109,59 +114,66 @@ private:
   nsAutoPtr<UnixSocketConnector> mConnector;
 
   /**
    * If true, do not requeue whatever task we're running
    */
   bool mShuttingDownOnIOThread;
 
   /**
-   * Number of valid bytes in |mAddress|
+   * Address we are connecting to, assuming we are creating a client connection.
    */
-  socklen_t mAddressLength;
+  nsCString mAddress;
 
   /**
-   * Address structure of the socket currently in use
+   * Size of the socket address struct
    */
-  struct sockaddr_storage mAddress;
+  socklen_t mAddrSize;
+
+  /**
+   * Address struct of the socket currently in use
+   */
+  sockaddr_any mAddr;
 
   /**
    * Task member for delayed connect task. Should only be access on main thread.
    */
   CancelableTask* mDelayedConnectTask;
 
   /**
    * I/O buffer for received data
    */
   nsAutoPtr<UnixSocketRawData> mBuffer;
 };
 
 StreamSocketIO::StreamSocketIO(MessageLoop* mIOLoop,
                                StreamSocket* aStreamSocket,
-                               UnixSocketConnector* aConnector)
+                               UnixSocketConnector* aConnector,
+                               const nsACString& aAddress)
   : UnixSocketWatcher(mIOLoop)
   , mStreamSocket(aStreamSocket)
   , mConnector(aConnector)
   , mShuttingDownOnIOThread(false)
-  , mAddressLength(0)
+  , mAddress(aAddress)
   , mDelayedConnectTask(nullptr)
 {
   MOZ_ASSERT(mStreamSocket);
   MOZ_ASSERT(mConnector);
 }
 
 StreamSocketIO::StreamSocketIO(MessageLoop* mIOLoop, int aFd,
                                ConnectionStatus aConnectionStatus,
                                StreamSocket* aStreamSocket,
-                               UnixSocketConnector* aConnector)
+                               UnixSocketConnector* aConnector,
+                               const nsACString& aAddress)
   : UnixSocketWatcher(mIOLoop, aFd, aConnectionStatus)
   , mStreamSocket(aStreamSocket)
   , mConnector(aConnector)
   , mShuttingDownOnIOThread(false)
-  , mAddressLength(0)
+  , mAddress(aAddress)
   , mDelayedConnectTask(nullptr)
 {
   MOZ_ASSERT(mStreamSocket);
   MOZ_ASSERT(mConnector);
 }
 
 StreamSocketIO::~StreamSocketIO()
 {
@@ -172,26 +184,17 @@ StreamSocketIO::~StreamSocketIO()
 void
 StreamSocketIO::GetSocketAddr(nsAString& aAddrStr) const
 {
   if (!mConnector) {
     NS_WARNING("No connector to get socket address from!");
     aAddrStr.Truncate();
     return;
   }
-
-  nsCString addressString;
-  nsresult rv = mConnector->ConvertAddressToString(
-    *reinterpret_cast<const struct sockaddr*>(&mAddress), mAddressLength,
-    addressString);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  aAddrStr.Assign(NS_ConvertUTF8toUTF16(addressString));
+  mConnector->GetSocketAddr(mAddr, aAddrStr);
 }
 
 StreamSocket*
 StreamSocketIO::GetStreamSocket()
 {
   return mStreamSocket.get();
 }
 
@@ -231,31 +234,44 @@ StreamSocketIO::CancelDelayedConnectTask
 }
 
 void
 StreamSocketIO::Connect()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(mConnector);
 
-  MOZ_ASSERT(!IsOpen());
-
-  struct sockaddr* address = reinterpret_cast<struct sockaddr*>(&mAddress);
-  mAddressLength = sizeof(mAddress);
-
-  int fd;
-  nsresult rv = mConnector->CreateStreamSocket(address, &mAddressLength, fd);
-  if (NS_FAILED(rv)) {
-    FireSocketError();
-    return;
+  if (!IsOpen()) {
+    int fd = mConnector->Create();
+    if (fd < 0) {
+      NS_WARNING("Cannot create socket fd!");
+      FireSocketError();
+      return;
+    }
+    if (!SetSocketFlags(fd)) {
+      NS_WARNING("Cannot set socket flags!");
+      FireSocketError();
+      return;
+    }
+    if (!mConnector->SetUp(GetFd())) {
+      NS_WARNING("Could not set up socket!");
+      FireSocketError();
+      return;
+    }
+    if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) {
+      NS_WARNING("Cannot create socket address!");
+      FireSocketError();
+      return;
+    }
+    SetFd(fd);
   }
-  SetFd(fd);
 
   // calls OnConnected() on success, or OnError() otherwise
-  rv = UnixSocketWatcher::Connect(address, mAddressLength);
+  nsresult rv = UnixSocketWatcher::Connect(
+    reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
   NS_WARN_IF(NS_FAILED(rv));
 }
 
 void
 StreamSocketIO::Send(UnixSocketIOBuffer* aData)
 {
   EnqueueData(aData);
   AddWatchers(WRITE_WATCHER, false);
@@ -333,30 +349,75 @@ StreamSocketIO::FireSocketError()
   // Clean up watchers, statuses, fds
   Close();
 
   // Tell the main thread we've errored
   NS_DispatchToMainThread(
     new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_ERROR));
 }
 
+bool
+StreamSocketIO::SetSocketFlags(int aFd)
+{
+  static const int reuseaddr = 1;
+
+  // Set socket addr to be reused even if kernel is still waiting to close
+  int res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR,
+                       &reuseaddr, sizeof(reuseaddr));
+  if (res < 0) {
+    return false;
+  }
+
+  // Set close-on-exec bit.
+  int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD));
+  if (-1 == flags) {
+    return false;
+  }
+  flags |= FD_CLOEXEC;
+  if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags))) {
+    return false;
+  }
+
+  // Set non-blocking status flag.
+  flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
+  if (-1 == flags) {
+    return false;
+  }
+  flags |= O_NONBLOCK;
+  if (-1 == TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags))) {
+    return false;
+  }
+
+  return true;
+}
+
 // |ConnectionOrientedSocketIO|
 
 nsresult
 StreamSocketIO::Accept(int aFd,
                        const union sockaddr_any* aAddr, socklen_t aAddrLen)
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTING);
 
+  // File-descriptor setup
+
+  if (!SetSocketFlags(aFd)) {
+    return NS_ERROR_FAILURE;
+  }
+  if (!mConnector->SetUp(aFd)) {
+    NS_WARNING("Could not set up socket!");
+    return NS_ERROR_FAILURE;
+  }
+
   SetSocket(aFd, SOCKET_IS_CONNECTED);
 
   // Address setup
-  mAddressLength = aAddrLen;
-  memcpy(&mAddress, aAddr, mAddressLength);
+  memcpy(&mAddr, aAddr, aAddrLen);
+  mAddrSize = aAddrLen;
 
   // Signal success
   NS_DispatchToMainThread(
     new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
 
   AddWatchers(READ_WATCHER, true);
   if (HasPendingData()) {
     AddWatchers(WRITE_WATCHER, false);
@@ -586,18 +647,19 @@ StreamSocket::Connect(UnixSocketConnecto
 
   nsAutoPtr<UnixSocketConnector> connector(aConnector);
 
   if (mIO) {
     NS_WARNING("Socket already connecting/connected!");
     return false;
   }
 
+  nsCString addr(aAddress);
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
-  mIO = new StreamSocketIO(ioLoop, this, connector.forget());
+  mIO = new StreamSocketIO(ioLoop, this, connector.forget(), addr);
   SetConnectionStatus(SOCKET_CONNECTING);
   if (aDelayMs > 0) {
     StreamSocketIO::DelayedConnectTask* connectTask =
       new StreamSocketIO::DelayedConnectTask(mIO);
     mIO->SetDelayedConnectTask(connectTask);
     MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
   } else {
     ioLoop->PostTask(FROM_HERE, new StreamSocketIO::ConnectTask(mIO));
@@ -614,17 +676,17 @@ StreamSocket::PrepareAccept(UnixSocketCo
   MOZ_ASSERT(aConnector);
 
   nsAutoPtr<UnixSocketConnector> connector(aConnector);
 
   SetConnectionStatus(SOCKET_CONNECTING);
 
   mIO = new StreamSocketIO(XRE_GetIOMessageLoop(),
                            -1, UnixSocketWatcher::SOCKET_IS_CONNECTING,
-                           this, connector.forget());
+                           this, connector.forget(), EmptyCString());
   return mIO;
 }
 
 // |DataSocket|
 
 void
 StreamSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
 {
--- a/ipc/unixsocket/UnixSocketConnector.cpp
+++ b/ipc/unixsocket/UnixSocketConnector.cpp
@@ -1,24 +1,16 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* 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 "UnixSocketConnector.h"
-#include "nsISupportsImpl.h" // For MOZ_COUNT_CTOR, MOZ_COUNT_DTOR
 
 namespace mozilla {
 namespace ipc {
 
-UnixSocketConnector::UnixSocketConnector()
-{
-  MOZ_COUNT_CTOR(UnixSocketConnector);
-}
-
 UnixSocketConnector::~UnixSocketConnector()
-{
-  MOZ_COUNT_DTOR(UnixSocketConnector);
-}
+{ }
 
 }
 }
--- a/ipc/unixsocket/UnixSocketConnector.h
+++ b/ipc/unixsocket/UnixSocketConnector.h
@@ -2,85 +2,84 @@
 /* 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 mozilla_ipc_unixsocketconnector_h
 #define mozilla_ipc_unixsocketconnector_h
 
-#include <sys/socket.h>
 #include "mozilla/ipc/UnixSocketWatcher.h"
 #include "nsString.h"
 
 namespace mozilla {
 namespace ipc {
 
 /**
  * |UnixSocketConnector| defines the socket creation and connection/listening
  * functions for |UnixSocketConsumer|, et al. Due to the fact that socket setup
- * can vary between protocols (Unix sockets, TCP sockets, Bluetooth sockets, etc),
+ * can vary between protocols (unix sockets, tcp sockets, bluetooth sockets, etc),
  * this allows the user to create whatever connection mechanism they need while
  * still depending on libevent for non-blocking communication handling.
  */
 class UnixSocketConnector
 {
 public:
   virtual ~UnixSocketConnector();
 
   /**
-   * Converts an address to a human-readable string.
+   * Establishs a file descriptor for a socket.
    *
-   * @param aAddress A socket address
-   * @param aAddressLength The number of valid bytes in |aAddress|
-   * @param[out] aAddressString The resulting string
-   * @return NS_OK on success, or an XPCOM error code otherwise.
+   * @return File descriptor for socket
    */
-  virtual nsresult ConvertAddressToString(const struct sockaddr& aAddress,
-                                          socklen_t aAddressLength,
-                                          nsACString& aAddressString) = 0;
+  virtual int Create() = 0;
 
   /**
-   * Creates a listening socket. I/O thread only.
+   * Since most socket specifics are related to address formation into a
+   * sockaddr struct, this function is defined by subclasses and fills in the
+   * structure as needed for whatever connection it is trying to build
    *
-   * @param[out] aAddress The listening socket's address
-   * @param[out] aAddressLength The number of valid bytes in |aAddress|
-   * @param[out] aListenFd The socket's file descriptor
-   * @return NS_OK on success, or an XPCOM error code otherwise.
+   * @param aIsServer True is we are acting as a server socket
+   * @param aAddrSize Size of the struct
+   * @param aAddr Struct to fill
+   * @param aAddress If aIsServer is false, Address to connect to. nullptr otherwise.
+   *
+   * @return True if address is filled correctly, false otherwise
    */
-  virtual nsresult CreateListenSocket(struct sockaddr* aAddress,
-                                      socklen_t* aAddressLength,
-                                      int& aListenFd) = 0;
+  virtual bool CreateAddr(bool aIsServer,
+                          socklen_t& aAddrSize,
+                          sockaddr_any& aAddr,
+                          const char* aAddress) = 0;
 
   /**
-   * Accepts a stream socket from a listening socket. I/O thread only.
+   * Does any socket type specific setup that may be needed, only for socket
+   * created by ConnectSocket()
    *
-   * @param aListenFd The listening socket
-   * @param[out] aAddress Returns the stream socket's address
-   * @param[out] aAddressLength Returns the number of valid bytes in |aAddress|
-   * @param[out] aStreamFd The stream socket's file descriptor
-   * @return NS_OK on success, or an XPCOM error code otherwise.
+   * @param aFd File descriptor for opened socket
+   *
+   * @return true is successful, false otherwise
    */
-  virtual nsresult AcceptStreamSocket(int aListenFd,
-                                      struct sockaddr* aAddress,
-                                      socklen_t* aAddressLen,
-                                      int& aStreamFd) = 0;
+  virtual bool SetUp(int aFd) = 0;
 
   /**
-   * Creates a stream socket. I/O thread only.
+   * Perform socket setup for socket created by ListenSocket(), after listen().
    *
-   * @param[in|out] aAddress The stream socket's address
-   * @param[in|out] aAddressLength The number of valid bytes in |aAddress|
-   * @param[out] aStreamFd The socket's file descriptor
-   * @return NS_OK on success, or an XPCOM error code otherwise.
+   * @param aFd File descriptor for opened socket
+   *
+   * @return true is successful, false otherwise
    */
-  virtual nsresult CreateStreamSocket(struct sockaddr* aAddress,
-                                      socklen_t* aAddressLength,
-                                      int& aStreamFd) = 0;
+  virtual bool SetUpListenSocket(int aFd) = 0;
 
-protected:
-  UnixSocketConnector();
+  /**
+   * Get address of socket we're currently connected to. Return null string if
+   * not connected.
+   *
+   * @param aAddr Address struct
+   * @param aAddrStr String to store address to
+   */
+  virtual void GetSocketAddr(const sockaddr_any& aAddr,
+                             nsAString& aAddrStr) = 0;
 };
 
 }
 }
 
 #endif