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