* 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> 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, * crypt/Makefile (libcrypt-routines): Add sha256-crypt, sha256,
sha512-crypt, and sha512. sha512-crypt, and sha512.
(tests): Add sha256test, sha256c-test, sha512test, and sha512c-test. (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. Copyright (C) 1992-2006, 2007 Free Software Foundation, Inc.
See the end for copying conditions. See the end for copying conditions.
Please send GNU C library bug reports via <http://sources.redhat.com/bugzilla/> Please send GNU C library bug reports via <http://sources.redhat.com/bugzilla/>
using `glibc' in the "product" field. 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 Version 2.6
* New Linux interfaces: epoll_pwait, sched_getcpu. * New Linux interfaces: epoll_pwait, sched_getcpu.

View File

@ -1944,6 +1944,9 @@ getaddrinfo (const char *name, const char *service,
if (in6ai != NULL) if (in6ai != NULL)
qsort (in6ai, in6ailen, sizeof (*in6ai), in6aicmp); 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) for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
{ {
results[i].dest_addr = q; 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 want connect() to connect to the other side. If we
cannot determine the source address remember this cannot determine the source address remember this
fact. */ 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); socklen_t sl = sizeof (results[i].source_addr);
if (fd != -1 if (fd != -1
&& __connect (fd, q->ai_addr, q->ai_addrlen) == 0 && __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].source_addr_len = sl;
results[i].got_source_addr = true; 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. */ deprecated or temporary addresses. */
struct in6addrinfo tmp; struct in6addrinfo tmp;
struct sockaddr_in6 *sin6p struct sockaddr_in6 *sin6p
@ -1994,14 +2011,29 @@ getaddrinfo (const char *name, const char *service,
if (found != NULL) if (found != NULL)
results[i].source_addr_flags = found->flags; 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 else
/* Just make sure that if we have to process the same /* Just make sure that if we have to process the same
address again we do not copy any memory. */ address again we do not copy any memory. */
results[i].source_addr_len = 0; results[i].source_addr_len = 0;
if (fd != -1)
close_not_cancel_no_status (fd);
} }
/* Remember the canonical name. */ /* 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 /* We got all the source addresses we can get, now sort using
the information. */ the information. */
qsort (results, nresults, sizeof (results[0]), rfc3484_sort); qsort (results, nresults, sizeof (results[0]), rfc3484_sort);