[haiku-commits] haiku: hrev46434 - src/kits/network/libnetapi headers/os/net

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 24 Nov 2013 22:36:48 +0100 (CET)

hrev46434 adds 1 changeset to branch 'master'
old head: 5c38483e0c7db53fdf9900046b4c96fa73ac9141
new head: dcc56bf748e948579a72e484633c6c9d86b01132
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=dcc56bf+%5E5c38483

----------------------------------------------------------------------------

dcc56bf: BNetEndpoint: Fix socket leak and reduce Accept() overhead.
  
  When using the copy constructor of BNetEndpoint the socket of the
  original endpoint gets dup'ed. The Accept() method later directly reset
  the fSocket member of the newly created BNetEndpoint to the socket
  returned by accept(). The socket dup'ed by the copy constructor was
  therefore leaked.
  
  Of course dup'ing the socket and copying the local and remote addresses
  is superfluous in the accept case, as these members all get set to new
  values. To reduce that overhead there is now a new private constructor
  that directly gets the final socket and remote and local address.

                                            [ Michael Lotz <mmlr@xxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev46434
Commit:      dcc56bf748e948579a72e484633c6c9d86b01132
URL:         http://cgit.haiku-os.org/haiku/commit/?id=dcc56bf
Author:      Michael Lotz <mmlr@xxxxxxxx>
Date:        Sun Nov 24 20:32:30 2013 UTC

----------------------------------------------------------------------------

2 files changed, 35 insertions(+), 14 deletions(-)
headers/os/net/NetEndpoint.h               |  4 +++
src/kits/network/libnetapi/NetEndpoint.cpp | 45 ++++++++++++++++++--------

----------------------------------------------------------------------------

diff --git a/headers/os/net/NetEndpoint.h b/headers/os/net/NetEndpoint.h
index 1dc3d62..37a0e27 100644
--- a/headers/os/net/NetEndpoint.h
+++ b/headers/os/net/NetEndpoint.h
@@ -78,6 +78,10 @@ class BNetEndpoint : public BArchivable {
                const BNetAddress& RemoteAddr();
 
        private:
+               BNetEndpoint(const BNetEndpoint& other, int socket,
+                       const struct sockaddr_in& localAddress,
+                       const struct sockaddr_in& peerAddress);
+
                status_t _SetupSocket();
 
                virtual void _ReservedBNetEndpointFBCCruft1();
diff --git a/src/kits/network/libnetapi/NetEndpoint.cpp 
b/src/kits/network/libnetapi/NetEndpoint.cpp
index e50225d..80bbe9b 100644
--- a/src/kits/network/libnetapi/NetEndpoint.cpp
+++ b/src/kits/network/libnetapi/NetEndpoint.cpp
@@ -105,6 +105,23 @@ BNetEndpoint::BNetEndpoint(const BNetEndpoint& endpoint)
 }
 
 
+// Private constructor only used from BNetEndpoint::Accept().
+BNetEndpoint::BNetEndpoint(const BNetEndpoint& endpoint, int socket,
+       const struct sockaddr_in& localAddress,
+       const struct sockaddr_in& peerAddress)
+       :
+       fStatus(endpoint.fStatus),
+       fFamily(endpoint.fFamily),
+       fType(endpoint.fType),
+       fProtocol(endpoint.fProtocol),
+       fSocket(socket),
+       fTimeout(endpoint.fTimeout),
+       fAddr(localAddress),
+       fPeer(peerAddress)
+{
+}
+
+
 BNetEndpoint&
 BNetEndpoint::operator=(const BNetEndpoint& endpoint)
 {
@@ -422,33 +439,33 @@ BNetEndpoint::Accept(int32 timeout)
        if (!IsDataPending(timeout < 0 ? B_INFINITE_TIMEOUT : 1000LL * timeout))
                return NULL;
 
-       struct sockaddr_in addr;
-       socklen_t addrSize = sizeof(addr);
+       struct sockaddr_in peerAddress;
+       socklen_t peerAddressSize = sizeof(peerAddress);
 
-       int socket = accept(fSocket, (struct sockaddr *) &addr, &addrSize);
+       int socket
+               = accept(fSocket, (struct sockaddr *)&peerAddress, 
&peerAddressSize);
        if (socket < 0) {
                Close();
                fStatus = errno;
                return NULL;
        }
 
-       BNetEndpoint* endpoint = new (std::nothrow) BNetEndpoint(*this);
-       if (endpoint == NULL) {
-               close(socket);
-               fStatus = B_NO_MEMORY;
+       struct sockaddr_in localAddress;
+       socklen_t localAddressSize = sizeof(localAddress);
+       if (getsockname(socket, (struct sockaddr *)&localAddress,
+                       &localAddressSize) < 0) {
+               fStatus = errno;
                return NULL;
        }
 
-       endpoint->fSocket = socket;
-       endpoint->fPeer.SetTo(addr);
-
-       if (getsockname(socket, (struct sockaddr *)&addr, &addrSize) < 0) {
-               delete endpoint;
-               fStatus = errno;
+       BNetEndpoint* endpoint = new (std::nothrow) BNetEndpoint(*this, socket,
+               localAddress, peerAddress);
+       if (endpoint == NULL) {
+               close(socket);
+               fStatus = B_NO_MEMORY;
                return NULL;
        }
 
-       endpoint->fAddr.SetTo(addr);
        return endpoint;
 }
 


Other related posts:

  • » [haiku-commits] haiku: hrev46434 - src/kits/network/libnetapi headers/os/net - mmlr