Bug 800249 - Patch 1: Add ability to store/retrieve address to UnixSocket; r=cjones
authorKyle Machulis <kyle@nonpolynomial.com>
Wed, 17 Oct 2012 17:10:27 -0700
changeset 110753 054604aa00bd159fcd06a54efdaafef35ec40e79
parent 110752 205475d5c2b77c88cc040fe7ad3a9d6994f48553
child 110754 3b0b4ccb241f77772938e5a96885eb28aca01201
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewerscjones
bugs800249
milestone19.0a1
Bug 800249 - Patch 1: Add ability to store/retrieve address to UnixSocket; r=cjones
ipc/unixsocket/UnixSocket.cpp
ipc/unixsocket/UnixSocket.h
--- a/ipc/unixsocket/UnixSocket.cpp
+++ b/ipc/unixsocket/UnixSocket.cpp
@@ -146,16 +146,22 @@ public:
 
   /** 
    * Set up nonblocking flags on whatever our current file descriptor is.
    *
    * @return true if successful, false otherwise
    */
   bool SetNonblockFlags();
 
+  void GetSocketAddr(struct sockaddr& aAddr, socklen_t& aAddrSize)
+  {
+    aAddr = mAddr;
+    aAddrSize = mAddrSize;
+  }
+
   /**
    * Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
    * directly from main thread. All non-main-thread accesses should happen with
    * mImpl as container.
    */
   RefPtr<UnixSocketConsumer> mConsumer;
 
 private:
@@ -222,16 +228,27 @@ private:
    * will be taken care of by the IO loop. Just set to nullptr.
    */
   CancelableTask* mTask;
 
   /**
    * Address we are connecting to, assuming we are creating a client connection.
    */
   nsCString mAddress;
+
+  /**
+   * Size of the socket address struct
+   */
+  socklen_t mAddrSize;
+
+  /**
+   * Address struct of the socket currently in use
+   */
+  struct sockaddr mAddr;
+
 };
 
 static void
 DestroyImpl(UnixSocketImpl* impl)
 {
   MOZ_ASSERT(impl);
   delete impl;
 }
@@ -399,57 +416,55 @@ void SocketConnectTask::Run() {
     return;
   }
   mImpl->Connect();
 }
 
 void
 UnixSocketImpl::Accept()
 {
-  socklen_t addr_sz;
-  struct sockaddr addr;
 
   if (!mConnector) {
     NS_WARNING("No connector object available!");
     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.
-  mConnector->CreateAddr(true, addr_sz, &addr, nullptr);
+  mConnector->CreateAddr(true, mAddrSize, &mAddr, nullptr);
 
   if(mFd.get() < 0)
   {
     mFd = mConnector->Create();
     if (mFd.get() < 0) {
       return;
     }
 
     if (!SetNonblockFlags()) {
       return;
     }
 
-    if (bind(mFd.get(), &addr, addr_sz)) {
+    if (bind(mFd.get(), &mAddr, mAddrSize)) {
 #ifdef DEBUG
       LOG("...bind(%d) gave errno %d", mFd.get(), errno);
 #endif
       return;
     }
 
     if (listen(mFd.get(), 1)) {
 #ifdef DEBUG
       LOG("...listen(%d) gave errno %d", mFd.get(), errno);
 #endif
       return;
     }
 
   }
 
   int client_fd;
-  client_fd = accept(mFd.get(), &addr, &addr_sz);
+  client_fd = accept(mFd.get(), &mAddr, &mAddrSize);
   if (client_fd < 0) {
     EnqueueTask(SOCKET_RETRY_TIME_MS, new SocketAcceptTask(this));
     return;
   }
 
   if (!mConnector->SetUp(client_fd)) {
     NS_WARNING("Could not set up socket!");
     return;
@@ -474,22 +489,20 @@ UnixSocketImpl::Connect()
   {
     mFd = mConnector->Create();
     if (mFd.get() < 0) {
       return;
     }
   }
 
   int ret;
-  socklen_t addr_sz;
-  struct sockaddr addr;
 
-  mConnector->CreateAddr(false, addr_sz, &addr, mAddress.get());
+  mConnector->CreateAddr(false, mAddrSize, &mAddr, mAddress.get());
 
-  ret = connect(mFd.get(), &addr, addr_sz);
+  ret = connect(mFd.get(), &mAddr, mAddrSize);
 
   if (ret) {
 #if DEBUG
     LOG("Socket connect errno=%d\n", errno);
 #endif
     mFd.reset(-1);
     nsRefPtr<OnSocketEventTask> t =
       new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR);
@@ -689,16 +702,26 @@ UnixSocketImpl::OnFileCanWriteWithoutBlo
       return;
     }
     mOutgoingQ.RemoveElementAt(0);
     delete data;
   }
 }
 
 void
+UnixSocketConsumer::GetSocketAddr(struct sockaddr& aAddr, socklen_t &aAddrSize)
+{
+  if (!mImpl) {
+    NS_WARNING("No socket currently open!");
+    return;
+  }
+  mImpl->GetSocketAddr(aAddr, aAddrSize);
+}
+
+void
 UnixSocketConsumer::NotifySuccess()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mConnectionStatus = SOCKET_CONNECTED;
   OnConnectSuccess();
 }
 
 void
--- a/ipc/unixsocket/UnixSocket.h
+++ b/ipc/unixsocket/UnixSocket.h
@@ -207,16 +207,22 @@ public:
    * Called by implementation to notify consumer of error.
    */
   void NotifyError();
 
   /** 
    * Called by implementation to notify consumer of disconnect.
    */
   void NotifyDisconnect();
+
+  /**
+   * Get the current sockaddr for the socket
+   */
+  void GetSocketAddr(struct sockaddr& aAddr, socklen_t& aAddrSize);
+  
 private:
   UnixSocketImpl* mImpl;
   SocketConnectionStatus mConnectionStatus;
 };
 
 } // namespace ipc
 } // namepsace mozilla