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