[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r4842 - in /fsf/trunk/libc: ./ localedata/ localedata/locales/ malloc/ nptl/ nptl/sysdeps/unix/sysv/linux/ nptl/sysdeps/unix...
- To: commits@xxxxxxxxxx
- Subject: [commits] r4842 - in /fsf/trunk/libc: ./ localedata/ localedata/locales/ malloc/ nptl/ nptl/sysdeps/unix/sysv/linux/ nptl/sysdeps/unix...
- From: eglibc@xxxxxxxxxx
- Date: Fri, 11 Jan 2008 08:23:05 -0000
Author: eglibc
Date: Fri Jan 11 00:22:59 2008
New Revision: 4842
Log:
Import glibc-mainline for 2008-01-11
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/localedata/ChangeLog
fsf/trunk/libc/localedata/locales/ga_IE
fsf/trunk/libc/malloc/malloc.c
fsf/trunk/libc/nptl/ChangeLog
fsf/trunk/libc/nptl/pthread-errnos.sym
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
fsf/trunk/libc/posix/tst-rfc3484-2.c
fsf/trunk/libc/posix/tst-rfc3484-3.c
fsf/trunk/libc/posix/tst-rfc3484.c
fsf/trunk/libc/sysdeps/posix/getaddrinfo.c
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Fri Jan 11 00:22:59 2008
@@ -1,3 +1,27 @@
+2008-01-10 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/posix/getaddrinfo.c (rfc3484_sort): Store result of
+ native interface lookup in all the relevant places.
+
+2008-01-10 Jakub Jelinek <jakub@xxxxxxxxxx>
+ Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/posix/getaddrinfo.c (sort_results): Remove service_order
+ field. Use sockaddr_in6 for source_addr.
+ (get_scope): Change type of parameter to sockaddr_in6. Adjust.
+ (match_prefix): Likewise.
+ (get_label): Likewise.
+ (get_precedence): Likewise.
+ (rfc3484_sort): Change to use indirect access to results array.
+ Adjust to use of sockaddr_in6. Replace service_order test with
+ simple index comparison.
+ (getaddrinfo): Define order array. Initialize it. Don't initialize
+ service_order field. Adjust qsort_t calls. Access sorted result
+ array indirectly through order array.
+ * posix/tst-rfc3484.c: Adjust for change of rfc3484_sort.
+ * posix/tst-rfc3484-2.c: Likewise.
+ * posix/tst-rfc3484-3.c: Likewise.
+
2008-01-09 Ulrich Drepper <drepper@xxxxxxxxxx>
[BZ #5541]
Modified: fsf/trunk/libc/localedata/ChangeLog
==============================================================================
--- fsf/trunk/libc/localedata/ChangeLog (original)
+++ fsf/trunk/libc/localedata/ChangeLog Fri Jan 11 00:22:59 2008
@@ -1,3 +1,8 @@
+2008-01-10 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ [BZ #5520]
+ * locales/ga_IE: Fix May, June, November and December entries in mon.
+
2007-12-11 Ulrich Drepper <drepper@xxxxxxxxxx>
* charmsp/HP-THAI8: New file.
Modified: fsf/trunk/libc/localedata/locales/ga_IE
==============================================================================
--- fsf/trunk/libc/localedata/locales/ga_IE (original)
+++ fsf/trunk/libc/localedata/locales/ga_IE Fri Jan 11 00:22:59 2008
@@ -101,14 +101,14 @@
"<U0046><U0065><U0061><U0062><U0068><U0072><U0061>";/
"<U004D><U00E1><U0072><U0074><U0061>";/
"<U0041><U0069><U0062><U0072><U0065><U00E1><U006E>";/
- "<U004D><U00ED><U0020><U006E><U0061><U0020><U0042><U0065><U0061><U006C><U0074><U0061><U0069><U006E><U0065>";/
- "<U004D><U0065><U0069><U0074><U0068>";/
+ "<U0042><U0065><U0061><U006C><U0074><U0061><U0069><U006E><U0065>";/
+ "<U004D><U0065><U0069><U0074><U0068><U0065><U0061><U006d><U0068>";/
"<U0049><U00FA><U0069><U006C>";/
"<U004C><U00FA><U006E><U0061><U0073><U0061>";/
"<U004D><U0065><U00E1><U006E><U0020><U0046><U00F3><U006D><U0068><U0061><U0069><U0072>";/
"<U0044><U0065><U0069><U0072><U0065><U0061><U0064><U0068><U0020><U0046><U00F3><U006D><U0068><U0061><U0069><U0072>";/
- "<U004D><U00ED><U0020><U006E><U0061><U0020><U0053><U0061><U006D><U0068><U006E><U0061>";/
- "<U004D><U00ED><U0020><U006E><U0061><U0020><U004E><U006F><U006C><U006C><U0061><U0067>"
+ "<U0053><U0061><U006D><U0068><U0061><U0069><U006E>";/
+ "<U004E><U006F><U006C><U006C><U0061><U0069><U0067>"
d_t_fmt "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
d_fmt "<U0025><U0064><U002E><U0025><U006D><U002E><U0025><U0079>"
t_fmt "<U0025><U0054>"
Modified: fsf/trunk/libc/malloc/malloc.c
==============================================================================
--- fsf/trunk/libc/malloc/malloc.c (original)
+++ fsf/trunk/libc/malloc/malloc.c Fri Jan 11 00:22:59 2008
@@ -3781,7 +3781,8 @@
}
#endif
}
- }
+ } else
+ (void)mutex_unlock(&ar_ptr->mutex);
assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
ar_ptr == arena_for_chunk(mem2chunk(p)));
return p;
Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Fri Jan 11 00:22:59 2008
@@ -1,3 +1,11 @@
+2008-01-10 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * pthread-errnos.sym: Add EOVERFLOW.
+ * sysdeps/unix/sysv/linux/structsem.sym: Add SEM_VALUE_MAX.
+ * sysdeps/unix/sysv/linux/sem_post.c: Don't overflow value field.
+ * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+
2007-12-14 Ulrich Drepper <drepper@xxxxxxxxxx>
* sysdeps/x86_64/pthreaddef.h (ARCH_RETRY_MMAP): Take additional
Modified: fsf/trunk/libc/nptl/pthread-errnos.sym
==============================================================================
--- fsf/trunk/libc/nptl/pthread-errnos.sym (original)
+++ fsf/trunk/libc/nptl/pthread-errnos.sym Fri Jan 11 00:22:59 2008
@@ -8,5 +8,6 @@
EINTR EINTR
EINVAL EINVAL
ENOSYS ENOSYS
+EOVERFLOW EOVERFLOW
ETIMEDOUT ETIMEDOUT
EWOULDBLOCK EWOULDBLOCK
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S Fri Jan 11 00:22:59 2008
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -34,12 +34,21 @@
movl 8(%esp), %ebx
+#if VALUE == 0
+ movl (%ebx), %eax
+#else
+ movl VALUE(%ebx), %eax
+#endif
+0: cmpl $SEM_VALUE_MAX, %eax
+ je 3f
+ leal 1(%eax), %edx
LOCK
#if VALUE == 0
- addl $1, (%ebx)
+ cmpxchgl %edx, (%ebx)
#else
- addl $1, VALUE(%ebx)
+ cmpxchgl %edx, VALUE(%ebx)
#endif
+ jnz 0b
cmpl $0, NWAITERS(%ebx)
je 2f
@@ -77,6 +86,32 @@
#else
call __errno_location@plt
movl $EINVAL, (%eax)
+#endif
+
+ orl $-1, %eax
+ popl %ebx
+ ret
+
+3:
+#ifdef PIC
+ call __i686.get_pc_thunk.bx
+#else
+ movl $5f, %ebx
+5:
+#endif
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+ movl errno@gotntpoff(%ebx), %edx
+ addl %gs:0, %edx
+ movl $EOVERFLOW, (%edx)
+# else
+ movl errno@gotntpoff(%ebx), %edx
+ movl $EOVERFLOW, %gs:(%edx)
+# endif
+#else
+ call __errno_location@plt
+ movl $EOVERFLOW, (%eax)
#endif
orl $-1, %eax
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/sem_post.c Fri Jan 11 00:22:59 2008
@@ -1,5 +1,5 @@
/* sem_post -- post to a POSIX semaphore. Generic futex-using version.
- Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@xxxxxxxxxx>, 2003.
@@ -31,7 +31,18 @@
{
struct new_sem *isem = (struct new_sem *) sem;
- int nr = atomic_increment_val (&isem->value);
+ __typeof (isem->value) cur;
+ do
+ {
+ cur = isem->value;
+ if (isem->value == SEM_VALUE_MAX)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+ }
+ while (atomic_compare_and_exchange_bool_acq (&isem->value, cur + 1, cur));
+
atomic_full_barrier ();
if (isem->nwaiters > 0)
{
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/structsem.sym Fri Jan 11 00:22:59 2008
@@ -1,3 +1,4 @@
+#include <limits.h>
#include <stddef.h>
#include <sched.h>
#include <bits/pthreadtypes.h>
@@ -8,3 +9,4 @@
VALUE offsetof (struct new_sem, value)
PRIVATE offsetof (struct new_sem, private)
NWAITERS offsetof (struct new_sem, nwaiters)
+SEM_VALUE_MAX SEM_VALUE_MAX
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S Fri Jan 11 00:22:59 2008
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -30,12 +30,21 @@
.type sem_post,@function
.align 16
sem_post:
+#if VALUE == 0
+ movl (%rdi), %eax
+#else
+ movl VALUE(%rdi), %eax
+#endif
+0: cmpl $SEM_VALUE_MAX, %eax
+ je 3f
+ leal 1(%eax), %esi
LOCK
#if VALUE == 0
- addl $1, (%rdi)
+ cmpxchgl %esi, (%rdi)
#else
- addl $1, VALUE(%rdi)
+ cmpxchgl %esi, VALUE(%rdi)
#endif
+ jnz 0b
cmpq $0, NWAITERS(%rdi)
je 2f
@@ -54,13 +63,28 @@
1:
#if USE___THREAD
- movq errno@gottpoff(%rip), %rdx
- movl $EINVAL, %fs:(%rdx)
+ movl $EINVAL, %eax
#else
callq __errno_location@plt
- movl $EINVAL, (%rax)
+ movl $EINVAL, %edx
+#endif
+ jmp 4f
+
+3:
+#if USE___THREAD
+ movl $EOVERFLOW, %eax
+#else
+ callq __errno_location@plt
+ movl $EOVERFLOW, %edx
#endif
+4:
+#if USE___THREAD
+ movq errno@gottpoff(%rip), %rdx
+ movl %eax, %fs:(%rdx)
+#else
+ movl %edx, (%rax)
+#endif
orl $-1, %eax
retq
.size sem_post,.-sem_post
Modified: fsf/trunk/libc/posix/tst-rfc3484-2.c
==============================================================================
--- fsf/trunk/libc/posix/tst-rfc3484-2.c (original)
+++ fsf/trunk/libc/posix/tst-rfc3484-2.c Fri Jan 11 00:22:59 2008
@@ -100,31 +100,32 @@
struct sort_result results[2];
+ size_t order[2];
results[0].dest_addr = &ai1;
results[0].got_source_addr = true;
results[0].source_addr_len = sizeof (so1);
results[0].source_addr_flags = 0;
- results[0].service_order = 0;
results[0].prefixlen = 16;
results[0].index = 0;
memcpy (&results[0].source_addr, &so1, sizeof (so1));
+ order[0] = 0;
results[1].dest_addr = &ai2;
results[1].got_source_addr = true;
results[1].source_addr_len = sizeof (so2);
results[1].source_addr_flags = 0;
- results[1].service_order = 1;
results[1].prefixlen = 16;
results[1].index = 0;
memcpy (&results[1].source_addr, &so2, sizeof (so2));
+ order[1] = 1;
struct sort_result_combo combo = { .results = results, .nresults = 2 };
- qsort_r (results, 2, sizeof (results[0]), rfc3484_sort, &combo);
+ qsort_r (order, 2, sizeof (order[0]), rfc3484_sort, &combo);
int result = 0;
- if (results[0].dest_addr->ai_family == AF_INET6)
+ if (results[order[0]].dest_addr->ai_family == AF_INET6)
{
puts ("wrong order in first test");
result |= 1;
@@ -136,24 +137,24 @@
results[1].got_source_addr = true;
results[1].source_addr_len = sizeof (so1);
results[1].source_addr_flags = 0;
- results[1].service_order = 1;
results[1].prefixlen = 16;
results[1].index = 0;
memcpy (&results[1].source_addr, &so1, sizeof (so1));
+ order[1] = 1;
results[0].dest_addr = &ai2;
results[0].got_source_addr = true;
results[0].source_addr_len = sizeof (so2);
results[0].source_addr_flags = 0;
- results[0].service_order = 0;
results[0].prefixlen = 16;
results[0].index = 0;
memcpy (&results[0].source_addr, &so2, sizeof (so2));
+ order[0] = 0;
- qsort_r (results, 2, sizeof (results[0]), rfc3484_sort, &combo);
+ qsort_r (order, 2, sizeof (order[0]), rfc3484_sort, &combo);
- if (results[0].dest_addr->ai_family == AF_INET6)
+ if (results[order[0]].dest_addr->ai_family == AF_INET6)
{
puts ("wrong order in second test");
result |= 1;
Modified: fsf/trunk/libc/posix/tst-rfc3484-3.c
==============================================================================
--- fsf/trunk/libc/posix/tst-rfc3484-3.c (original)
+++ fsf/trunk/libc/posix/tst-rfc3484-3.c Fri Jan 11 00:22:59 2008
@@ -66,6 +66,7 @@
#define naddrs (sizeof (addrs) / sizeof (addrs[0]))
static struct addrinfo ais[naddrs];
static struct sort_result results[naddrs];
+static size_t order[naddrs];
static const int expected[naddrs] =
{
@@ -111,18 +112,19 @@
memcpy(&results[i].source_addr, &so, sizeof (so));
results[i].source_addr_len = sizeof (so);
results[i].source_addr_flags = 0;
- results[i].service_order = i;
results[i].prefixlen = 8;
results[i].index = 0;
+
+ order[i] = i;
}
struct sort_result_combo combo = { .results = results, .nresults = naddrs };
- qsort_r (results, naddrs, sizeof (results[0]), rfc3484_sort, &combo);
+ qsort_r (order, naddrs, sizeof (order[0]), rfc3484_sort, &combo);
int result = 0;
for (int i = 0; i < naddrs; ++i)
{
- struct in_addr addr = ((struct sockaddr_in *) (results[i].dest_addr->ai_addr))->sin_addr;
+ struct in_addr addr = ((struct sockaddr_in *) (results[order[i]].dest_addr->ai_addr))->sin_addr;
int here = memcmp (&addr, &addrs[expected[i]].sin_addr,
sizeof (struct in_addr));
Modified: fsf/trunk/libc/posix/tst-rfc3484.c
==============================================================================
--- fsf/trunk/libc/posix/tst-rfc3484.c (original)
+++ fsf/trunk/libc/posix/tst-rfc3484.c Fri Jan 11 00:22:59 2008
@@ -64,6 +64,7 @@
#define naddrs (sizeof (addrs) / sizeof (addrs[0]))
static struct addrinfo ais[naddrs];
static struct sort_result results[naddrs];
+static size_t order[naddrs];
static int expected[naddrs] =
{
@@ -100,18 +101,19 @@
memcpy(&results[i].source_addr, &so, sizeof (so));
results[i].source_addr_len = sizeof (so);
results[i].source_addr_flags = 0;
- results[i].service_order = i;
results[i].prefixlen = 8;
results[i].index = 0;
+
+ order[i] = i;
}
struct sort_result_combo combo = { .results = results, .nresults = naddrs };
- qsort_r (results, naddrs, sizeof (results[0]), rfc3484_sort, &combo);
+ qsort_r (order, naddrs, sizeof (order[0]), rfc3484_sort, &combo);
int result = 0;
for (int i = 0; i < naddrs; ++i)
{
- struct in_addr addr = ((struct sockaddr_in *) (results[i].dest_addr->ai_addr))->sin_addr;
+ struct in_addr addr = ((struct sockaddr_in *) (results[order[i]].dest_addr->ai_addr))->sin_addr;
int here = memcmp (&addr, &addrs[expected[i]].sin_addr,
sizeof (struct in_addr));
Modified: fsf/trunk/libc/sysdeps/posix/getaddrinfo.c
==============================================================================
--- fsf/trunk/libc/sysdeps/posix/getaddrinfo.c (original)
+++ fsf/trunk/libc/sysdeps/posix/getaddrinfo.c Fri Jan 11 00:22:59 2008
@@ -997,8 +997,10 @@
struct sort_result
{
struct addrinfo *dest_addr;
- struct sockaddr_storage source_addr;
- size_t service_order;
+ /* Using sockaddr_storage is for now overkill. We only support IPv4
+ and IPv6 so far. If this changes at some point we can adjust the
+ type here. */
+ struct sockaddr_in6 source_addr;
uint8_t source_addr_len;
bool got_source_addr;
uint8_t source_addr_flags;
@@ -1047,13 +1049,11 @@
static int
-get_scope (const struct sockaddr_storage *ss)
+get_scope (const struct sockaddr_in6 *in6)
{
int scope;
- if (ss->ss_family == PF_INET6)
- {
- const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *) ss;
-
+ if (in6->sin6_family == PF_INET6)
+ {
if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
{
if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr))
@@ -1067,9 +1067,9 @@
else
scope = in6->sin6_addr.s6_addr[1] & 0xf;
}
- else if (ss->ss_family == PF_INET)
- {
- const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
+ else if (in6->sin6_family == PF_INET)
+ {
+ const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
size_t cnt = 0;
while (1)
@@ -1179,18 +1179,15 @@
static int
-match_prefix (const struct sockaddr_storage *ss,
+match_prefix (const struct sockaddr_in6 *in6,
const struct prefixentry *list, int default_val)
{
int idx;
struct sockaddr_in6 in6_mem;
- const struct sockaddr_in6 *in6;
-
- if (ss->ss_family == PF_INET6)
- in6 = (const struct sockaddr_in6 *) ss;
- else if (ss->ss_family == PF_INET)
- {
- const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
+
+ if (in6->sin6_family == PF_INET)
+ {
+ const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
/* Convert to IPv6 address. */
in6_mem.sin6_family = PF_INET6;
@@ -1209,7 +1206,7 @@
in6 = &in6_mem;
}
- else
+ else if (in6->sin6_family != PF_INET6)
return default_val;
for (idx = 0; ; ++idx)
@@ -1241,18 +1238,18 @@
static int
-get_label (const struct sockaddr_storage *ss)
+get_label (const struct sockaddr_in6 *in6)
{
/* XXX What is a good default value? */
- return match_prefix (ss, labels, INT_MAX);
+ return match_prefix (in6, labels, INT_MAX);
}
static int
-get_precedence (const struct sockaddr_storage *ss)
+get_precedence (const struct sockaddr_in6 *in6)
{
/* XXX What is a good default value? */
- return match_prefix (ss, precedence, 0);
+ return match_prefix (in6, precedence, 0);
}
@@ -1272,9 +1269,11 @@
static int
rfc3484_sort (const void *p1, const void *p2, void *arg)
{
- const struct sort_result *a1 = (const struct sort_result *) p1;
- const struct sort_result *a2 = (const struct sort_result *) p2;
+ const size_t idx1 = *(const size_t *) p1;
+ const size_t idx2 = *(const size_t *) p2;
struct sort_result_combo *src = (struct sort_result_combo *) arg;
+ struct sort_result *a1 = &src->results[idx1];
+ struct sort_result *a2 = &src->results[idx2];
/* Rule 1: Avoid unusable destinations.
We have the got_source_addr flag set if the destination is reachable. */
@@ -1287,10 +1286,10 @@
/* Rule 2: Prefer matching scope. Only interesting if both
destination addresses are IPv6. */
int a1_dst_scope
- = get_scope ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+ = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
int a2_dst_scope
- = get_scope ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+ = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
if (a1->got_source_addr)
{
@@ -1330,11 +1329,11 @@
if (a1->got_source_addr)
{
int a1_dst_label
- = get_label ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+ = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
int a1_src_label = get_label (&a1->source_addr);
int a2_dst_label
- = get_label ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+ = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
int a2_src_label = get_label (&a2->source_addr);
if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
@@ -1346,9 +1345,9 @@
/* Rule 6: Prefer higher precedence. */
int a1_prec
- = get_precedence ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+ = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
int a2_prec
- = get_precedence ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+ = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
if (a1_prec > a2_prec)
return -1;
@@ -1364,27 +1363,54 @@
(most?) cases. */
if (a1->index != a2->index)
{
- if (a1->native == -1 || a2->native == -1)
- {
- /* If we do not have the information use 'native' as the
- default. */
- int a1_native = 0;
- int a2_native = 0;
- __check_native (a1->index, &a1_native, a2->index, &a2_native);
+ int a1_native = a1->native;
+ int a2_native = a2->native;
+
+ if (a1_native == -1 || a2_native == -1)
+ {
+ uint32_t a1_index;
+ if (a1_native == -1)
+ {
+ /* If we do not have the information use 'native' as
+ the default. */
+ a1_native = 0;
+ a1_index = a1->index;
+ }
+ else
+ a1_index = 0xffffffffu;
+
+ uint32_t a2_index;
+ if (a2_native == -1)
+ {
+ /* If we do not have the information use 'native' as
+ the default. */
+ a2_native = 0;
+ a2_index = a2->index;
+ }
+ else
+ a2_index = 0xffffffffu;
+
+ __check_native (a1_index, &a1_native, a2_index, &a2_native);
/* Fill in the results in all the records. */
for (int i = 0; i < src->nresults; ++i)
- {
- if (a1->native == -1 && src->results[i].index == a1->index)
+ if (src->results[i].index == a1_index)
+ {
+ assert (src->results[i].native == -1
+ || src->results[i].native == a1_native);
src->results[i].native = a1_native;
- if (a2->native == -1 && src->results[i].index == a2->index)
+ }
+ else if (src->results[i].index == a2_index)
+ {
+ assert (src->results[i].native == -1
+ || src->results[i].native == a2_native);
src->results[i].native = a2_native;
- }
- }
-
- if (a1->native && !a2->native)
+ }
+ }
+
+ if (a1_native && !a2_native)
return -1;
- if (!a1->native && a2->native)
+ if (!a1_native && a2_native)
return 1;
}
}
@@ -1406,8 +1432,8 @@
if (a1->dest_addr->ai_family == PF_INET)
{
- assert (a1->source_addr.ss_family == PF_INET);
- assert (a2->source_addr.ss_family == PF_INET);
+ assert (a1->source_addr.sin6_family == PF_INET);
+ assert (a2->source_addr.sin6_family == PF_INET);
/* Outside of subnets, as defined by the network masks,
common address prefixes for IPv4 addresses make no sense.
@@ -1437,8 +1463,8 @@
}
else if (a1->dest_addr->ai_family == PF_INET6)
{
- assert (a1->source_addr.ss_family == PF_INET6);
- assert (a2->source_addr.ss_family == PF_INET6);
+ assert (a1->source_addr.sin6_family == PF_INET6);
+ assert (a2->source_addr.sin6_family == PF_INET6);
struct sockaddr_in6 *in1_dst;
struct sockaddr_in6 *in1_src;
@@ -1478,7 +1504,7 @@
compare with the value indicating the order in which the entries
have been received from the services. NB: no two entries can have
the same order so the test will never return zero. */
- return a1->service_order < a2->service_order ? -1 : 1;
+ return idx1 < idx2 ? -1 : 1;
}
@@ -2100,6 +2126,7 @@
__libc_once (once, gaiconf_init);
/* Sort results according to RFC 3484. */
struct sort_result results[nresults];
+ size_t order[nresults];
struct addrinfo *q;
struct addrinfo *last = NULL;
char *canonname = NULL;
@@ -2115,8 +2142,8 @@
for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
{
results[i].dest_addr = q;
- results[i].service_order = i;
results[i].native = -1;
+ order[i] = i;
/* If we just looked up the address for a different
protocol, reuse the result. */
@@ -2255,16 +2282,16 @@
__libc_lock_lock (lock);
if (old_once && gaiconf_reload_flag)
gaiconf_reload ();
- qsort_r (results, nresults, sizeof (results[0]), rfc3484_sort, &src);
+ qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
__libc_lock_unlock (lock);
}
else
- qsort_r (results, nresults, sizeof (results[0]), rfc3484_sort, &src);
+ qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
/* Queue the results up as they come out of sorting. */
- q = p = results[0].dest_addr;
+ q = p = results[order[0]].dest_addr;
for (i = 1; i < nresults; ++i)
- q = q->ai_next = results[i].dest_addr;
+ q = q->ai_next = results[order[i]].dest_addr;
q->ai_next = NULL;
/* Fill in the canonical name into the new first entry. */