Skip to content

Commit

Permalink
* sysdeps/posix/getaddrinfo.c (getaddrinfo): Avoid unnecessary
Browse files Browse the repository at this point in the history
	open/close when determining source addresses.
  • Loading branch information
Ulrich Drepper committed Sep 19, 2007
1 parent c3266dc commit e1db049
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 7 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
32 changes: 31 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
47 changes: 41 additions & 6 deletions sysdeps/posix/getaddrinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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. */
Expand All @@ -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);
Expand Down

0 comments on commit e1db049

Please sign in to comment.