getaddrinfo: Refactor code for readability

The close_retry goto jump is confusing and clumsy to read, so refactor
the code a bit to make it easier to follow.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: DJ Delorie <dj@redhat.com>
This commit is contained in:
Siddhesh Poyarekar 2022-03-22 22:40:05 +05:30
parent f7fbb99652
commit d3f2c2c8b5
1 changed files with 33 additions and 12 deletions

View File

@ -2246,6 +2246,36 @@ gaiconf_reload (void)
gaiconf_init ();
}
static bool
try_connect (int *fdp, int *afp, struct sockaddr_in6 *source_addrp,
const struct sockaddr *addr, socklen_t addrlen, int family)
{
int fd = *fdp;
int af = *afp;
socklen_t sl = sizeof (*source_addrp);
while (true)
{
if (fd != -1 && __connect (fd, addr, addrlen) == 0
&& __getsockname (fd, (struct sockaddr *) source_addrp, &sl) == 0)
return true;
if (errno == EAFNOSUPPORT && af == AF_INET6 && family == AF_INET)
{
/* This could mean IPv6 sockets are IPv6-only. */
if (fd != -1)
__close_nocancel_nostatus (fd);
*afp = af = AF_INET;
*fdp = fd = __socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC,
IPPROTO_IP);
continue;
}
return false;
}
__builtin_unreachable ();
}
int
getaddrinfo (const char *name, const char *service,
@ -2436,7 +2466,6 @@ getaddrinfo (const char *name, const char *service,
if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
{
if (fd != -1)
close_retry:
__close_nocancel_nostatus (fd);
af = q->ai_family;
fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP);
@ -2448,14 +2477,10 @@ getaddrinfo (const char *name, const char *service,
__connect (fd, &sa, sizeof (sa));
}
socklen_t sl = sizeof (results[i].source_addr);
if (fd != -1
&& __connect (fd, q->ai_addr, q->ai_addrlen) == 0
&& __getsockname (fd,
(struct sockaddr *) &results[i].source_addr,
&sl) == 0)
if (try_connect (&fd, &af, &results[i].source_addr, q->ai_addr,
q->ai_addrlen, q->ai_family))
{
results[i].source_addr_len = sl;
results[i].source_addr_len = sizeof (results[i].source_addr);
results[i].got_source_addr = true;
if (in6ai != NULL)
@ -2520,10 +2545,6 @@ getaddrinfo (const char *name, const char *service,
results[i].source_addr_len = sizeof (struct sockaddr_in);
}
}
else if (errno == EAFNOSUPPORT && af == AF_INET6
&& q->ai_family == AF_INET)
/* This could mean IPv6 sockets are IPv6-only. */
goto close_retry;
else
/* Just make sure that if we have to process the same
address again we do not copy any memory. */