]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Minor makesock() fixes.
authorAndre Noll <maan@systemlinux.org>
Sun, 10 Oct 2010 16:51:17 +0000 (18:51 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 14 Nov 2010 14:42:21 +0000 (15:42 +0100)
On getaddrinfo() or setsockopt() errors, we leak the flowopts and/or
the local/remote address info structure. Fix this by jumping to the
cleanup section at the bottom of makesock() rather than returning
early without cleaning up.

Moreover, we can not rely on errno containing a valid error code in the
cleanup part of the function because flowopt_cleanup() calls free()
which usually resets errno. So use the error code provided via "rc"
if possible and fall back to the new -E_MAKESOCK if rc is non-negative
to make sure we return a negative value on errors.

error.h
net.c

diff --git a/error.h b/error.h
index 5db5e1749a5d915dc3f55f956c423399613da7bf..9864b1d98b3859f753b747d1f49080af41af633b 100644 (file)
--- a/error.h
+++ b/error.h
@@ -243,6 +243,7 @@ extern const char **para_errlist[];
        PARA_ERROR(SENDMSG, "sendmsg() failed"), \
        PARA_ERROR(RECVMSG, "recvmsg() failed"), \
        PARA_ERROR(SCM_CREDENTIALS, "did not receive SCM credentials"), \
        PARA_ERROR(SENDMSG, "sendmsg() failed"), \
        PARA_ERROR(RECVMSG, "recvmsg() failed"), \
        PARA_ERROR(SCM_CREDENTIALS, "did not receive SCM credentials"), \
+       PARA_ERROR(MAKESOCK, "makesock error"), \
 
 
 #define UDP_RECV_ERRORS \
 
 
 #define UDP_RECV_ERRORS \
diff --git a/net.c b/net.c
index 64602a4bf60e7ce934f230cb0ae9d63f5ec404f5..fa48e54f3f8525f26c716ef88784739ecd82a1fb 100644 (file)
--- a/net.c
+++ b/net.c
@@ -380,8 +380,8 @@ int makesock(unsigned l4type, bool passive,
             const char *host, uint16_t port_number,
             struct flowopts *fo)
 {
             const char *host, uint16_t port_number,
             struct flowopts *fo)
 {
-       struct addrinfo *local = NULL, *src,
-                       *remote = NULL, *dst, hints;
+       struct addrinfo *local = NULL, *src = NULL, *remote = NULL,
+               *dst = NULL, hints;
        unsigned int    l3type = AF_UNSPEC;
        int             rc, on = 1, sockfd = -1,
                        socktype = sock_type(l4type);
        unsigned int    l3type = AF_UNSPEC;
        int             rc, on = 1, sockfd = -1,
                        socktype = sock_type(l4type);
@@ -414,7 +414,8 @@ int makesock(unsigned l4type, bool passive,
                                layer4_name(l4type),
                                host? host : (passive? "[loopback]" : "[localhost]"),
                                port, gai_strerror(rc));
                                layer4_name(l4type),
                                host? host : (passive? "[loopback]" : "[localhost]"),
                                port, gai_strerror(rc));
-               return -E_ADDRESS_LOOKUP;
+               rc = -E_ADDRESS_LOOKUP;
+               goto out;
        }
 
        /* Iterate over all src/dst combination, exhausting dst first */
        }
 
        /* Iterate over all src/dst combination, exhausting dst first */
@@ -439,7 +440,8 @@ int makesock(unsigned l4type, bool passive,
                        close(sockfd);
                        PARA_ERROR_LOG("can not set SO_REUSEADDR: %s\n",
                                       strerror(rc));
                        close(sockfd);
                        PARA_ERROR_LOG("can not set SO_REUSEADDR: %s\n",
                                       strerror(rc));
-                       return -ERRNO_TO_PARA_ERROR(rc);
+                       rc = -ERRNO_TO_PARA_ERROR(rc);
+                       break;
                }
                flowopt_setopts(sockfd, fo);
 
                }
                flowopt_setopts(sockfd, fo);
 
@@ -462,6 +464,7 @@ get_next_src:
                if (src && (src = src->ai_next)) /* restart inner loop */
                        dst = remote;
        }
                if (src && (src = src->ai_next)) /* restart inner loop */
                        dst = remote;
        }
+out:
        if (local)
                freeaddrinfo(local);
        if (remote)
        if (local)
                freeaddrinfo(local);
        if (remote)
@@ -469,11 +472,12 @@ get_next_src:
        flowopt_cleanup(fo);
 
        if (src == NULL && dst == NULL) {
        flowopt_cleanup(fo);
 
        if (src == NULL && dst == NULL) {
-               rc = errno;
+               if (rc >= 0)
+                       rc = -E_MAKESOCK;
                PARA_ERROR_LOG("can not create %s socket %s#%s.\n",
                        layer4_name(l4type), host? host : (passive?
                        "[loopback]" : "[localhost]"), port);
                PARA_ERROR_LOG("can not create %s socket %s#%s.\n",
                        layer4_name(l4type), host? host : (passive?
                        "[loopback]" : "[localhost]"), port);
-               return -ERRNO_TO_PARA_ERROR(rc);
+               return rc;
        }
        return sockfd;
 }
        }
        return sockfd;
 }