* sysdeps/posix/getaddrinfo.c (getaddrinfo): Avoid unnecessary

open/close when determining source addresses.
This commit is contained in:
Ulrich Drepper 2007-09-19 22:12:22 +00:00
parent c3266dc0d8
commit e1db0493fd
3 changed files with 75 additions and 7 deletions

View File

@ -1,5 +1,8 @@
2007-09-19 Ulrich Drepper <drepper@redhat.com>
* sysdeps/posix/getaddrinfo.c (getaddrinfo): Avoid unnecessary
open/close when determining source addresses.
* crypt/Makefile (libcrypt-routines): Add sha256-crypt, sha256,
sha512-crypt, and sha512.
(tests): Add sha256test, sha256c-test, sha512test, and sha512c-test.

32
NEWS
View File

@ -1,10 +1,40 @@
GNU C Library NEWS -- history of user-visible changes. 2007-4-25
GNU C Library NEWS -- history of user-visible changes. 2007-9-19
Copyright (C) 1992-2006, 2007 Free Software Foundation, Inc.
See the end for copying conditions.
Please send GNU C library bug reports via <http://sources.redhat.com/bugzilla/>
using `glibc' in the "product" field.
Version 2.7
* More checking functions: fread, fread_unlocked, open*, mq_open.
Implemented by Jakub Jelinek and Ulrich Drepper.
* Extend fortification to C++. Implemented by Jakub Jelinek.
* Implement 'm' modifier for scanf. Add stricter C99/SUS compliance
by not recognizing 'a' as a modifier when those specs are requested.
Implemented by Jakub Jelinek.
* PPC optimizations to math and string functions.
Implemented by Steven Munroe.
* New interfaces: mkostemp, mkostemp64. Like mkstemp* but allow additonal
options to be passed. Implemented by Ulrich Drepper.
* More CPU set manipulation functions. Implemented by Ulrich Drepper.
* Handle private futexes in the NPTL implementation.
Implemented by Jakub Jelinek and Ulrich Drepper.
* Add support for O_CLOEXEC. Implement in Hurd. Use throughout libc.
Implemented by Roland McGrath and Ulrich Drepper.
* Linux/x86-64 vDSO support. Implemented by Ulrich Drepper.
* SHA-256 and SHA-512 based password encryption.
Implemented by Ulrich Drepper.
Version 2.6
* New Linux interfaces: epoll_pwait, sched_getcpu.

View File

@ -1944,6 +1944,9 @@ getaddrinfo (const char *name, const char *service,
if (in6ai != NULL)
qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp);
int fd = -1;
int af = AF_UNSPEC;
for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
{
results[i].dest_addr = q;
@ -1968,7 +1971,21 @@ getaddrinfo (const char *name, const char *service,
want connect() to connect to the other side. If we
cannot determine the source address remember this
fact. */
int fd = __socket (q->ai_family, SOCK_DGRAM, IPPROTO_IP);
if (fd == -1 || (af == AF_INET && q->ai_family == AF_INET6))
{
if (fd != -1)
close_retry:
close (fd);
af = q->ai_family;
fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
}
else
{
/* Reset the connection. */
struct sockaddr sa = { .sa_family = AF_UNSPEC };
__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
@ -1979,9 +1996,9 @@ getaddrinfo (const char *name, const char *service,
results[i].source_addr_len = sl;
results[i].got_source_addr = true;
if (q->ai_family == PF_INET6 && in6ai != NULL)
if (q->ai_family == AF_INET6 && in6ai != NULL)
{
/* See whether the source address is the list of
/* See whether the source address is on the list of
deprecated or temporary addresses. */
struct in6addrinfo tmp;
struct sockaddr_in6 *sin6p
@ -1994,14 +2011,29 @@ getaddrinfo (const char *name, const char *service,
if (found != NULL)
results[i].source_addr_flags = found->flags;
}
else if (q->ai_family == AF_INET && af == AF_INET6)
{
/* We have to convert the address. The socket is
IPv6 and the request is for IPv4. */
struct sockaddr_in6 *sin6
= (struct sockaddr_in6 *) &results[i].source_addr;
struct sockaddr_in *sin
= (struct sockaddr_in *) &results[i].source_addr;
assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
memcpy (&sin->sin_addr,
&sin6->sin6_addr.s6_addr32[3], INADDRSZ);
results[i].source_addr_len = INADDRSZ;
sin->sin_family = AF_INET;
}
}
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. */
results[i].source_addr_len = 0;
if (fd != -1)
close_not_cancel_no_status (fd);
}
/* Remember the canonical name. */
@ -2013,6 +2045,9 @@ getaddrinfo (const char *name, const char *service,
}
}
if (fd != -1)
close_not_cancel_no_status (fd);
/* We got all the source addresses we can get, now sort using
the information. */
qsort (results, nresults, sizeof (results[0]), rfc3484_sort);