Bug 1161020: Use new socket-connector interface in socket classes, r=kmachulis
authorThomas Zimmermann <tdz@users.sourceforge.net>
Tue, 19 May 2015 13:28:46 +0200
changeset 244516 6d5e774afa38ddaeaf6f42e4661584c4de011c28
parent 244515 854336cbcbb9ebd49ebdcf8085345de48b742bf5
child 244517 3529de81a66875b22d105c3b269baf9d8930b2a5
push id28782
push userkwierso@gmail.com
push dateTue, 19 May 2015 23:42:58 +0000
treeherdermozilla-central@ac277e615f8f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmachulis
bugs1161020
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1161020: Use new socket-connector interface in socket classes, r=kmachulis This patch converts the socket I/O classes to use the new interface of the socket-connector classes. All sockets are now created and set up by a socket connector.
dom/bluetooth/bluez/BluetoothSocket.cpp
ipc/unixsocket/ListenSocket.cpp
ipc/unixsocket/StreamSocket.cpp
--- a/dom/bluetooth/bluez/BluetoothSocket.cpp
+++ b/dom/bluetooth/bluez/BluetoothSocket.cpp
@@ -25,21 +25,20 @@ static const size_t MAX_READ_SIZE = 1 <<
 
 class BluetoothSocket::BluetoothSocketIO final
   : public UnixSocketWatcher
   , public DataSocketIO
 {
 public:
   BluetoothSocketIO(MessageLoop* mIOLoop,
                     BluetoothSocket* aConsumer,
-                    UnixSocketConnector* aConnector,
-                    const nsACString& aAddress);
+                    UnixSocketConnector* aConnector);
   ~BluetoothSocketIO();
 
-  void        GetSocketAddr(nsAString& aAddrStr) const;
+  void GetSocketAddr(nsAString& aAddrStr) const;
 
   BluetoothSocket* GetBluetoothSocket();
   DataSocket* GetDataSocket();
 
   // Delayed-task handling
   //
 
   void SetDelayedConnectTask(CancelableTask* aTask);
@@ -89,19 +88,16 @@ 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;
 
   /**
@@ -110,51 +106,45 @@ private:
   nsAutoPtr<UnixSocketConnector> mConnector;
 
   /**
    * If true, do not requeue whatever task we're running
    */
   bool mShuttingDownOnIOThread;
 
   /**
-   * Address we are connecting to, assuming we are creating a client connection.
+   * Number of valid bytes in |mAddress|
    */
-  nsCString mAddress;
+  socklen_t mAddressLength;
 
   /**
-   * Size of the socket address struct
+   * Address structure of the socket currently in use
    */
-  socklen_t mAddrSize;
-
-  /**
-   * Address struct of the socket currently in use
-   */
-  sockaddr_any mAddr;
+  struct sockaddr_storage mAddress;
 
   /**
    * 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,
-  const nsACString& aAddress)
+  UnixSocketConnector* aConnector)
   : UnixSocketWatcher(mIOLoop)
   , mConsumer(aConsumer)
   , mConnector(aConnector)
   , mShuttingDownOnIOThread(false)
-  , mAddress(aAddress)
+  , mAddressLength(0)
   , mDelayedConnectTask(nullptr)
 {
   MOZ_ASSERT(mConsumer);
   MOZ_ASSERT(mConnector);
 }
 
 BluetoothSocket::BluetoothSocketIO::~BluetoothSocketIO()
 {
@@ -165,17 +155,27 @@ BluetoothSocket::BluetoothSocketIO::~Blu
 void
 BluetoothSocket::BluetoothSocketIO::GetSocketAddr(nsAString& aAddrStr) const
 {
   if (!mConnector) {
     NS_WARNING("No connector to get socket address from!");
     aAddrStr.Truncate();
     return;
   }
-  mConnector->GetSocketAddr(mAddr, aAddrStr);
+
+  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));
 }
 
 BluetoothSocket*
 BluetoothSocket::BluetoothSocketIO::GetBluetoothSocket()
 {
   return mConsumer.get();
 }
 
@@ -216,82 +216,56 @@ BluetoothSocket::BluetoothSocketIO::Canc
 
 void
 BluetoothSocket::BluetoothSocketIO::Listen()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(mConnector);
 
   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->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!");
+    mAddressLength = sizeof(mAddress);
+
+    int fd;
+    nsresult rv = mConnector->CreateListenSocket(
+      reinterpret_cast<struct sockaddr*>(&mAddress), &mAddressLength, fd);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
       FireSocketError();
       return;
     }
     SetFd(fd);
 
     // calls OnListening on success, or OnError otherwise
-    nsresult rv = UnixSocketWatcher::Listen(
-      reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
+    rv = UnixSocketWatcher::Listen(
+      reinterpret_cast<struct sockaddr*>(&mAddress), mAddressLength);
     NS_WARN_IF(NS_FAILED(rv));
   }
 }
 
 void
 BluetoothSocket::BluetoothSocketIO::Connect()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(mConnector);
 
   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(fd)) {
-      NS_WARNING("Could not set up socket!");
-      FireSocketError();
-      return;
-    }
-    if (!mConnector->CreateAddr(false, mAddrSize, mAddr, mAddress.get())) {
-      NS_WARNING("Cannot create socket address!");
+    mAddressLength = sizeof(mAddress);
+
+    int fd;
+    nsresult rv = mConnector->CreateStreamSocket(
+      reinterpret_cast<struct sockaddr*>(&mAddress), &mAddressLength, fd);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
       FireSocketError();
       return;
     }
     SetFd(fd);
   }
 
   // calls OnConnected() on success, or OnError() otherwise
   nsresult rv = UnixSocketWatcher::Connect(
-    reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
+    reinterpret_cast<struct sockaddr*>(&mAddress), mAddressLength);
   NS_WARN_IF(NS_FAILED(rv));
 }
 
 void
 BluetoothSocket::BluetoothSocketIO::Send(UnixSocketIOBuffer* aBuffer)
 {
   EnqueueData(aBuffer);
   AddWatchers(WRITE_WATCHER, false);
@@ -333,28 +307,24 @@ BluetoothSocket::BluetoothSocketIO::OnEr
 void
 BluetoothSocket::BluetoothSocketIO::OnSocketCanAcceptWithoutBlocking()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING);
 
   RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
 
-  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!");
+  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();
     return;
   }
 
   Close();
   SetSocket(fd, SOCKET_IS_CONNECTED);
 
   NS_DispatchToMainThread(
     new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
@@ -406,48 +376,16 @@ 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);
 
@@ -725,19 +663,18 @@ 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(), addr);
+  mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
   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));
   }
@@ -752,20 +689,22 @@ BluetoothSocket::ListenSocket(BluetoothU
 
   nsAutoPtr<UnixSocketConnector> connector(aConnector);
 
   if (mIO) {
     NS_WARNING("Socket already connecting/connected!");
     return false;
   }
 
-  mIO = new BluetoothSocketIO(
-    XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString());
+  MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+
+  mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
   SetConnectionStatus(SOCKET_LISTENING);
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ListenTask(mIO));
+  ioLoop->PostTask(FROM_HERE, new ListenTask(mIO));
+
   return true;
 }
 
 // |DataSocket|
 
 void
 BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
 {
--- a/ipc/unixsocket/ListenSocket.cpp
+++ b/ipc/unixsocket/ListenSocket.cpp
@@ -23,18 +23,17 @@ class ListenSocketIO final
   : public UnixSocketWatcher
   , public SocketIOBase
 {
 public:
   class ListenTask;
 
   ListenSocketIO(MessageLoop* mIOLoop,
                  ListenSocket* aListenSocket,
-                 UnixSocketConnector* aConnector,
-                 const nsACString& aAddress);
+                 UnixSocketConnector* aConnector);
   ~ListenSocketIO();
 
   void GetSocketAddr(nsAString& aAddrStr) const;
 
   // Task callback methods
   //
 
   /**
@@ -59,19 +58,16 @@ 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;
 
   /**
@@ -80,43 +76,37 @@ private:
   nsAutoPtr<UnixSocketConnector> mConnector;
 
   /**
    * If true, do not requeue whatever task we're running
    */
   bool mShuttingDownOnIOThread;
 
   /**
-   * Address we are connecting to, assuming we are creating a client connection.
+   * Number of valid bytes in |mAddress|
    */
-  nsCString mAddress;
+  socklen_t mAddressLength;
 
   /**
-   * Size of the socket address struct
+   * Address structure of the socket currently in use
    */
-  socklen_t mAddrSize;
-
-  /**
-   * Address struct of the socket currently in use
-   */
-  sockaddr_any mAddr;
+  struct sockaddr_storage mAddress;
 
   ConnectionOrientedSocketIO* mCOSocketIO;
 };
 
 ListenSocketIO::ListenSocketIO(MessageLoop* mIOLoop,
                                ListenSocket* aListenSocket,
-                               UnixSocketConnector* aConnector,
-                               const nsACString& aAddress)
+                               UnixSocketConnector* aConnector)
   : UnixSocketWatcher(mIOLoop)
   , SocketIOBase()
   , mListenSocket(aListenSocket)
   , mConnector(aConnector)
   , mShuttingDownOnIOThread(false)
-  , mAddress(aAddress)
+  , mAddressLength(0)
   , mCOSocketIO(nullptr)
 {
   MOZ_ASSERT(mListenSocket);
   MOZ_ASSERT(mConnector);
 }
 
 ListenSocketIO::~ListenSocketIO()
 {
@@ -127,59 +117,53 @@ ListenSocketIO::~ListenSocketIO()
 void
 ListenSocketIO::GetSocketAddr(nsAString& aAddrStr) const
 {
   if (!mConnector) {
     NS_WARNING("No connector to get socket address from!");
     aAddrStr.Truncate();
     return;
   }
-  mConnector->GetSocketAddr(mAddr, aAddrStr);
+
+  nsCString addressString;
+  nsresult rv = mConnector->ConvertAddressToString(
+    *reinterpret_cast<const struct sockaddr*>(&mAddress), mAddressLength,
+    addressString);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  aAddrStr.Assign(NS_ConvertUTF8toUTF16(addressString));
 }
 
 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 = 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!");
+    int fd;
+    nsresult rv = mConnector->CreateListenSocket(address, &mAddressLength,
+                                                 fd);
+    if (NS_FAILED(rv)) {
       FireSocketError();
       return;
     }
     SetFd(fd);
   }
 
   mCOSocketIO = aCOSocketIO;
 
   // calls OnListening on success, or OnError otherwise
-  nsresult rv = UnixSocketWatcher::Listen(
-    reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
+  nsresult rv = UnixSocketWatcher::Listen(address, mAddressLength);
   NS_WARN_IF(NS_FAILED(rv));
 }
 
 void
 ListenSocketIO::OnConnected()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
 
@@ -216,72 +200,41 @@ 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);
 
-  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);
+  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();
     return;
   }
 
-  RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
-
   mCOSocketIO->Accept(fd,
-                      reinterpret_cast<union sockaddr_any*>(&addr),
-                      addrLen);
+                      reinterpret_cast<union sockaddr_any*>(&storage),
+                      addressLength);
 }
 
 // |SocketIOBase|
 
 SocketBase*
 ListenSocketIO::GetSocketBase()
 {
   return mListenSocket.get();
@@ -392,18 +345,17 @@ 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(), EmptyCString());
+  mIO = new ListenSocketIO(XRE_GetIOMessageLoop(), this, connector.forget());
 
   // 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,23 +25,21 @@ class StreamSocketIO final
 {
 public:
   class ConnectTask;
   class DelayedConnectTask;
   class ReceiveRunnable;
 
   StreamSocketIO(MessageLoop* mIOLoop,
                  StreamSocket* aStreamSocket,
-                 UnixSocketConnector* aConnector,
-                 const nsACString& aAddress);
+                 UnixSocketConnector* aConnector);
   StreamSocketIO(MessageLoop* mIOLoop, int aFd,
                  ConnectionStatus aConnectionStatus,
                  StreamSocket* aStreamSocket,
-                 UnixSocketConnector* aConnector,
-                 const nsACString& aAddress);
+                 UnixSocketConnector* aConnector);
   ~StreamSocketIO();
 
   void GetSocketAddr(nsAString& aAddrStr) const;
 
   StreamSocket* GetStreamSocket();
   DataSocket* GetDataSocket();
 
   // Delayed-task handling
@@ -93,19 +91,16 @@ 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;
 
   /**
@@ -114,66 +109,59 @@ private:
   nsAutoPtr<UnixSocketConnector> mConnector;
 
   /**
    * If true, do not requeue whatever task we're running
    */
   bool mShuttingDownOnIOThread;
 
   /**
-   * Address we are connecting to, assuming we are creating a client connection.
+   * Number of valid bytes in |mAddress|
    */
-  nsCString mAddress;
+  socklen_t mAddressLength;
 
   /**
-   * Size of the socket address struct
+   * Address structure of the socket currently in use
    */
-  socklen_t mAddrSize;
-
-  /**
-   * Address struct of the socket currently in use
-   */
-  sockaddr_any mAddr;
+  struct sockaddr_storage mAddress;
 
   /**
    * 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,
-                               const nsACString& aAddress)
+                               UnixSocketConnector* aConnector)
   : UnixSocketWatcher(mIOLoop)
   , mStreamSocket(aStreamSocket)
   , mConnector(aConnector)
   , mShuttingDownOnIOThread(false)
-  , mAddress(aAddress)
+  , mAddressLength(0)
   , mDelayedConnectTask(nullptr)
 {
   MOZ_ASSERT(mStreamSocket);
   MOZ_ASSERT(mConnector);
 }
 
 StreamSocketIO::StreamSocketIO(MessageLoop* mIOLoop, int aFd,
                                ConnectionStatus aConnectionStatus,
                                StreamSocket* aStreamSocket,
-                               UnixSocketConnector* aConnector,
-                               const nsACString& aAddress)
+                               UnixSocketConnector* aConnector)
   : UnixSocketWatcher(mIOLoop, aFd, aConnectionStatus)
   , mStreamSocket(aStreamSocket)
   , mConnector(aConnector)
   , mShuttingDownOnIOThread(false)
-  , mAddress(aAddress)
+  , mAddressLength(0)
   , mDelayedConnectTask(nullptr)
 {
   MOZ_ASSERT(mStreamSocket);
   MOZ_ASSERT(mConnector);
 }
 
 StreamSocketIO::~StreamSocketIO()
 {
@@ -184,17 +172,26 @@ StreamSocketIO::~StreamSocketIO()
 void
 StreamSocketIO::GetSocketAddr(nsAString& aAddrStr) const
 {
   if (!mConnector) {
     NS_WARNING("No connector to get socket address from!");
     aAddrStr.Truncate();
     return;
   }
-  mConnector->GetSocketAddr(mAddr, aAddrStr);
+
+  nsCString addressString;
+  nsresult rv = mConnector->ConvertAddressToString(
+    *reinterpret_cast<const struct sockaddr*>(&mAddress), mAddressLength,
+    addressString);
+  if (NS_FAILED(rv)) {
+    return;
+  }
+
+  aAddrStr.Assign(NS_ConvertUTF8toUTF16(addressString));
 }
 
 StreamSocket*
 StreamSocketIO::GetStreamSocket()
 {
   return mStreamSocket.get();
 }
 
@@ -234,44 +231,31 @@ StreamSocketIO::CancelDelayedConnectTask
 }
 
 void
 StreamSocketIO::Connect()
 {
   MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop());
   MOZ_ASSERT(mConnector);
 
-  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);
+  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;
   }
+  SetFd(fd);
 
   // calls OnConnected() on success, or OnError() otherwise
-  nsresult rv = UnixSocketWatcher::Connect(
-    reinterpret_cast<struct sockaddr*>(&mAddr), mAddrSize);
+  rv = UnixSocketWatcher::Connect(address, mAddressLength);
   NS_WARN_IF(NS_FAILED(rv));
 }
 
 void
 StreamSocketIO::Send(UnixSocketIOBuffer* aData)
 {
   EnqueueData(aData);
   AddWatchers(WRITE_WATCHER, false);
@@ -349,75 +333,30 @@ 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
-  memcpy(&mAddr, aAddr, aAddrLen);
-  mAddrSize = aAddrLen;
+  mAddressLength = aAddrLen;
+  memcpy(&mAddress, aAddr, mAddressLength);
 
   // Signal success
   NS_DispatchToMainThread(
     new SocketIOEventRunnable(this, SocketIOEventRunnable::CONNECT_SUCCESS));
 
   AddWatchers(READ_WATCHER, true);
   if (HasPendingData()) {
     AddWatchers(WRITE_WATCHER, false);
@@ -647,19 +586,18 @@ 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(), addr);
+  mIO = new StreamSocketIO(ioLoop, this, connector.forget());
   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));
@@ -676,17 +614,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(), EmptyCString());
+                           this, connector.forget());
   return mIO;
 }
 
 // |DataSocket|
 
 void
 StreamSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
 {