* 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>
|
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
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.
|
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.
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user