Home | History | Annotate | Download | only in naming
      1 /*
      2  *
      3  * Copyright 2017 gRPC authors.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  */
     18 
     19 #include <grpc/grpc.h>
     20 #include <grpc/support/alloc.h>
     21 #include <grpc/support/log.h>
     22 #include <grpc/support/string_util.h>
     23 #include <grpc/support/sync.h>
     24 #include <grpc/support/time.h>
     25 #include <string.h>
     26 
     27 #include <gflags/gflags.h>
     28 #include <gmock/gmock.h>
     29 #include <sys/types.h>
     30 #include <vector>
     31 
     32 #include <address_sorting/address_sorting.h>
     33 #include "test/cpp/util/subprocess.h"
     34 #include "test/cpp/util/test_config.h"
     35 
     36 #include "src/core/ext/filters/client_channel/client_channel.h"
     37 #include "src/core/ext/filters/client_channel/resolver.h"
     38 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
     39 #include "src/core/ext/filters/client_channel/resolver_registry.h"
     40 #include "src/core/lib/channel/channel_args.h"
     41 #include "src/core/lib/gpr/env.h"
     42 #include "src/core/lib/gpr/host_port.h"
     43 #include "src/core/lib/gpr/string.h"
     44 #include "src/core/lib/iomgr/combiner.h"
     45 #include "src/core/lib/iomgr/executor.h"
     46 #include "src/core/lib/iomgr/iomgr.h"
     47 #include "src/core/lib/iomgr/resolve_address.h"
     48 #include "src/core/lib/iomgr/sockaddr_utils.h"
     49 #include "test/core/util/port.h"
     50 #include "test/core/util/test_config.h"
     51 
     52 #ifndef GPR_WINDOWS
     53 #include <arpa/inet.h>
     54 #include <sys/socket.h>
     55 #endif
     56 
     57 namespace {
     58 
     59 struct TestAddress {
     60   std::string dest_addr;
     61   int family;
     62 };
     63 
     64 grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) {
     65   char* host;
     66   char* port;
     67   grpc_resolved_address resolved_addr;
     68   gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port);
     69   if (test_addr.family == AF_INET) {
     70     sockaddr_in in_dest;
     71     memset(&in_dest, 0, sizeof(sockaddr_in));
     72     in_dest.sin_port = htons(atoi(port));
     73     in_dest.sin_family = AF_INET;
     74     GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1);
     75     memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in));
     76     resolved_addr.len = sizeof(sockaddr_in);
     77   } else {
     78     GPR_ASSERT(test_addr.family == AF_INET6);
     79     sockaddr_in6 in6_dest;
     80     memset(&in6_dest, 0, sizeof(sockaddr_in6));
     81     in6_dest.sin6_port = htons(atoi(port));
     82     in6_dest.sin6_family = AF_INET6;
     83     GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1);
     84     memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6));
     85     resolved_addr.len = sizeof(sockaddr_in6);
     86   }
     87   gpr_free(host);
     88   gpr_free(port);
     89   return resolved_addr;
     90 }
     91 
     92 class MockSourceAddrFactory : public address_sorting_source_addr_factory {
     93  public:
     94   MockSourceAddrFactory(
     95       bool ipv4_supported, bool ipv6_supported,
     96       const std::map<std::string, TestAddress>& dest_addr_to_src_addr)
     97       : ipv4_supported_(ipv4_supported),
     98         ipv6_supported_(ipv6_supported),
     99         dest_addr_to_src_addr_(dest_addr_to_src_addr) {}
    100 
    101   bool GetSourceAddr(const address_sorting_address* dest_addr,
    102                      address_sorting_address* source_addr) {
    103     if ((address_sorting_abstract_get_family(dest_addr) ==
    104              ADDRESS_SORTING_AF_INET &&
    105          !ipv4_supported_) ||
    106         (address_sorting_abstract_get_family(dest_addr) ==
    107              ADDRESS_SORTING_AF_INET6 &&
    108          !ipv6_supported_)) {
    109       return false;
    110     }
    111     char* ip_addr_str;
    112     grpc_resolved_address dest_addr_as_resolved_addr;
    113     memcpy(&dest_addr_as_resolved_addr.addr, dest_addr, dest_addr->len);
    114     dest_addr_as_resolved_addr.len = dest_addr->len;
    115     grpc_sockaddr_to_string(&ip_addr_str, &dest_addr_as_resolved_addr,
    116                             false /* normalize */);
    117     auto it = dest_addr_to_src_addr_.find(ip_addr_str);
    118     if (it == dest_addr_to_src_addr_.end()) {
    119       gpr_log(GPR_DEBUG, "can't find |%s| in dest to src map", ip_addr_str);
    120       gpr_free(ip_addr_str);
    121       return false;
    122     }
    123     gpr_free(ip_addr_str);
    124     grpc_resolved_address source_addr_as_resolved_addr =
    125         TestAddressToGrpcResolvedAddress(it->second);
    126     memcpy(source_addr->addr, &source_addr_as_resolved_addr.addr,
    127            source_addr_as_resolved_addr.len);
    128     source_addr->len = source_addr_as_resolved_addr.len;
    129     return true;
    130   }
    131 
    132  private:
    133   // user provided test config
    134   bool ipv4_supported_;
    135   bool ipv6_supported_;
    136   std::map<std::string, TestAddress> dest_addr_to_src_addr_;
    137 };
    138 
    139 static bool mock_source_addr_factory_wrapper_get_source_addr(
    140     address_sorting_source_addr_factory* factory,
    141     const address_sorting_address* dest_addr,
    142     address_sorting_address* source_addr) {
    143   MockSourceAddrFactory* mock =
    144       reinterpret_cast<MockSourceAddrFactory*>(factory);
    145   return mock->GetSourceAddr(dest_addr, source_addr);
    146 }
    147 
    148 void mock_source_addr_factory_wrapper_destroy(
    149     address_sorting_source_addr_factory* factory) {
    150   MockSourceAddrFactory* mock =
    151       reinterpret_cast<MockSourceAddrFactory*>(factory);
    152   delete mock;
    153 }
    154 
    155 const address_sorting_source_addr_factory_vtable kMockSourceAddrFactoryVtable =
    156     {
    157         mock_source_addr_factory_wrapper_get_source_addr,
    158         mock_source_addr_factory_wrapper_destroy,
    159 };
    160 
    161 void OverrideAddressSortingSourceAddrFactory(
    162     bool ipv4_supported, bool ipv6_supported,
    163     const std::map<std::string, TestAddress>& dest_addr_to_src_addr) {
    164   address_sorting_source_addr_factory* factory = new MockSourceAddrFactory(
    165       ipv4_supported, ipv6_supported, dest_addr_to_src_addr);
    166   factory->vtable = &kMockSourceAddrFactoryVtable;
    167   address_sorting_override_source_addr_factory_for_testing(factory);
    168 }
    169 
    170 grpc_lb_addresses* BuildLbAddrInputs(std::vector<TestAddress> test_addrs) {
    171   grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr);
    172   lb_addrs->addresses =
    173       (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size());
    174   lb_addrs->num_addresses = test_addrs.size();
    175   for (size_t i = 0; i < test_addrs.size(); i++) {
    176     lb_addrs->addresses[i].address =
    177         TestAddressToGrpcResolvedAddress(test_addrs[i]);
    178   }
    179   return lb_addrs;
    180 }
    181 
    182 void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs,
    183                          std::vector<std::string> expected_addrs) {
    184   EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size());
    185   for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
    186     char* ip_addr_str;
    187     grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address,
    188                             false /* normalize */);
    189     EXPECT_EQ(expected_addrs[i], ip_addr_str);
    190     gpr_free(ip_addr_str);
    191   }
    192   grpc_core::ExecCtx exec_ctx;
    193   grpc_lb_addresses_destroy(lb_addrs);
    194 }
    195 
    196 /* We need to run each test case inside of its own
    197  * isolated grpc_init/grpc_shutdown pair, so that
    198  * the "address sorting source addr factory" can be
    199  * restored to its default for each test case. */
    200 class AddressSortingTest : public ::testing::Test {
    201  protected:
    202   void SetUp() override { grpc_init(); }
    203   void TearDown() override { grpc_shutdown(); }
    204 };
    205 
    206 /* Tests for rule 1 */
    207 TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
    208   bool ipv4_supported = true;
    209   bool ipv6_supported = true;
    210   OverrideAddressSortingSourceAddrFactory(
    211       ipv4_supported, ipv6_supported,
    212       {
    213           {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}},
    214       });
    215   auto* lb_addrs = BuildLbAddrInputs({
    216       {"1.2.3.4:443", AF_INET},
    217       {"5.6.7.8:443", AF_INET},
    218   });
    219   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    220   VerifyLbAddrOutputs(lb_addrs, {
    221                                     "1.2.3.4:443",
    222                                     "5.6.7.8:443",
    223                                 });
    224 }
    225 
    226 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
    227   bool ipv4_supported = true;
    228   bool ipv6_supported = false;
    229   OverrideAddressSortingSourceAddrFactory(
    230       ipv4_supported, ipv6_supported,
    231       {
    232           {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
    233       });
    234   auto lb_addrs = BuildLbAddrInputs({
    235       {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
    236       {"1.2.3.4:443", AF_INET},
    237   });
    238   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    239   VerifyLbAddrOutputs(lb_addrs, {
    240                                     "1.2.3.4:443",
    241                                     "[2607:f8b0:400a:801::1002]:443",
    242                                 });
    243 }
    244 
    245 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
    246   bool ipv4_supported = false;
    247   bool ipv6_supported = true;
    248   OverrideAddressSortingSourceAddrFactory(
    249       ipv4_supported, ipv6_supported,
    250       {
    251           {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
    252           {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}},
    253       });
    254   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    255       {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
    256       {"1.2.3.4:443", AF_INET},
    257   });
    258   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    259   VerifyLbAddrOutputs(lb_addrs, {
    260                                     "[2607:f8b0:400a:801::1002]:443",
    261                                     "1.2.3.4:443",
    262                                 });
    263 }
    264 
    265 /* Tests for rule 2 */
    266 
    267 TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
    268   bool ipv4_supported = true;
    269   bool ipv6_supported = true;
    270   OverrideAddressSortingSourceAddrFactory(
    271       ipv4_supported, ipv6_supported,
    272       {
    273           {"[2000:f8b0:400a:801::1002]:443",
    274            {"[fec0::1000]:0", AF_INET6}},  // global and site-local scope
    275           {"[fec0::5000]:443",
    276            {"[fec0::5001]:0", AF_INET6}},  // site-local and site-local scope
    277       });
    278   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    279       {"[2000:f8b0:400a:801::1002]:443", AF_INET6},
    280       {"[fec0::5000]:443", AF_INET6},
    281   });
    282   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    283   VerifyLbAddrOutputs(lb_addrs, {
    284                                     "[fec0::5000]:443",
    285                                     "[2000:f8b0:400a:801::1002]:443",
    286                                 });
    287 }
    288 
    289 /* Tests for rule 5 */
    290 
    291 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
    292   bool ipv4_supported = true;
    293   bool ipv6_supported = true;
    294   OverrideAddressSortingSourceAddrFactory(
    295       ipv4_supported, ipv6_supported,
    296       {
    297           {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
    298           {"[2001::5001]:443",
    299            {"[2001::5002]:0", AF_INET6}},  // matching labels
    300       });
    301   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    302       {"[2002::5001]:443", AF_INET6},
    303       {"[2001::5001]:443", AF_INET6},
    304   });
    305   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    306   VerifyLbAddrOutputs(lb_addrs, {
    307                                     "[2001::5001]:443",
    308                                     "[2002::5001]:443",
    309                                 });
    310 }
    311 
    312 /* Flip the input on the test above to reorder the sort function's
    313  * comparator's inputs. */
    314 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
    315   bool ipv4_supported = true;
    316   bool ipv6_supported = true;
    317   OverrideAddressSortingSourceAddrFactory(
    318       ipv4_supported, ipv6_supported,
    319       {
    320           {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
    321           {"[2001::5001]:443",
    322            {"[2001::5002]:0", AF_INET6}},  // matching labels
    323       });
    324   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    325       {"[2001::5001]:443", AF_INET6},
    326       {"[2002::5001]:443", AF_INET6},
    327   });
    328   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    329   VerifyLbAddrOutputs(lb_addrs, {
    330                                     "[2001::5001]:443",
    331                                     "[2002::5001]:443",
    332                                 });
    333 }
    334 
    335 /* Tests for rule 6 */
    336 
    337 TEST_F(AddressSortingTest,
    338        TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {
    339   bool ipv4_supported = true;
    340   bool ipv6_supported = true;
    341   OverrideAddressSortingSourceAddrFactory(
    342       ipv4_supported, ipv6_supported,
    343       {
    344           {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
    345           {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}},
    346       });
    347   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    348       {"[3ffe::5001]:443", AF_INET6},
    349       {"1.2.3.4:443", AF_INET},
    350   });
    351   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    352   VerifyLbAddrOutputs(
    353       lb_addrs, {
    354                     // The AF_INET address should be IPv4-mapped by the sort,
    355                     // and IPv4-mapped
    356                     // addresses have higher precedence than 3ffe::/16 by spec.
    357                     "1.2.3.4:443",
    358                     "[3ffe::5001]:443",
    359                 });
    360 }
    361 
    362 TEST_F(AddressSortingTest,
    363        TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) {
    364   bool ipv4_supported = true;
    365   bool ipv6_supported = true;
    366 // Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
    367 #if GPR_APPLE == 1
    368   const char* v4_compat_dest = "[::0.0.0.2]:443";
    369   const char* v4_compat_src = "[::0.0.0.2]:0";
    370 #else
    371   const char* v4_compat_dest = "[::2]:443";
    372   const char* v4_compat_src = "[::2]:0";
    373 #endif
    374   OverrideAddressSortingSourceAddrFactory(
    375       ipv4_supported, ipv6_supported,
    376       {
    377           {"[::1]:443", {"[::1]:0", AF_INET6}},
    378           {v4_compat_dest, {v4_compat_src, AF_INET6}},
    379       });
    380   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    381       {v4_compat_dest, AF_INET6},
    382       {"[::1]:443", AF_INET6},
    383   });
    384   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    385   VerifyLbAddrOutputs(lb_addrs, {
    386                                     "[::1]:443",
    387                                     v4_compat_dest,
    388                                 });
    389 }
    390 
    391 TEST_F(AddressSortingTest,
    392        TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
    393   bool ipv4_supported = true;
    394   bool ipv6_supported = true;
    395   OverrideAddressSortingSourceAddrFactory(
    396       ipv4_supported, ipv6_supported,
    397       {
    398           // 1234::2 for src and dest to make sure that prefix matching has no
    399           // influence on this test.
    400           {"[1234::2]:443", {"[1234::2]:0", AF_INET6}},
    401           {"[::1]:443", {"[::1]:0", AF_INET6}},
    402       });
    403   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    404       {"[1234::2]:443", AF_INET6},
    405       {"[::1]:443", AF_INET6},
    406   });
    407   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    408   VerifyLbAddrOutputs(
    409       lb_addrs,
    410       {
    411           // ::1 should match the localhost precedence entry and be prioritized
    412           "[::1]:443",
    413           "[1234::2]:443",
    414       });
    415 }
    416 
    417 TEST_F(AddressSortingTest,
    418        TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
    419   bool ipv4_supported = true;
    420   bool ipv6_supported = true;
    421   OverrideAddressSortingSourceAddrFactory(
    422       ipv4_supported, ipv6_supported,
    423       {
    424           {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}},
    425           {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
    426       });
    427   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    428       {"[2001::1234]:443", AF_INET6},
    429       {"[2000::5001]:443", AF_INET6},
    430   });
    431   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    432   VerifyLbAddrOutputs(
    433       lb_addrs, {
    434                     // The 2000::/16 address should match the ::/0 prefix rule
    435                     "[2000::5001]:443",
    436                     "[2001::1234]:443",
    437                 });
    438 }
    439 
    440 TEST_F(
    441     AddressSortingTest,
    442     TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) {
    443   bool ipv4_supported = true;
    444   bool ipv6_supported = true;
    445   OverrideAddressSortingSourceAddrFactory(
    446       ipv4_supported, ipv6_supported,
    447       {
    448           {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}},
    449           {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
    450       });
    451   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    452       {"[2001::1231]:443", AF_INET6},
    453       {"[2000::5001]:443", AF_INET6},
    454   });
    455   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    456   VerifyLbAddrOutputs(lb_addrs, {
    457                                     "[2000::5001]:443",
    458                                     "[2001::1231]:443",
    459                                 });
    460 }
    461 
    462 TEST_F(AddressSortingTest,
    463        TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {
    464   bool ipv4_supported = true;
    465   bool ipv6_supported = true;
    466   OverrideAddressSortingSourceAddrFactory(
    467       ipv4_supported, ipv6_supported,
    468       {
    469           {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
    470           {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}},
    471       });
    472   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    473       {"[fec0::1234]:443", AF_INET6},
    474       {"[fc00::5001]:443", AF_INET6},
    475   });
    476   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    477   VerifyLbAddrOutputs(lb_addrs, {
    478                                     "[fc00::5001]:443",
    479                                     "[fec0::1234]:443",
    480                                 });
    481 }
    482 
    483 TEST_F(
    484     AddressSortingTest,
    485     TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) {
    486   bool ipv4_supported = true;
    487   bool ipv6_supported = true;
    488   // Use embedded ipv4 addresses with leading 1's instead of zero's to be
    489   // compatible with inet_ntop implementations that can display such
    490   // addresses with leading zero's as e.g.: "::ffff:0:2", as on windows.
    491   OverrideAddressSortingSourceAddrFactory(
    492       ipv4_supported, ipv6_supported,
    493       {
    494           {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},
    495           {"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
    496       });
    497   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    498       {"[::ffff:1.1.1.2]:443", AF_INET6},
    499       {"[1234::2]:443", AF_INET6},
    500   });
    501   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    502   VerifyLbAddrOutputs(lb_addrs, {
    503                                     // ::ffff:0:2 should match the v4-mapped
    504                                     // precedence entry and be deprioritized.
    505                                     "[1234::2]:443",
    506                                     "[::ffff:1.1.1.2]:443",
    507                                 });
    508 }
    509 
    510 /* Tests for rule 8 */
    511 
    512 TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
    513   bool ipv4_supported = true;
    514   bool ipv6_supported = true;
    515   OverrideAddressSortingSourceAddrFactory(
    516       ipv4_supported, ipv6_supported,
    517       {
    518           // Both of these destinations have the same precedence in default
    519           // policy
    520           // table.
    521           {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
    522           {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
    523       });
    524   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    525       {"[3ffe::5001]:443", AF_INET6},
    526       {"[fec0::1234]:443", AF_INET6},
    527   });
    528   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    529   VerifyLbAddrOutputs(lb_addrs, {
    530                                     "[fec0::1234]:443",
    531                                     "[3ffe::5001]:443",
    532                                 });
    533 }
    534 
    535 /* Tests for rule 9 */
    536 
    537 TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
    538   bool ipv4_supported = true;
    539   bool ipv6_supported = true;
    540   OverrideAddressSortingSourceAddrFactory(
    541       ipv4_supported, ipv6_supported,
    542       {
    543           // Both of these destinations have the same precedence in default
    544           // policy
    545           // table.
    546           {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}},
    547           {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}},
    548       });
    549   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    550       {"[3ffe:5001::]:443", AF_INET6},
    551       {"[3ffe:1234::]:443", AF_INET6},
    552   });
    553   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    554   VerifyLbAddrOutputs(lb_addrs, {
    555                                     "[3ffe:1234::]:443",
    556                                     "[3ffe:5001::]:443",
    557                                 });
    558 }
    559 
    560 TEST_F(AddressSortingTest,
    561        TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {
    562   bool ipv4_supported = true;
    563   bool ipv6_supported = true;
    564   OverrideAddressSortingSourceAddrFactory(
    565       ipv4_supported, ipv6_supported,
    566       {
    567           {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}},
    568           {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}},
    569       });
    570   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    571       {"[3ffe::5001]:443", AF_INET6},
    572       {"[3ffe::1234]:443", AF_INET6},
    573   });
    574   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    575   VerifyLbAddrOutputs(lb_addrs, {
    576                                     "[3ffe::1234]:443",
    577                                     "[3ffe::5001]:443",
    578                                 });
    579 }
    580 
    581 TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
    582   bool ipv4_supported = true;
    583   bool ipv6_supported = true;
    584   OverrideAddressSortingSourceAddrFactory(
    585       ipv4_supported, ipv6_supported,
    586       {
    587           {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}},
    588           {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}},
    589       });
    590   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    591       {"[3ffe:8000::]:443", AF_INET6},
    592       {"[3ffe:2000::]:443", AF_INET6},
    593   });
    594   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    595   VerifyLbAddrOutputs(lb_addrs, {
    596                                     "[3ffe:2000::]:443",
    597                                     "[3ffe:8000::]:443",
    598                                 });
    599 }
    600 
    601 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
    602   bool ipv4_supported = true;
    603   bool ipv6_supported = true;
    604   OverrideAddressSortingSourceAddrFactory(
    605       ipv4_supported, ipv6_supported,
    606       {
    607           {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}},
    608           {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}},
    609       });
    610   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    611       {"[3ffe:6::]:443", AF_INET6},
    612       {"[3ffe:c::]:443", AF_INET6},
    613   });
    614   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    615   VerifyLbAddrOutputs(lb_addrs, {
    616                                     "[3ffe:c::]:443",
    617                                     "[3ffe:6::]:443",
    618                                 });
    619 }
    620 
    621 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
    622   bool ipv4_supported = true;
    623   bool ipv6_supported = true;
    624   OverrideAddressSortingSourceAddrFactory(
    625       ipv4_supported, ipv6_supported,
    626       {
    627           {"[3ffe:1111:1111:1111::]:443",
    628            {"[3ffe:1111:1111:1111::]:0", AF_INET6}},
    629           {"[3ffe:1111:1111:1110::]:443",
    630            {"[3ffe:1111:1111:1111::]:0", AF_INET6}},
    631       });
    632   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    633       {"[3ffe:1111:1111:1110::]:443", AF_INET6},
    634       {"[3ffe:1111:1111:1111::]:443", AF_INET6},
    635   });
    636   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    637   VerifyLbAddrOutputs(lb_addrs, {
    638                                     "[3ffe:1111:1111:1111::]:443",
    639                                     "[3ffe:1111:1111:1110::]:443",
    640                                 });
    641 }
    642 
    643 /* Tests for rule 10 */
    644 
    645 TEST_F(AddressSortingTest, TestStableSort) {
    646   bool ipv4_supported = true;
    647   bool ipv6_supported = true;
    648   OverrideAddressSortingSourceAddrFactory(
    649       ipv4_supported, ipv6_supported,
    650       {
    651           {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}},
    652           {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}},
    653       });
    654   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    655       {"[3ffe::1234]:443", AF_INET6},
    656       {"[3ffe::1235]:443", AF_INET6},
    657   });
    658   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    659   VerifyLbAddrOutputs(lb_addrs, {
    660                                     "[3ffe::1234]:443",
    661                                     "[3ffe::1235]:443",
    662                                 });
    663 }
    664 
    665 TEST_F(AddressSortingTest, TestStableSortFiveElements) {
    666   bool ipv4_supported = true;
    667   bool ipv6_supported = true;
    668   OverrideAddressSortingSourceAddrFactory(
    669       ipv4_supported, ipv6_supported,
    670       {
    671           {"[3ffe::1231]:443", {"[3ffe::1201]:0", AF_INET6}},
    672           {"[3ffe::1232]:443", {"[3ffe::1202]:0", AF_INET6}},
    673           {"[3ffe::1233]:443", {"[3ffe::1203]:0", AF_INET6}},
    674           {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}},
    675           {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}},
    676       });
    677   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    678       {"[3ffe::1231]:443", AF_INET6},
    679       {"[3ffe::1232]:443", AF_INET6},
    680       {"[3ffe::1233]:443", AF_INET6},
    681       {"[3ffe::1234]:443", AF_INET6},
    682       {"[3ffe::1235]:443", AF_INET6},
    683   });
    684   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    685   VerifyLbAddrOutputs(lb_addrs, {
    686                                     "[3ffe::1231]:443",
    687                                     "[3ffe::1232]:443",
    688                                     "[3ffe::1233]:443",
    689                                     "[3ffe::1234]:443",
    690                                     "[3ffe::1235]:443",
    691                                 });
    692 }
    693 
    694 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
    695   bool ipv4_supported = true;
    696   bool ipv6_supported = true;
    697   OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
    698   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    699       {"[3ffe::1231]:443", AF_INET6},
    700       {"[3ffe::1232]:443", AF_INET6},
    701       {"[3ffe::1233]:443", AF_INET6},
    702       {"[3ffe::1234]:443", AF_INET6},
    703       {"[3ffe::1235]:443", AF_INET6},
    704   });
    705   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    706   VerifyLbAddrOutputs(lb_addrs, {
    707                                     "[3ffe::1231]:443",
    708                                     "[3ffe::1232]:443",
    709                                     "[3ffe::1233]:443",
    710                                     "[3ffe::1234]:443",
    711                                     "[3ffe::1235]:443",
    712                                 });
    713 }
    714 
    715 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
    716   bool ipv4_supported = true;
    717   bool ipv6_supported = true;
    718   OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
    719   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    720       {"[::ffff:5.6.7.8]:443", AF_INET6},
    721       {"1.2.3.4:443", AF_INET},
    722   });
    723   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    724   VerifyLbAddrOutputs(lb_addrs, {
    725                                     "[::ffff:5.6.7.8]:443",
    726                                     "1.2.3.4:443",
    727                                 });
    728 }
    729 
    730 TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
    731   bool ipv4_supported = true;
    732   bool ipv6_supported = true;
    733 // Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
    734 #if GPR_APPLE == 1
    735   const char* v4_compat_dest = "[::0.0.0.2]:443";
    736   const char* v4_compat_src = "[::0.0.0.3]:0";
    737 #else
    738   const char* v4_compat_dest = "[::2]:443";
    739   const char* v4_compat_src = "[::3]:0";
    740 #endif
    741   OverrideAddressSortingSourceAddrFactory(
    742       ipv4_supported, ipv6_supported,
    743       {
    744           {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}},
    745           {v4_compat_dest, {v4_compat_src, AF_INET6}},
    746       });
    747   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    748       {"[fec0::2000]:443", AF_INET6},
    749       {v4_compat_dest, AF_INET6},
    750   });
    751   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    752   VerifyLbAddrOutputs(lb_addrs,
    753                       {
    754                           // The sort should be stable since
    755                           // v4-compatible has same precedence as site-local.
    756                           "[fec0::2000]:443",
    757                           v4_compat_dest,
    758                       });
    759 }
    760 
    761 /* TestPrefersIpv6Loopback tests the actual "address probing" code
    762  * for the current platform, without any mocks.
    763  * This test relies on the assumption that the ipv6 loopback address is
    764  * available in the hosts/containers that grpc C/C++ tests run on
    765  * (whether ipv4 loopback is available or not, an available ipv6
    766  * loopback should be preferred). */
    767 TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
    768   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    769       {"[::1]:443", AF_INET6},
    770       {"127.0.0.1:443", AF_INET},
    771   });
    772   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    773   VerifyLbAddrOutputs(lb_addrs, {
    774                                     "[::1]:443",
    775                                     "127.0.0.1:443",
    776                                 });
    777 }
    778 
    779 /* Flip the order of the inputs above and expect the same output order
    780  * (try to rule out influence of arbitrary qsort ordering) */
    781 TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
    782   grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
    783       {"127.0.0.1:443", AF_INET},
    784       {"[::1]:443", AF_INET6},
    785   });
    786   grpc_cares_wrapper_address_sorting_sort(lb_addrs);
    787   VerifyLbAddrOutputs(lb_addrs, {
    788                                     "[::1]:443",
    789                                     "127.0.0.1:443",
    790                                 });
    791 }
    792 
    793 /* Try to rule out false positives in the above two tests in which
    794  * the sorter might think that neither ipv6 or ipv4 loopback is
    795  * available, but ipv6 loopback is still preferred only due
    796  * to precedance table lookups. */
    797 TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {
    798   sockaddr_in6 ipv6_loopback;
    799   memset(&ipv6_loopback, 0, sizeof(ipv6_loopback));
    800   ipv6_loopback.sin6_family = AF_INET6;
    801   ((char*)&ipv6_loopback.sin6_addr)[15] = 1;
    802   ipv6_loopback.sin6_port = htons(443);
    803   // Set up the source and destination parameters of
    804   // address_sorting_get_source_addr
    805   address_sorting_address sort_input_dest;
    806   memcpy(&sort_input_dest.addr, &ipv6_loopback, sizeof(ipv6_loopback));
    807   sort_input_dest.len = sizeof(ipv6_loopback);
    808   address_sorting_address source_for_sort_input_dest;
    809   memset(&source_for_sort_input_dest, 0, sizeof(source_for_sort_input_dest));
    810   // address_sorting_get_source_addr returns true if a source address was found
    811   // for the destination address, otherwise false.
    812   EXPECT_TRUE(address_sorting_get_source_addr_for_testing(
    813       &sort_input_dest, &source_for_sort_input_dest));
    814   // Now also check that the source address was filled in correctly.
    815   EXPECT_GT(source_for_sort_input_dest.len, 0u);
    816   sockaddr_in6* source_addr_output =
    817       (sockaddr_in6*)source_for_sort_input_dest.addr;
    818   EXPECT_EQ(source_addr_output->sin6_family, AF_INET6);
    819   char* buf = static_cast<char*>(gpr_zalloc(100));
    820   EXPECT_NE(inet_ntop(AF_INET6, &source_addr_output->sin6_addr, buf, 100),
    821             nullptr)
    822       << "inet_ntop failed. Errno: " + std::to_string(errno);
    823   std::string source_addr_str(buf);
    824   gpr_free(buf);
    825   // This test
    826   // assumes that the source address for any loopback destination is also the
    827   // loopback address.
    828   EXPECT_EQ(source_addr_str, "::1");
    829 }
    830 
    831 }  // namespace
    832 
    833 int main(int argc, char** argv) {
    834   char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
    835   if (resolver == nullptr || strlen(resolver) == 0) {
    836     gpr_setenv("GRPC_DNS_RESOLVER", "ares");
    837   } else if (strcmp("ares", resolver)) {
    838     gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver);
    839   }
    840   gpr_free(resolver);
    841   grpc_test_init(argc, argv);
    842   ::testing::InitGoogleTest(&argc, argv);
    843   auto result = RUN_ALL_TESTS();
    844   // Test sequential and nested inits and shutdowns.
    845   grpc_init();
    846   grpc_init();
    847   grpc_shutdown();
    848   grpc_shutdown();
    849   grpc_init();
    850   grpc_shutdown();
    851   return result;
    852 }
    853