mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
* sysdeps/posix/getaddrinfo.c (getaddrinfo): Avoid unnecessary
open/close when determining source addresses.
This commit is contained in:
parent
c3266dc0d8
commit
e1db0493fd
@ -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
32
NEWS
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user