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 244454 6d5e774afa38ddaeaf6f42e4661584c4de011c28
parent 244453 854336cbcbb9ebd49ebdcf8085345de48b742bf5
child 244455 3529de81a66875b22d105c3b269baf9d8930b2a5
push id15662
push usertdz@users.sourceforge.net
push dateTue, 19 May 2015 11:28:50 +0000
treeherderb2g-inbound@3529de81a668 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmachulis
bugs1161020
milestone41.0a1
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)
 {