diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-01-11 07:45:15 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2008-01-11 07:45:15 +0000 |
commit | 07b7d301cc62d3f4ff1bbaf668ddc2510f7a55d8 (patch) | |
tree | b7a82272de69e03b1850cb2cf93e25f258769fa2 /sysdeps | |
parent | 1e44f485d223b0f2f7b194935a0109cb7b713cc3 (diff) | |
download | glibc-07b7d301cc62d3f4ff1bbaf668ddc2510f7a55d8.tar.gz glibc-07b7d301cc62d3f4ff1bbaf668ddc2510f7a55d8.tar.xz glibc-07b7d301cc62d3f4ff1bbaf668ddc2510f7a55d8.zip |
Updated to fedora-glibc-20080111T0737
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/posix/getaddrinfo.c | 125 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/makecontext.S | 10 |
2 files changed, 82 insertions, 53 deletions
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index e8f4099b7f..8746725d7a 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -997,8 +997,10 @@ gaih_inet (const char *name, const struct gaih_service *service, 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 const struct scopeentry *scopes; static int -get_scope (const struct sockaddr_storage *ss) +get_scope (const struct sockaddr_in6 *in6) { int scope; - if (ss->ss_family == PF_INET6) + if (in6->sin6_family == PF_INET6) { - const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *) ss; - if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr)) { if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr)) @@ -1067,9 +1067,9 @@ get_scope (const struct sockaddr_storage *ss) else scope = in6->sin6_addr.s6_addr[1] & 0xf; } - else if (ss->ss_family == PF_INET) + else if (in6->sin6_family == PF_INET) { - const struct sockaddr_in *in = (const struct sockaddr_in *) ss; + const struct sockaddr_in *in = (const struct sockaddr_in *) in6; size_t cnt = 0; while (1) @@ -1179,18 +1179,15 @@ static const struct prefixentry default_precedence[] = 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) + if (in6->sin6_family == PF_INET) { - const struct sockaddr_in *in = (const struct sockaddr_in *) ss; + const struct sockaddr_in *in = (const struct sockaddr_in *) in6; /* Convert to IPv6 address. */ in6_mem.sin6_family = PF_INET6; @@ -1209,7 +1206,7 @@ match_prefix (const struct sockaddr_storage *ss, in6 = &in6_mem; } - else + else if (in6->sin6_family != PF_INET6) return default_val; for (idx = 0; ; ++idx) @@ -1241,18 +1238,18 @@ match_prefix (const struct sockaddr_storage *ss, 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 @@ fls (uint32_t a) 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 @@ rfc3484_sort (const void *p1, const void *p2, void *arg) /* 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 @@ rfc3484_sort (const void *p1, const void *p2, void *arg) 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 @@ rfc3484_sort (const void *p1, const void *p2, void *arg) /* 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 @@ rfc3484_sort (const void *p1, const void *p2, void *arg) (most?) cases. */ if (a1->index != a2->index) { - if (a1->native == -1 || a2->native == -1) + int a1_native = a1->native; + int a2_native = a2->native; + + 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); + 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 @@ rfc3484_sort (const void *p1, const void *p2, void *arg) 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 @@ rfc3484_sort (const void *p1, const void *p2, void *arg) } 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 @@ rfc3484_sort (const void *p1, const void *p2, void *arg) 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 @@ getaddrinfo (const char *name, const char *service, __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 @@ getaddrinfo (const char *name, const char *service, 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 @@ getaddrinfo (const char *name, const char *service, __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. */ diff --git a/sysdeps/unix/sysv/linux/i386/makecontext.S b/sysdeps/unix/sysv/linux/i386/makecontext.S index 89be1176f7..ad2340555a 100644 --- a/sysdeps/unix/sysv/linux/i386/makecontext.S +++ b/sysdeps/unix/sysv/linux/i386/makecontext.S @@ -1,5 +1,5 @@ /* Create new context. - Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2005, 2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -41,13 +41,15 @@ ENTRY(__makecontext) movl 12(%esp), %ecx movl %ecx, oEBX(%eax) - /* Make room on the new stack for the parameters. */ + /* Make room on the new stack for the parameters. + Room for the arguments, return address (== L(exitcode)) and + oLINK pointer is needed. One of the pointer sizes is subtracted + after aligning the stack. */ negl %ecx - leal -8(%edx,%ecx,4), %edx + leal -4(%edx,%ecx,4), %edx negl %ecx /* Align the stack. */ - addl $16, %edx andl $0xfffffff0, %edx subl $4, %edx |