From: Andre Noll Date: Sun, 10 Oct 2010 16:51:17 +0000 (+0200) Subject: Minor makesock() fixes. X-Git-Tag: v0.4.5~9 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=e5f02e0748de02eabfb8e0746af09eb676ec1dc0;p=paraslash.git Minor makesock() fixes. 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. --- diff --git a/error.h b/error.h index 5db5e174..9864b1d9 100644 --- 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(MAKESOCK, "makesock error"), \ #define UDP_RECV_ERRORS \ diff --git a/net.c b/net.c index 64602a4b..fa48e54f 100644 --- 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) { - 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); @@ -414,7 +414,8 @@ int makesock(unsigned l4type, bool passive, 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 */ @@ -439,7 +440,8 @@ int makesock(unsigned l4type, bool passive, 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); @@ -462,6 +464,7 @@ get_next_src: if (src && (src = src->ai_next)) /* restart inner loop */ dst = remote; } +out: if (local) freeaddrinfo(local); if (remote) @@ -469,11 +472,12 @@ get_next_src: 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); - return -ERRNO_TO_PARA_ERROR(rc); + return rc; } return sockfd; }