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