summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteinar H. Gunderson <sesse@google.com>2010-12-20 11:48:07 +0100
committerSteinar H. Gunderson <sesse@google.com>2011-01-14 21:41:18 +0100
commit2e23e29245aa42d0f9419187c94e72dba3888eef (patch)
tree1ccf9d9a8b5ed49dea39f6199f86290f18d19661
parentf4dca7be3b7bc181f1534be187428c5a52cb8c6a (diff)
downloadbionic-2e23e29245aa42d0f9419187c94e72dba3888eef.zip
bionic-2e23e29245aa42d0f9419187c94e72dba3888eef.tar.gz
bionic-2e23e29245aa42d0f9419187c94e72dba3888eef.tar.bz2
Backport (simple cherry-pick) d33019030c1f0cddca557f9659e3c471bde0e6a9
to gingerbread. Implement RFC3484 policy table changes from draft-ietf-6man-rfc3484-revise-01. The changes in a nutshell: - Handle v4-mapped as different from v4-compat (this was probably an existing bug in our code). - Add policy entries for ULA, above most everything else. - Put v4-compat, old-style IPv6 site-local and 6bone addresses way down in the preference table. The rest is just shuffling numbers around (no actual changes to priority).
-rw-r--r--libc/netbsd/net/getaddrinfo.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index aa3b81a..7ae1439 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -1327,9 +1327,13 @@ _get_scope(const struct sockaddr *addr)
#define IN6_IS_ADDR_6TO4(a) \
(((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02))
+/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */
+#define IN6_IS_ADDR_6BONE(a) \
+ (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe))
+
/*
* Get the label for a given IPv4/IPv6 address.
- * RFC 3484, section 2.1, plus Teredo added in with label 5.
+ * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
*/
/*ARGSUSED*/
@@ -1337,19 +1341,27 @@ static int
_get_label(const struct sockaddr *addr)
{
if (addr->sa_family == AF_INET) {
- return 4;
+ return 3;
} else if (addr->sa_family == AF_INET6) {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
return 0;
- } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
+ } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
+ return 1;
+ } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
return 3;
+ } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
+ return 4;
} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
return 5;
- } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
- return 2;
+ } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
+ return 10;
+ } else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
+ return 11;
+ } else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
+ return 12;
} else {
- return 1;
+ return 2;
}
} else {
/*
@@ -1362,7 +1374,7 @@ _get_label(const struct sockaddr *addr)
/*
* Get the precedence for a given IPv4/IPv6 address.
- * RFC 3484, section 2.1, plus Teredo added in with precedence 25.
+ * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
*/
/*ARGSUSED*/
@@ -1370,22 +1382,28 @@ static int
_get_precedence(const struct sockaddr *addr)
{
if (addr->sa_family == AF_INET) {
- return 10;
+ return 30;
} else if (addr->sa_family == AF_INET6) {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
+ return 60;
+ } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
return 50;
- } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
+ } else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
+ return 30;
+ } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
return 20;
} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
- return 25;
- } else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
- return 30;
+ return 10;
+ } else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
+ IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
+ IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
+ return 1;
} else {
return 40;
}
} else {
- return 5;
+ return 1;
}
}