From e5f02e0748de02eabfb8e0746af09eb676ec1dc0 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 10 Oct 2010 18:51:17 +0200 Subject: [PATCH] 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. --- error.h | 1 + net.c | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) 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; } -- 2.39.5