From 690dde672a877083e29ee5af0b8252697aa48fa0 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Wed, 18 Oct 2017 00:20:33 -0700 Subject: Add address sorting submodule for use in c-ares wrapper --- bazel/grpc_build_system.bzl | 2 ++ 1 file changed, 2 insertions(+) (limited to 'bazel') diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 571b29cc09..2b4ec68aa3 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -41,6 +41,8 @@ def _get_external_deps(external_deps): 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 -- cgit v1.2.3 From d21ee150765c73876992bbf06c716b4600ba047f Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 28 Dec 2017 18:09:19 -0800 Subject: 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 --- bazel/grpc_build_system.bzl | 4 +- test/cpp/naming/address_sorting_test.cc | 112 ++++++++++++++++++++- third_party/address_sorting/BUILD | 5 +- third_party/address_sorting/address_sorting.bzl | 38 +++++++ third_party/address_sorting/address_sorting.c | 49 +++++++-- .../address_sorting/address_sorting_internal.h | 3 + 6 files changed, 196 insertions(+), 15 deletions(-) create mode 100644 third_party/address_sorting/address_sorting.bzl (limited to 'bazel') 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" @@ -325,6 +325,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; @@ -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 #include #include #define ADDRESS_SORTING_POSIX 1 -- cgit v1.2.3