[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r4186 - in /fsf/trunk/libc: ./ include/ sysdeps/i386/i586/ sysdeps/posix/ sysdeps/unix/sysv/linux/
- To: commits@xxxxxxxxxx
- Subject: [commits] r4186 - in /fsf/trunk/libc: ./ include/ sysdeps/i386/i586/ sysdeps/posix/ sysdeps/unix/sysv/linux/
- From: eglibc@xxxxxxxxxx
- Date: Tue, 13 Nov 2007 08:03:13 -0000
Author: eglibc
Date: Tue Nov 13 00:03:12 2007
New Revision: 4186
Log:
Import glibc-mainline for 2007-11-13
Added:
fsf/trunk/libc/sysdeps/i386/i586/memcpy_chk.S
fsf/trunk/libc/sysdeps/i386/i586/mempcpy_chk.S
fsf/trunk/libc/sysdeps/i386/i586/memset_chk.S
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/include/ifaddrs.h
fsf/trunk/libc/sysdeps/posix/getaddrinfo.c
fsf/trunk/libc/sysdeps/unix/sysv/linux/check_pf.c
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Tue Nov 13 00:03:12 2007
@@ -1,3 +1,21 @@
+2007-09-13 H.J. Lu <hongjiu.lu@xxxxxxxxx>
+
+ * sysdeps/i386/i586/memcpy_chk.S: New file.
+ * sysdeps/i386/i586/mempcpy_chk.S: Likewise.
+ * sysdeps/i386/i586/memset_chk.S: Likewise.
+
+2007-11-12 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * include/ifaddrs.c (struct in6addrinfo): Add prefixlen field.
+ * sysdeps/unix/sysv/linux/check_pf.c (make_request): Always return
+ list of interfaces. Also store prefix length.
+ * sysdeps/posix/getaddrinfo.c (sort_result): Add prefixlen element.
+ (rfc3484_sort): In rule 9, for IPv4 addresses count only matching
+ prefix if source and destination address are in the same subnet.
+ (getaddrinfo): Always call __check_pf. Fill in prefixlen field.
+ Always look for matching record in in6ai list.
+ Correct source_addr_len value for IPv6->IPv4 converted records.
+
2007-11-11 Roland McGrath <roland@xxxxxxxx>
* include/kernel-features.h: New file.
Modified: fsf/trunk/libc/include/ifaddrs.h
==============================================================================
--- fsf/trunk/libc/include/ifaddrs.h (original)
+++ fsf/trunk/libc/include/ifaddrs.h Tue Nov 13 00:03:12 2007
@@ -12,7 +12,9 @@
in6ai_deprecated = 1,
in6ai_temporary = 2,
in6ai_homeaddress = 4
- } flags;
+ } flags:8;
+ uint8_t prefixlen;
+ uint16_t :16;
uint32_t addr[4];
};
Added: fsf/trunk/libc/sysdeps/i386/i586/memcpy_chk.S
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i586/memcpy_chk.S (added)
+++ fsf/trunk/libc/sysdeps/i386/i586/memcpy_chk.S Tue Nov 13 00:03:12 2007
@@ -1,0 +1,1 @@
+#include <sysdeps/i386/i686/memcpy_chk.S>
Added: fsf/trunk/libc/sysdeps/i386/i586/mempcpy_chk.S
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i586/mempcpy_chk.S (added)
+++ fsf/trunk/libc/sysdeps/i386/i586/mempcpy_chk.S Tue Nov 13 00:03:12 2007
@@ -1,0 +1,1 @@
+#include <sysdeps/i386/i686/mempcpy_chk.S>
Added: fsf/trunk/libc/sysdeps/i386/i586/memset_chk.S
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/i586/memset_chk.S (added)
+++ fsf/trunk/libc/sysdeps/i386/i586/memset_chk.S Tue Nov 13 00:03:12 2007
@@ -1,0 +1,1 @@
+#include <sysdeps/i386/i686/memset_chk.S>
Modified: fsf/trunk/libc/sysdeps/posix/getaddrinfo.c
==============================================================================
--- fsf/trunk/libc/sysdeps/posix/getaddrinfo.c (original)
+++ fsf/trunk/libc/sysdeps/posix/getaddrinfo.c Tue Nov 13 00:03:12 2007
@@ -1006,6 +1006,7 @@
uint8_t source_addr_len;
bool got_source_addr;
uint8_t source_addr_flags;
+ uint8_t prefixlen;
};
@@ -1223,7 +1224,7 @@
fls (uint32_t a)
{
uint32_t mask;
- int n = 0;
+ int n;
for (n = 0, mask = 1 << 31; n < 32; mask >>= 1, ++n)
if ((a & mask) != 0)
break;
@@ -1350,20 +1351,31 @@
assert (a1->source_addr.ss_family == PF_INET);
assert (a2->source_addr.ss_family == PF_INET);
- struct sockaddr_in *in1_dst;
- struct sockaddr_in *in1_src;
- struct sockaddr_in *in2_dst;
- struct sockaddr_in *in2_src;
-
- in1_dst = (struct sockaddr_in *) a1->dest_addr->ai_addr;
- in1_src = (struct sockaddr_in *) &a1->source_addr;
- in2_dst = (struct sockaddr_in *) a2->dest_addr->ai_addr;
- in2_src = (struct sockaddr_in *) &a2->source_addr;
-
- bit1 = fls (ntohl (in1_dst->sin_addr.s_addr
- ^ in1_src->sin_addr.s_addr));
- bit2 = fls (ntohl (in2_dst->sin_addr.s_addr
- ^ in2_src->sin_addr.s_addr));
+ /* Outside of subnets, as defined by the network masks,
+ common address prefixes for IPv4 addresses make no sense.
+ So, define a non-zero value only if source and
+ destination address are on the same subnet. */
+ struct sockaddr_in *in1_dst
+ = (struct sockaddr_in *) a1->dest_addr->ai_addr;
+ in_addr_t in1_dst_addr = ntohl (in1_dst->sin_addr.s_addr);
+ struct sockaddr_in *in1_src
+ = (struct sockaddr_in *) &a1->source_addr;
+ in_addr_t in1_src_addr = ntohl (in1_src->sin_addr.s_addr);
+ in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
+
+ if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
+ bit1 = fls (in1_dst_addr ^ in1_src_addr);
+
+ struct sockaddr_in *in2_dst
+ = (struct sockaddr_in *) a2->dest_addr->ai_addr;
+ in_addr_t in2_dst_addr = ntohl (in2_dst->sin_addr.s_addr);
+ struct sockaddr_in *in2_src
+ = (struct sockaddr_in *) &a2->source_addr;
+ in_addr_t in2_src_addr = ntohl (in2_src->sin_addr.s_addr);
+ in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
+
+ if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
+ bit2 = fls (in2_dst_addr ^ in2_src_addr);
}
else if (a1->dest_addr->ai_family == PF_INET6)
{
@@ -1799,63 +1811,42 @@
int sockfd = -1;
pid_t nl_pid;
#endif
- /* We might need information about what kind of interfaces are available.
- But even if AI_ADDRCONFIG is not used, if the user requested IPv6
- addresses we have to know whether an address is deprecated or
- temporary. */
- if ((hints->ai_flags & AI_ADDRCONFIG) || hints->ai_family == PF_UNSPEC
- || hints->ai_family == PF_INET6)
- {
- /* Determine whether we have IPv4 or IPv6 interfaces or both. We
- cannot cache the results since new interfaces could be added at
- any time. */
- __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
+ /* We might need information about what interfaces are available.
+ Also determine whether we have IPv4 or IPv6 interfaces or both. We
+ cannot cache the results since new interfaces could be added at
+ any time. */
+ __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
#ifdef HAVE_NETLINK_ROUTE
- if (! __no_netlink_support)
- {
- sockfd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-
- struct sockaddr_nl nladdr;
- memset (&nladdr, '\0', sizeof (nladdr));
- nladdr.nl_family = AF_NETLINK;
-
- socklen_t addr_len = sizeof (nladdr);
-
- if (sockfd >= 0
- && __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
- && __getsockname (sockfd, (struct sockaddr *) &nladdr,
- &addr_len) == 0
- && make_request (sockfd, nladdr.nl_pid, &seen_ipv4, &seen_ipv6,
- in6ai, in6ailen) == 0)
- {
- /* It worked. */
- nl_pid = nladdr.nl_pid;
- goto got_netlink_socket;
- }
-
- if (sockfd >= 0)
- close_not_cancel_no_status (sockfd);
-
-#if __ASSUME_NETLINK_SUPPORT == 0
- /* Remember that there is no netlink support. */
- if (errno != EMFILE && errno != ENFILE)
- __no_netlink_support = 1;
-#else
- else
- {
- if (errno != EMFILE && errno != ENFILE)
- sockfd = -2;
-
- /* We cannot determine what interfaces are available. Be
- pessimistic. */
- seen_ipv4 = true;
- seen_ipv6 = true;
- return;
- }
+ if (! __no_netlink_support)
+ {
+ sockfd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+
+ struct sockaddr_nl nladdr;
+ memset (&nladdr, '\0', sizeof (nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ socklen_t addr_len = sizeof (nladdr);
+
+ if (sockfd >= 0
+ && __bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
+ && __getsockname (sockfd, (struct sockaddr *) &nladdr,
+ &addr_len) == 0
+ && make_request (sockfd, nladdr.nl_pid, &seen_ipv4, &seen_ipv6,
+ in6ai, in6ailen) == 0)
+ {
+ /* It worked. */
+ nl_pid = nladdr.nl_pid;
+ goto got_netlink_socket;
+ }
+
+ if (sockfd >= 0)
+ close_not_cancel_no_status (sockfd);
+
+ /* Remember that there is no netlink support. */
+ if (errno != EMFILE && errno != ENFILE)
+ __no_netlink_support = 1;
+ }
#endif
- }
-#endif
- }
#ifdef HAVE_NETLINK_ROUTE
got_netlink_socket:
@@ -1958,7 +1949,6 @@
for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
{
results[i].dest_addr = q;
- results[i].got_source_addr = false;
results[i].service_order = i;
/* If we just looked up the address for a different
@@ -1971,10 +1961,13 @@
results[i].source_addr_len = results[i - 1].source_addr_len;
results[i].got_source_addr = results[i - 1].got_source_addr;
results[i].source_addr_flags = results[i - 1].source_addr_flags;
+ results[i].prefixlen = results[i - 1].prefixlen;
}
else
{
+ results[i].got_source_addr = false;
results[i].source_addr_flags = 0;
+ results[i].prefixlen = 0;
/* We overwrite the type with SOCK_DGRAM since we do not
want connect() to connect to the other side. If we
@@ -2005,22 +1998,39 @@
results[i].source_addr_len = sl;
results[i].got_source_addr = true;
- if (q->ai_family == AF_INET6 && in6ai != NULL)
+ if (in6ai != NULL)
{
/* See whether the source address is on the list of
deprecated or temporary addresses. */
struct in6addrinfo tmp;
- struct sockaddr_in6 *sin6p
- = (struct sockaddr_in6 *) &results[i].source_addr;
- memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
+
+ if (q->ai_family == AF_INET && af == AF_INET)
+ {
+ struct sockaddr_in *sinp
+ = (struct sockaddr_in *) &results[i].source_addr;
+ tmp.addr[0] = 0;
+ tmp.addr[1] = 0;
+ tmp.addr[2] = htonl (0xffff);
+ tmp.addr[3] = sinp->sin_addr.s_addr;
+ }
+ else
+ {
+ struct sockaddr_in6 *sin6p
+ = (struct sockaddr_in6 *) &results[i].source_addr;
+ memcpy (tmp.addr, &sin6p->sin6_addr, IN6ADDRSZ);
+ }
struct in6addrinfo *found
= bsearch (&tmp, in6ai, in6ailen, sizeof (*in6ai),
in6aicmp);
if (found != NULL)
- results[i].source_addr_flags = found->flags;
+ {
+ results[i].source_addr_flags = found->flags;
+ results[i].prefixlen = found->prefixlen;
+ }
}
- else if (q->ai_family == AF_INET && af == AF_INET6)
+
+ 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. */
@@ -2029,10 +2039,17 @@
struct sockaddr_in *sin
= (struct sockaddr_in *) &results[i].source_addr;
assert (IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr32));
+ sin->sin_family = AF_INET;
+ /* We do not have to initialize sin_port since this
+ fields has the same position and size in the IPv6
+ structure. */
+ assert (offsetof (struct sockaddr_in, sin_port)
+ == offsetof (struct sockaddr_in6, sin6_port));
+ assert (sizeof (sin->sin_port)
+ == sizeof (sin6->sin6_port));
memcpy (&sin->sin_addr,
&sin6->sin6_addr.s6_addr32[3], INADDRSZ);
- results[i].source_addr_len = INADDRSZ;
- sin->sin_family = AF_INET;
+ results[i].source_addr_len = sizeof (struct sockaddr_in);
}
}
else if (errno == EAFNOSUPPORT && af == AF_INET6
Modified: fsf/trunk/libc/sysdeps/unix/sysv/linux/check_pf.c
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/check_pf.c (original)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/check_pf.c Tue Nov 13 00:03:12 2007
@@ -145,92 +145,69 @@
struct rtattr *rta = IFA_RTA (ifam);
size_t len = nlmh->nlmsg_len - NLMSG_LENGTH (sizeof (*ifam));
- switch (ifam->ifa_family)
+ if (ifam->ifa_family != AF_INET
+ && ifam->ifa_family != AF_INET6)
+ continue;
+
+ const void *local = NULL;
+ const void *address = NULL;
+ while (RTA_OK (rta, len))
{
- const void *local;
- const void *address;
-
- case AF_INET:
- local = NULL;
- address = NULL;
- while (RTA_OK (rta, len))
+ switch (rta->rta_type)
{
- switch (rta->rta_type)
- {
- case IFA_LOCAL:
- local = RTA_DATA (rta);
- break;
-
- case IFA_ADDRESS:
- address = RTA_DATA (rta);
- goto out_v4;
- }
-
- rta = RTA_NEXT (rta, len);
+ case IFA_LOCAL:
+ local = RTA_DATA (rta);
+ break;
+
+ case IFA_ADDRESS:
+ address = RTA_DATA (rta);
+ goto out;
}
- if (local != NULL)
+ rta = RTA_NEXT (rta, len);
+ }
+
+ if (local != NULL)
+ {
+ address = local;
+ out:
+ if (ifam->ifa_family != AF_INET)
{
- out_v4:
- if (*(const in_addr_t *) (address ?: local)
+ if (*(const in_addr_t *) address
!= htonl (INADDR_LOOPBACK))
*seen_ipv4 = true;
}
- break;
-
- case AF_INET6:
- local = NULL;
- address = NULL;
- while (RTA_OK (rta, len))
+ else
{
- switch (rta->rta_type)
- {
- case IFA_LOCAL:
- local = RTA_DATA (rta);
- break;
-
- case IFA_ADDRESS:
- address = RTA_DATA (rta);
- goto out_v6;
- }
-
- rta = RTA_NEXT (rta, len);
- }
-
- if (local != NULL)
- {
- out_v6:
- if (!IN6_IS_ADDR_LOOPBACK (address ?: local))
+ if (!IN6_IS_ADDR_LOOPBACK (address))
*seen_ipv6 = true;
}
-
- if (ifam->ifa_flags & (IFA_F_DEPRECATED
- | IFA_F_TEMPORARY
- | IFA_F_HOMEADDRESS
- | IFA_F_OPTIMISTIC))
- {
- struct in6ailist *newp = alloca (sizeof (*newp));
- newp->info.flags = (((ifam->ifa_flags
- & (IFA_F_DEPRECATED
- | IFA_F_OPTIMISTIC))
- ? in6ai_deprecated : 0)
- | ((ifam->ifa_flags
- & IFA_F_TEMPORARY)
- ? in6ai_temporary : 0)
- | ((ifam->ifa_flags
- & IFA_F_HOMEADDRESS)
- ? in6ai_homeaddress : 0));
- memcpy (newp->info.addr, address ?: local,
- sizeof (newp->info.addr));
- newp->next = in6ailist;
- in6ailist = newp;
- ++in6ailistlen;
- }
- break;
- default:
- /* Ignore. */
- break;
}
+
+ struct in6ailist *newp = alloca (sizeof (*newp));
+ newp->info.flags = (((ifam->ifa_flags
+ & (IFA_F_DEPRECATED
+ | IFA_F_OPTIMISTIC))
+ ? in6ai_deprecated : 0)
+ | ((ifam->ifa_flags
+ & IFA_F_TEMPORARY)
+ ? in6ai_temporary : 0)
+ | ((ifam->ifa_flags
+ & IFA_F_HOMEADDRESS)
+ ? in6ai_homeaddress : 0));
+ newp->info.prefixlen = ifam->ifa_prefixlen;
+ if (ifam->ifa_family == AF_INET)
+ {
+ newp->info.addr[0] = 0;
+ newp->info.addr[1] = 0;
+ newp->info.addr[2] = htonl (0xffff);
+ newp->info.addr[3] = *(const in_addr_t *) address;
+ }
+ else
+ memcpy (newp->info.addr, address, sizeof (newp->info.addr));
+ newp->next = in6ailist;
+ in6ailist = newp;
+ ++in6ailistlen;
}
else if (nlmh->nlmsg_type == NLMSG_DONE)
/* We found the end, leave the loop. */