| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 | /* * * Copyright 2017 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */#include <grpc/grpc.h>#include <grpc/support/alloc.h>#include <grpc/support/log.h>#include <grpc/support/string_util.h>#include <grpc/support/sync.h>#include <grpc/support/time.h>#include <string.h>#include <gflags/gflags.h>#include <gmock/gmock.h>#include <sys/types.h>#include <vector>#include <address_sorting/address_sorting.h>#include "test/cpp/util/subprocess.h"#include "test/cpp/util/test_config.h"#include "src/core/ext/filters/client_channel/client_channel.h"#include "src/core/ext/filters/client_channel/resolver.h"#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"#include "src/core/ext/filters/client_channel/resolver_registry.h"#include "src/core/ext/filters/client_channel/server_address.h"#include "src/core/lib/channel/channel_args.h"#include "src/core/lib/gpr/env.h"#include "src/core/lib/gpr/host_port.h"#include "src/core/lib/gpr/string.h"#include "src/core/lib/iomgr/combiner.h"#include "src/core/lib/iomgr/executor.h"#include "src/core/lib/iomgr/iomgr.h"#include "src/core/lib/iomgr/resolve_address.h"#include "src/core/lib/iomgr/sockaddr_utils.h"#include "test/core/util/port.h"#include "test/core/util/test_config.h"#ifndef GPR_WINDOWS#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>#endifnamespace {struct TestAddress {  std::string dest_addr;  int family;};grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) {  char* host;  char* port;  grpc_resolved_address resolved_addr;  gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port);  if (test_addr.family == AF_INET) {    sockaddr_in in_dest;    memset(&in_dest, 0, sizeof(sockaddr_in));    in_dest.sin_port = htons(atoi(port));    in_dest.sin_family = AF_INET;    GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1);    memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in));    resolved_addr.len = sizeof(sockaddr_in);  } else {    GPR_ASSERT(test_addr.family == AF_INET6);    sockaddr_in6 in6_dest;    memset(&in6_dest, 0, sizeof(sockaddr_in6));    in6_dest.sin6_port = htons(atoi(port));    in6_dest.sin6_family = AF_INET6;    GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1);    memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6));    resolved_addr.len = sizeof(sockaddr_in6);  }  gpr_free(host);  gpr_free(port);  return resolved_addr;}class MockSourceAddrFactory : public address_sorting_source_addr_factory { public:  MockSourceAddrFactory(      bool ipv4_supported, bool ipv6_supported,      const std::map<std::string, TestAddress>& dest_addr_to_src_addr)      : ipv4_supported_(ipv4_supported),        ipv6_supported_(ipv6_supported),        dest_addr_to_src_addr_(dest_addr_to_src_addr) {}  bool GetSourceAddr(const address_sorting_address* dest_addr,                     address_sorting_address* source_addr) {    if ((address_sorting_abstract_get_family(dest_addr) ==             ADDRESS_SORTING_AF_INET &&         !ipv4_supported_) ||        (address_sorting_abstract_get_family(dest_addr) ==             ADDRESS_SORTING_AF_INET6 &&         !ipv6_supported_)) {      return false;    }    char* ip_addr_str;    grpc_resolved_address dest_addr_as_resolved_addr;    memcpy(&dest_addr_as_resolved_addr.addr, dest_addr, dest_addr->len);    dest_addr_as_resolved_addr.len = dest_addr->len;    grpc_sockaddr_to_string(&ip_addr_str, &dest_addr_as_resolved_addr,                            false /* normalize */);    auto it = dest_addr_to_src_addr_.find(ip_addr_str);    if (it == dest_addr_to_src_addr_.end()) {      gpr_log(GPR_DEBUG, "can't find |%s| in dest to src map", ip_addr_str);      gpr_free(ip_addr_str);      return false;    }    gpr_free(ip_addr_str);    grpc_resolved_address source_addr_as_resolved_addr =        TestAddressToGrpcResolvedAddress(it->second);    memcpy(source_addr->addr, &source_addr_as_resolved_addr.addr,           source_addr_as_resolved_addr.len);    source_addr->len = source_addr_as_resolved_addr.len;    return true;  } private:  // user provided test config  bool ipv4_supported_;  bool ipv6_supported_;  std::map<std::string, TestAddress> dest_addr_to_src_addr_;};static bool mock_source_addr_factory_wrapper_get_source_addr(    address_sorting_source_addr_factory* factory,    const address_sorting_address* dest_addr,    address_sorting_address* source_addr) {  MockSourceAddrFactory* mock =      reinterpret_cast<MockSourceAddrFactory*>(factory);  return mock->GetSourceAddr(dest_addr, source_addr);}void mock_source_addr_factory_wrapper_destroy(    address_sorting_source_addr_factory* factory) {  MockSourceAddrFactory* mock =      reinterpret_cast<MockSourceAddrFactory*>(factory);  delete mock;}const address_sorting_source_addr_factory_vtable kMockSourceAddrFactoryVtable =    {        mock_source_addr_factory_wrapper_get_source_addr,        mock_source_addr_factory_wrapper_destroy,};void OverrideAddressSortingSourceAddrFactory(    bool ipv4_supported, bool ipv6_supported,    const std::map<std::string, TestAddress>& dest_addr_to_src_addr) {  address_sorting_source_addr_factory* factory = new MockSourceAddrFactory(      ipv4_supported, ipv6_supported, dest_addr_to_src_addr);  factory->vtable = &kMockSourceAddrFactoryVtable;  address_sorting_override_source_addr_factory_for_testing(factory);}grpc_core::ServerAddressList BuildLbAddrInputs(    const std::vector<TestAddress>& test_addrs) {  grpc_core::ServerAddressList addresses;  for (const auto& addr : test_addrs) {    addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr);  }  return addresses;}void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses,                         std::vector<std::string> expected_addrs) {  EXPECT_EQ(addresses.size(), expected_addrs.size());  for (size_t i = 0; i < addresses.size(); ++i) {    char* ip_addr_str;    grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(),                            false /* normalize */);    EXPECT_EQ(expected_addrs[i], ip_addr_str);    gpr_free(ip_addr_str);  }  grpc_core::ExecCtx exec_ctx;}/* We need to run each test case inside of its own * isolated grpc_init/grpc_shutdown pair, so that * the "address sorting source addr factory" can be * restored to its default for each test case. */class AddressSortingTest : public ::testing::Test { protected:  void SetUp() override { grpc_init(); }  void TearDown() override { grpc_shutdown_blocking(); }};/* Tests for rule 1 */TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}},      });  auto lb_addrs = BuildLbAddrInputs({      {"1.2.3.4:443", AF_INET},      {"5.6.7.8:443", AF_INET},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "1.2.3.4:443",                                    "5.6.7.8:443",                                });}TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {  bool ipv4_supported = true;  bool ipv6_supported = false;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[2607:f8b0:400a:801::1002]:443", AF_INET6},      {"1.2.3.4:443", AF_INET},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "1.2.3.4:443",                                    "[2607:f8b0:400a:801::1002]:443",                                });}TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {  bool ipv4_supported = false;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},          {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[2607:f8b0:400a:801::1002]:443", AF_INET6},      {"1.2.3.4:443", AF_INET},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[2607:f8b0:400a:801::1002]:443",                                    "1.2.3.4:443",                                });}/* Tests for rule 2 */TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[2000:f8b0:400a:801::1002]:443",           {"[fec0::1000]:0", AF_INET6}},  // global and site-local scope          {"[fec0::5000]:443",           {"[fec0::5001]:0", AF_INET6}},  // site-local and site-local scope      });  auto lb_addrs = BuildLbAddrInputs({      {"[2000:f8b0:400a:801::1002]:443", AF_INET6},      {"[fec0::5000]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[fec0::5000]:443",                                    "[2000:f8b0:400a:801::1002]:443",                                });}/* Tests for rule 5 */TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},          {"[2001::5001]:443",           {"[2001::5002]:0", AF_INET6}},  // matching labels      });  auto lb_addrs = BuildLbAddrInputs({      {"[2002::5001]:443", AF_INET6},      {"[2001::5001]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[2001::5001]:443",                                    "[2002::5001]:443",                                });}/* Flip the input on the test above to reorder the sort function's * comparator's inputs. */TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},          {"[2001::5001]:443",           {"[2001::5002]:0", AF_INET6}},  // matching labels      });  auto lb_addrs = BuildLbAddrInputs({      {"[2001::5001]:443", AF_INET6},      {"[2002::5001]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[2001::5001]:443",                                    "[2002::5001]:443",                                });}/* Tests for rule 6 */TEST_F(AddressSortingTest,       TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},          {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe::5001]:443", AF_INET6},      {"1.2.3.4:443", AF_INET},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(      lb_addrs, {                    // The AF_INET address should be IPv4-mapped by the sort,                    // and IPv4-mapped                    // addresses have higher precedence than 3ffe::/16 by spec.                    "1.2.3.4:443",                    "[3ffe::5001]:443",                });}TEST_F(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}},      });  auto 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_F(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}},      });  auto 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_F(AddressSortingTest,       TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}},          {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[2001::1234]:443", AF_INET6},      {"[2000::5001]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(      lb_addrs, {                    // The 2000::/16 address should match the ::/0 prefix rule                    "[2000::5001]:443",                    "[2001::1234]:443",                });}TEST_F(    AddressSortingTest,    TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}},          {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[2001::1231]:443", AF_INET6},      {"[2000::5001]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[2000::5001]:443",                                    "[2001::1231]:443",                                });}TEST_F(AddressSortingTest,       TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},          {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[fec0::1234]:443", AF_INET6},      {"[fc00::5001]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[fc00::5001]:443",                                    "[fec0::1234]:443",                                });}TEST_F(    AddressSortingTest,    TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) {  bool ipv4_supported = true;  bool ipv6_supported = true;  // Use embedded ipv4 addresses with leading 1's instead of zero's to be  // compatible with inet_ntop implementations that can display such  // addresses with leading zero's as e.g.: "::ffff:0:2", as on windows.  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},          {"[1234::2]:443", {"[1234::3]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[::ffff:1.1.1.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:1.1.1.2]:443",                                });}/* Tests for rule 8 */TEST_F(AddressSortingTest, TestPrefersSmallerScope) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          // Both of these destinations have the same precedence in default          // policy          // table.          {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},          {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe::5001]:443", AF_INET6},      {"[fec0::1234]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[fec0::1234]:443",                                    "[3ffe::5001]:443",                                });}/* Tests for rule 9 */TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          // Both of these destinations have the same precedence in default          // policy          // table.          {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}},          {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe:5001::]:443", AF_INET6},      {"[3ffe:1234::]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[3ffe:1234::]:443",                                    "[3ffe:5001::]:443",                                });}TEST_F(AddressSortingTest,       TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}},          {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe::5001]:443", AF_INET6},      {"[3ffe::1234]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[3ffe::1234]:443",                                    "[3ffe::5001]:443",                                });}TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}},          {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe:8000::]:443", AF_INET6},      {"[3ffe:2000::]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[3ffe:2000::]:443",                                    "[3ffe:8000::]:443",                                });}TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}},          {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe:6::]:443", AF_INET6},      {"[3ffe:c::]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[3ffe:c::]:443",                                    "[3ffe:6::]:443",                                });}TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[3ffe:1111:1111:1111::]:443",           {"[3ffe:1111:1111:1111::]:0", AF_INET6}},          {"[3ffe:1111:1111:1110::]:443",           {"[3ffe:1111:1111:1111::]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe:1111:1111:1110::]:443", AF_INET6},      {"[3ffe:1111:1111:1111::]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[3ffe:1111:1111:1111::]:443",                                    "[3ffe:1111:1111:1110::]:443",                                });}/* Tests for rule 10 */TEST_F(AddressSortingTest, TestStableSort) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}},          {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe::1234]:443", AF_INET6},      {"[3ffe::1235]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[3ffe::1234]:443",                                    "[3ffe::1235]:443",                                });}TEST_F(AddressSortingTest, TestStableSortFiveElements) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(      ipv4_supported, ipv6_supported,      {          {"[3ffe::1231]:443", {"[3ffe::1201]:0", AF_INET6}},          {"[3ffe::1232]:443", {"[3ffe::1202]:0", AF_INET6}},          {"[3ffe::1233]:443", {"[3ffe::1203]:0", AF_INET6}},          {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}},          {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}},      });  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe::1231]:443", AF_INET6},      {"[3ffe::1232]:443", AF_INET6},      {"[3ffe::1233]:443", AF_INET6},      {"[3ffe::1234]:443", AF_INET6},      {"[3ffe::1235]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[3ffe::1231]:443",                                    "[3ffe::1232]:443",                                    "[3ffe::1233]:443",                                    "[3ffe::1234]:443",                                    "[3ffe::1235]:443",                                });}TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});  auto lb_addrs = BuildLbAddrInputs({      {"[3ffe::1231]:443", AF_INET6},      {"[3ffe::1232]:443", AF_INET6},      {"[3ffe::1233]:443", AF_INET6},      {"[3ffe::1234]:443", AF_INET6},      {"[3ffe::1235]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[3ffe::1231]:443",                                    "[3ffe::1232]:443",                                    "[3ffe::1233]:443",                                    "[3ffe::1234]:443",                                    "[3ffe::1235]:443",                                });}TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {  bool ipv4_supported = true;  bool ipv6_supported = true;  OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});  auto lb_addrs = BuildLbAddrInputs({      {"[::ffff:5.6.7.8]:443", AF_INET6},      {"1.2.3.4:443", AF_INET},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[::ffff:5.6.7.8]:443",                                    "1.2.3.4:443",                                });}TEST_F(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}},      });  auto 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,                      });}/* TestPrefersIpv6Loopback tests the actual "address probing" code * for the current platform, without any mocks. * This test relies on the assumption that the ipv6 loopback address is * available in the hosts/containers that grpc C/C++ tests run on * (whether ipv4 loopback is available or not, an available ipv6 * loopback should be preferred). */TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {  auto lb_addrs = BuildLbAddrInputs({      {"[::1]:443", AF_INET6},      {"127.0.0.1:443", AF_INET},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[::1]:443",                                    "127.0.0.1:443",                                });}/* Flip the order of the inputs above and expect the same output order * (try to rule out influence of arbitrary qsort ordering) */TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {  auto lb_addrs = BuildLbAddrInputs({      {"127.0.0.1:443", AF_INET},      {"[::1]:443", AF_INET6},  });  grpc_cares_wrapper_address_sorting_sort(&lb_addrs);  VerifyLbAddrOutputs(lb_addrs, {                                    "[::1]:443",                                    "127.0.0.1:443",                                });}/* Try to rule out false positives in the above two tests in which * the sorter might think that neither ipv6 or ipv4 loopback is * available, but ipv6 loopback is still preferred only due * to precedence table lookups. */TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {  sockaddr_in6 ipv6_loopback;  memset(&ipv6_loopback, 0, sizeof(ipv6_loopback));  ipv6_loopback.sin6_family = AF_INET6;  ((char*)&ipv6_loopback.sin6_addr)[15] = 1;  ipv6_loopback.sin6_port = htons(443);  // Set up the source and destination parameters of  // address_sorting_get_source_addr  address_sorting_address sort_input_dest;  memcpy(&sort_input_dest.addr, &ipv6_loopback, sizeof(ipv6_loopback));  sort_input_dest.len = sizeof(ipv6_loopback);  address_sorting_address source_for_sort_input_dest;  memset(&source_for_sort_input_dest, 0, sizeof(source_for_sort_input_dest));  // address_sorting_get_source_addr returns true if a source address was found  // for the destination address, otherwise false.  EXPECT_TRUE(address_sorting_get_source_addr_for_testing(      &sort_input_dest, &source_for_sort_input_dest));  // Now also check that the source address was filled in correctly.  EXPECT_GT(source_for_sort_input_dest.len, 0u);  sockaddr_in6* source_addr_output =      (sockaddr_in6*)source_for_sort_input_dest.addr;  EXPECT_EQ(source_addr_output->sin6_family, AF_INET6);  char* buf = static_cast<char*>(gpr_zalloc(100));  EXPECT_NE(inet_ntop(AF_INET6, &source_addr_output->sin6_addr, buf, 100),            nullptr)      << "inet_ntop failed. Errno: " + std::to_string(errno);  std::string source_addr_str(buf);  gpr_free(buf);  // This test  // assumes that the source address for any loopback destination is also the  // loopback address.  EXPECT_EQ(source_addr_str, "::1");}}  // namespaceint main(int argc, char** argv) {  char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");  if (resolver == nullptr || strlen(resolver) == 0) {    gpr_setenv("GRPC_DNS_RESOLVER", "ares");  } else if (strcmp("ares", resolver)) {    gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver);  }  gpr_free(resolver);  grpc::testing::TestEnvironment env(argc, argv);  ::testing::InitGoogleTest(&argc, argv);  auto result = RUN_ALL_TESTS();  // Test sequential and nested inits and shutdowns.  grpc_init();  grpc_init();  grpc_shutdown();  grpc_shutdown();  grpc_init();  grpc_shutdown();  return result;}
 |