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