aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Alexander Polcyn <apolcyn@google.com>2017-12-28 18:09:19 -0800
committerGravatar Alexander Polcyn <apolcyn@google.com>2018-03-20 23:51:23 -0700
commitd21ee150765c73876992bbf06c716b4600ba047f (patch)
treeef97400ceb7007fc0c1498e61adf851cdc0eaa26
parent690dde672a877083e29ee5af0b8252697aa48fa0 (diff)
Stop relying on certain ipv6 macros. Also bazel build updates.
Fix error just made in bazel/grpc_build_system.bzl Fix merge conflict support/env -> gpr/env
-rw-r--r--bazel/grpc_build_system.bzl4
-rw-r--r--test/cpp/naming/address_sorting_test.cc112
-rw-r--r--third_party/address_sorting/BUILD5
-rw-r--r--third_party/address_sorting/address_sorting.bzl38
-rw-r--r--third_party/address_sorting/address_sorting.c49
-rw-r--r--third_party/address_sorting/address_sorting_internal.h3
6 files changed, 196 insertions, 15 deletions
diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl
index 2b4ec68aa3..03a6bd7824 100644
--- a/bazel/grpc_build_system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -38,11 +38,11 @@ def _get_external_deps(external_deps):
for dep in external_deps:
if dep == "nanopb":
ret += ["grpc_nanopb"]
+ elif dep == "address_sorting":
+ ret += ["//third_party/address_sorting"]
elif dep == "cares":
ret += select({"//:grpc_no_ares": [],
"//conditions:default": ["//external:cares"],})
- elif dep == "address_sorting":
- ret += ["//third_party/address_sorting"]
else:
ret += ["//external:" + dep]
return ret
diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc
index d2c73a5674..3648364788 100644
--- a/test/cpp/naming/address_sorting_test.cc
+++ b/test/cpp/naming/address_sorting_test.cc
@@ -46,7 +46,7 @@
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/env.h"
+#include "src/core/lib/gpr/env.h"
#include "src/core/lib/support/string.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -326,6 +326,61 @@ TEST(AddressSortingTest,
}
TEST(AddressSortingTest,
+ TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) {
+ bool ipv4_supported = true;
+ bool ipv6_supported = true;
+// Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
+#if GPR_APPLE == 1
+ const char* v4_compat_dest = "[::0.0.0.2]:443";
+ const char* v4_compat_src = "[::0.0.0.2]:0";
+#else
+ const char* v4_compat_dest = "[::2]:443";
+ const char* v4_compat_src = "[::2]:0";
+#endif
+ OverrideAddressSortingSourceAddrFactory(
+ ipv4_supported, ipv6_supported,
+ {
+ {"[::1]:443", {"[::1]:0", AF_INET6}},
+ {v4_compat_dest, {v4_compat_src, AF_INET6}},
+ });
+ grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ {v4_compat_dest, AF_INET6},
+ {"[::1]:443", AF_INET6},
+ });
+ grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ VerifyLbAddrOutputs(lb_addrs, {
+ "[::1]:443",
+ v4_compat_dest,
+ });
+}
+
+TEST(AddressSortingTest,
+ TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
+ bool ipv4_supported = true;
+ bool ipv6_supported = true;
+ OverrideAddressSortingSourceAddrFactory(
+ ipv4_supported, ipv6_supported,
+ {
+ // 1234::2 for src and dest to make sure that prefix matching has no
+ // influence on this test.
+ {"[1234::2]:443", {"[1234::2]:0", AF_INET6}},
+ {"[::1]:443", {"[::1]:0", AF_INET6}},
+ });
+ grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ {"[1234::2]:443", AF_INET6},
+ {"[::1]:443", AF_INET6},
+ });
+ grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ VerifyLbAddrOutputs(
+ lb_addrs,
+ {
+ // ::1 should match the localhost precedence entry and be prioritized
+ "[::1]:443",
+ "[1234::2]:443",
+ });
+}
+
+TEST(AddressSortingTest,
TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
bool ipv4_supported = true;
bool ipv6_supported = true;
@@ -391,6 +446,30 @@ TEST(AddressSortingTest,
});
}
+TEST(
+ AddressSortingTest,
+ TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) {
+ bool ipv4_supported = true;
+ bool ipv6_supported = true;
+ OverrideAddressSortingSourceAddrFactory(
+ ipv4_supported, ipv6_supported,
+ {
+ {"[::ffff:0.0.0.2]:443", {"[::ffff:0.0.0.3]:0", AF_INET6}},
+ {"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
+ });
+ grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ {"[::ffff:0.0.0.2]:443", AF_INET6},
+ {"[1234::2]:443", AF_INET6},
+ });
+ grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ VerifyLbAddrOutputs(lb_addrs, {
+ // ::ffff:0:2 should match the v4-mapped
+ // precedence entry and be deprioritized.
+ "[1234::2]:443",
+ "[::ffff:0.0.0.2]:443",
+ });
+}
+
/* Tests for rule 8 */
TEST(AddressSortingTest, TestPrefersSmallerScope) {
@@ -611,6 +690,37 @@ TEST(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
});
}
+TEST(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
+ bool ipv4_supported = true;
+ bool ipv6_supported = true;
+// Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
+#if GPR_APPLE == 1
+ const char* v4_compat_dest = "[::0.0.0.2]:443";
+ const char* v4_compat_src = "[::0.0.0.3]:0";
+#else
+ const char* v4_compat_dest = "[::2]:443";
+ const char* v4_compat_src = "[::3]:0";
+#endif
+ OverrideAddressSortingSourceAddrFactory(
+ ipv4_supported, ipv6_supported,
+ {
+ {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}},
+ {v4_compat_dest, {v4_compat_src, AF_INET6}},
+ });
+ grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ {"[fec0::2000]:443", AF_INET6},
+ {v4_compat_dest, AF_INET6},
+ });
+ grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ VerifyLbAddrOutputs(lb_addrs,
+ {
+ // The sort should be stable since
+ // v4-compatible has same precedence as site-local.
+ "[fec0::2000]:443",
+ v4_compat_dest,
+ });
+}
+
int main(int argc, char** argv) {
const char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
if (resolver == NULL || strlen(resolver) == 0) {
diff --git a/third_party/address_sorting/BUILD b/third_party/address_sorting/BUILD
index 9462829766..defa0851aa 100644
--- a/third_party/address_sorting/BUILD
+++ b/third_party/address_sorting/BUILD
@@ -36,11 +36,13 @@ package(
],
)
+load(":address_sorting.bzl", "address_sorting_cc_library")
+
licenses(["notice"]) # BSD
exports_files(["LICENSE"])
-cc_library(
+address_sorting_cc_library(
name = "address_sorting",
srcs = [
"address_sorting.c",
@@ -51,6 +53,7 @@ cc_library(
"address_sorting.h",
"address_sorting_internal.h",
],
+ copts = ["-std=c99"],
includes = [
".",
],
diff --git a/third_party/address_sorting/address_sorting.bzl b/third_party/address_sorting/address_sorting.bzl
new file mode 100644
index 0000000000..25d008442b
--- /dev/null
+++ b/third_party/address_sorting/address_sorting.bzl
@@ -0,0 +1,38 @@
+# $NetBSD: getaddrinfo.c,v 1.82 2006/03/25 12:09:40 rpaulo Exp $ */
+# $KAME: getaddrinfo.c,v 1.29 2000/08/31 17:26:57 itojun Exp $ */
+#
+# Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the project nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+def address_sorting_cc_library(name, srcs, hdrs, copts, includes):
+ native.cc_library(
+ name = name,
+ srcs = srcs,
+ hdrs = hdrs,
+ copts = copts,
+ includes = includes,
+ )
diff --git a/third_party/address_sorting/address_sorting.c b/third_party/address_sorting/address_sorting.c
index 977567f36a..ec46099bec 100644
--- a/third_party/address_sorting/address_sorting.c
+++ b/third_party/address_sorting/address_sorting.c
@@ -79,6 +79,33 @@ static int ipv6_prefix_match_length(const struct sockaddr_in6* sa,
return cur_bit;
}
+static int in6_is_addr_loopback(const struct in6_addr* ipv6_address) {
+ uint32_t* bits32 = (uint32_t*)ipv6_address;
+ return bits32[0] == 0 && bits32[1] == 0 && bits32[2] == 0 &&
+ bits32[3] == htonl(1);
+}
+
+static int in6_is_addr_v4mapped(const struct in6_addr* ipv6_address) {
+ uint32_t* bits32 = (uint32_t*)ipv6_address;
+ return bits32[0] == 0 && bits32[1] == 0 && bits32[2] == htonl(0x0000ffff);
+}
+
+static int in6_is_addr_v4compat(const struct in6_addr* ipv6_address) {
+ uint32_t* bits32 = (uint32_t*)ipv6_address;
+ return bits32[0] == 0 && bits32[1] == 0 && bits32[2] == 0 && bits32[3] != 0 &&
+ bits32[3] != htonl(1);
+}
+
+static int in6_is_addr_sitelocal(const struct in6_addr* ipv6_address) {
+ uint8_t* bytes = (uint8_t*)ipv6_address;
+ return bytes[0] == 0xfe && (bytes[1] & 0xc0) == 0xc0;
+}
+
+static int in6_is_addr_linklocal(const struct in6_addr* ipv6_address) {
+ uint8_t* bytes = (uint8_t*)ipv6_address;
+ return bytes[0] == 0xfe && (bytes[1] & 0xc0) == 0x80;
+}
+
static int in6_is_addr_6to4(const struct in6_addr* ipv6_address) {
uint8_t* bytes = (uint8_t*)ipv6_address;
return bytes[0] == 0x20 && bytes[1] == 0x02;
@@ -121,9 +148,9 @@ static int get_label_value(const address_sorting_address* resolved_addr) {
return 1;
}
struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr;
- if (IN6_IS_ADDR_LOOPBACK(&ipv6_addr->sin6_addr)) {
+ if (in6_is_addr_loopback(&ipv6_addr->sin6_addr)) {
return 0;
- } else if (IN6_IS_ADDR_V4MAPPED(&ipv6_addr->sin6_addr)) {
+ } else if (in6_is_addr_v4mapped(&ipv6_addr->sin6_addr)) {
return 4;
} else if (in6_is_addr_6to4(&ipv6_addr->sin6_addr)) {
return 2;
@@ -131,9 +158,9 @@ static int get_label_value(const address_sorting_address* resolved_addr) {
return 5;
} else if (in6_is_addr_ula(&ipv6_addr->sin6_addr)) {
return 13;
- } else if (IN6_IS_ADDR_V4COMPAT(&ipv6_addr->sin6_addr)) {
+ } else if (in6_is_addr_v4compat(&ipv6_addr->sin6_addr)) {
return 3;
- } else if (IN6_IS_ADDR_SITELOCAL(&ipv6_addr->sin6_addr)) {
+ } else if (in6_is_addr_sitelocal(&ipv6_addr->sin6_addr)) {
return 11;
} else if (in6_is_addr_6bone(&ipv6_addr->sin6_addr)) {
return 12;
@@ -150,9 +177,9 @@ static int get_precedence_value(const address_sorting_address* resolved_addr) {
return 1;
}
struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr;
- if (IN6_IS_ADDR_LOOPBACK(&ipv6_addr->sin6_addr)) {
+ if (in6_is_addr_loopback(&ipv6_addr->sin6_addr)) {
return 50;
- } else if (IN6_IS_ADDR_V4MAPPED(&ipv6_addr->sin6_addr)) {
+ } else if (in6_is_addr_v4mapped(&ipv6_addr->sin6_addr)) {
return 35;
} else if (in6_is_addr_6to4(&ipv6_addr->sin6_addr)) {
return 30;
@@ -160,8 +187,8 @@ static int get_precedence_value(const address_sorting_address* resolved_addr) {
return 5;
} else if (in6_is_addr_ula(&ipv6_addr->sin6_addr)) {
return 3;
- } else if (IN6_IS_ADDR_V4COMPAT(&ipv6_addr->sin6_addr) ||
- IN6_IS_ADDR_SITELOCAL(&ipv6_addr->sin6_addr) ||
+ } else if (in6_is_addr_v4compat(&ipv6_addr->sin6_addr) ||
+ in6_is_addr_sitelocal(&ipv6_addr->sin6_addr) ||
in6_is_addr_6bone(&ipv6_addr->sin6_addr)) {
return 1;
}
@@ -175,11 +202,11 @@ static int sockaddr_get_scope(const address_sorting_address* resolved_addr) {
} else if (address_sorting_abstract_get_family(resolved_addr) ==
ADDRESS_SORTING_AF_INET6) {
struct sockaddr_in6* ipv6_addr = (struct sockaddr_in6*)&resolved_addr->addr;
- if (IN6_IS_ADDR_LOOPBACK(&ipv6_addr->sin6_addr) ||
- IN6_IS_ADDR_LINKLOCAL(&ipv6_addr->sin6_addr)) {
+ if (in6_is_addr_loopback(&ipv6_addr->sin6_addr) ||
+ in6_is_addr_linklocal(&ipv6_addr->sin6_addr)) {
return kIPv6AddrScopeLinkLocal;
}
- if (IN6_IS_ADDR_SITELOCAL(&ipv6_addr->sin6_addr)) {
+ if (in6_is_addr_sitelocal(&ipv6_addr->sin6_addr)) {
return kIPv6AddrScopeSiteLocal;
}
return kIPv6AddrScopeGlobal;
diff --git a/third_party/address_sorting/address_sorting_internal.h b/third_party/address_sorting/address_sorting_internal.h
index 9712c96599..ee366fef1c 100644
--- a/third_party/address_sorting/address_sorting_internal.h
+++ b/third_party/address_sorting/address_sorting_internal.h
@@ -51,7 +51,10 @@
/* Workaround for issue described in
*
* https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1187301 */
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
+#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define ADDRESS_SORTING_POSIX 1