Plug a minor memory leak that could occur when we opened a TCP connection
authorscottmk <scottmk@9efc2488-bf62-4759-914b-345cdb29e865>
Thu, 14 Oct 2010 16:30:17 +0000 (16:30 +0000)
committerscottmk <scottmk@9efc2488-bf62-4759-914b-345cdb29e865>
Thu, 14 Oct 2010 16:30:17 +0000 (16:30 +0000)
to a server.  In practice this meant whenever we opened a Jabber session.

We call getaddrinfo() to get a dynamically allocated linked list of
addresses for a given server name.  Then we traverse the list, looking
for one that accepts streaming connections over IPV4, in order to get
an IP address.

At the end, we call freeaddrinfo() to free the linked list.

Previously we would pass to freeaddrinfo() a pointer, not to the
head of the list, but to the node that we used for getting an IP
address.  Prior nodes, if any, would leak.

Also: added calls to freeaddrinfo() in the case of early returns, to
avoid leaking the list in the event of an error.

M    src/libopensrf/socket_bundle.c

git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@2036 9efc2488-bf62-4759-914b-345cdb29e865

src/libopensrf/socket_bundle.c

index 64d4e20..a9be085 100644 (file)
@@ -309,17 +309,20 @@ int socket_open_tcp_client(socket_manager* mgr, int port, const char* dest_addr)
        // ------------------------------------------------------------------
        struct addrinfo hints = { 0, 0, 0, 0, 0, NULL, NULL, NULL };
        hints.ai_socktype = SOCK_STREAM;
-       struct addrinfo* addr_info = NULL;
+       struct addrinfo* addr_info_list = NULL;
        errno = 0;
-       int rc = getaddrinfo( dest_addr, NULL, &hints, &addr_info );
-       if( rc || ! addr_info ) {
+       int rc = getaddrinfo( dest_addr, NULL, &hints, &addr_info_list );
+       if( rc || ! addr_info_list ) {
                osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): No Such Host => %s: %s",
                        dest_addr, gai_strerror( rc ) );
+               if( addr_info_list )
+                       freeaddrinfo( addr_info_list );
                return -1;
        }
 
        // Look for an address supporting IPv4.  Someday we'll look for
        // either IPv4 or IPv6, and branch according to what we find.
+       const struct addrinfo* addr_info = addr_info_list;
        while( addr_info && addr_info->ai_family != PF_INET ) {
                addr_info = addr_info->ai_next;
        }
@@ -327,6 +330,8 @@ int socket_open_tcp_client(socket_manager* mgr, int port, const char* dest_addr)
        if( ! addr_info ) {
                osrfLogWarning( OSRF_LOG_MARK,
                        "socket_open_tcp_client(): Host %s does not support IPV4", dest_addr );
+               if( addr_info_list )
+                       freeaddrinfo( addr_info_list );
                return -1;
        }
 
@@ -337,6 +342,8 @@ int socket_open_tcp_client(socket_manager* mgr, int port, const char* dest_addr)
        if( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
                osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot create TCP socket: %s",
                        strerror( errno ) );
+               if( addr_info_list )
+                       freeaddrinfo( addr_info_list );
                return -1;
        }
 
@@ -352,7 +359,7 @@ int socket_open_tcp_client(socket_manager* mgr, int port, const char* dest_addr)
        struct sockaddr_in* ai_addr_in = (struct sockaddr_in*) addr_info->ai_addr;
        remoteAddr.sin_addr.s_addr = ai_addr_in->sin_addr.s_addr;
 
-       freeaddrinfo( addr_info );
+       freeaddrinfo( addr_info_list );
 
        // ------------------------------------------------------------------
        // Connect to server