3 * Copyright 2017 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
27 #include <gflags/gflags.h>
28 #include <gmock/gmock.h>
29 #include <sys/types.h>
32 #include <address_sorting/address_sorting.h>
33 #include "test/cpp/util/subprocess.h"
34 #include "test/cpp/util/test_config.h"
36 #include "src/core/ext/filters/client_channel/client_channel.h"
37 #include "src/core/ext/filters/client_channel/resolver.h"
38 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
39 #include "src/core/ext/filters/client_channel/resolver_registry.h"
40 #include "src/core/ext/filters/client_channel/server_address.h"
41 #include "src/core/lib/channel/channel_args.h"
42 #include "src/core/lib/gpr/env.h"
43 #include "src/core/lib/gpr/host_port.h"
44 #include "src/core/lib/gpr/string.h"
45 #include "src/core/lib/iomgr/combiner.h"
46 #include "src/core/lib/iomgr/executor.h"
47 #include "src/core/lib/iomgr/iomgr.h"
48 #include "src/core/lib/iomgr/resolve_address.h"
49 #include "src/core/lib/iomgr/sockaddr_utils.h"
50 #include "test/core/util/port.h"
51 #include "test/core/util/test_config.h"
54 #include <arpa/inet.h>
55 #include <sys/socket.h>
61 std::string dest_addr;
65 grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) {
68 grpc_resolved_address resolved_addr;
69 gpr_split_host_port(test_addr.dest_addr.c_str(), &host, &port);
70 if (test_addr.family == AF_INET) {
72 memset(&in_dest, 0, sizeof(sockaddr_in));
73 in_dest.sin_port = htons(atoi(port));
74 in_dest.sin_family = AF_INET;
75 GPR_ASSERT(inet_pton(AF_INET, host, &in_dest.sin_addr) == 1);
76 memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in));
77 resolved_addr.len = sizeof(sockaddr_in);
79 GPR_ASSERT(test_addr.family == AF_INET6);
80 sockaddr_in6 in6_dest;
81 memset(&in6_dest, 0, sizeof(sockaddr_in6));
82 in6_dest.sin6_port = htons(atoi(port));
83 in6_dest.sin6_family = AF_INET6;
84 GPR_ASSERT(inet_pton(AF_INET6, host, &in6_dest.sin6_addr) == 1);
85 memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6));
86 resolved_addr.len = sizeof(sockaddr_in6);
93 class MockSourceAddrFactory : public address_sorting_source_addr_factory {
95 MockSourceAddrFactory(
96 bool ipv4_supported, bool ipv6_supported,
97 const std::map<std::string, TestAddress>& dest_addr_to_src_addr)
98 : ipv4_supported_(ipv4_supported),
99 ipv6_supported_(ipv6_supported),
100 dest_addr_to_src_addr_(dest_addr_to_src_addr) {}
102 bool GetSourceAddr(const address_sorting_address* dest_addr,
103 address_sorting_address* source_addr) {
104 if ((address_sorting_abstract_get_family(dest_addr) ==
105 ADDRESS_SORTING_AF_INET &&
107 (address_sorting_abstract_get_family(dest_addr) ==
108 ADDRESS_SORTING_AF_INET6 &&
113 grpc_resolved_address dest_addr_as_resolved_addr;
114 memcpy(&dest_addr_as_resolved_addr.addr, dest_addr, dest_addr->len);
115 dest_addr_as_resolved_addr.len = dest_addr->len;
116 grpc_sockaddr_to_string(&ip_addr_str, &dest_addr_as_resolved_addr,
117 false /* normalize */);
118 auto it = dest_addr_to_src_addr_.find(ip_addr_str);
119 if (it == dest_addr_to_src_addr_.end()) {
120 gpr_log(GPR_DEBUG, "can't find |%s| in dest to src map", ip_addr_str);
121 gpr_free(ip_addr_str);
124 gpr_free(ip_addr_str);
125 grpc_resolved_address source_addr_as_resolved_addr =
126 TestAddressToGrpcResolvedAddress(it->second);
127 memcpy(source_addr->addr, &source_addr_as_resolved_addr.addr,
128 source_addr_as_resolved_addr.len);
129 source_addr->len = source_addr_as_resolved_addr.len;
134 // user provided test config
135 bool ipv4_supported_;
136 bool ipv6_supported_;
137 std::map<std::string, TestAddress> dest_addr_to_src_addr_;
140 static bool mock_source_addr_factory_wrapper_get_source_addr(
141 address_sorting_source_addr_factory* factory,
142 const address_sorting_address* dest_addr,
143 address_sorting_address* source_addr) {
144 MockSourceAddrFactory* mock =
145 reinterpret_cast<MockSourceAddrFactory*>(factory);
146 return mock->GetSourceAddr(dest_addr, source_addr);
149 void mock_source_addr_factory_wrapper_destroy(
150 address_sorting_source_addr_factory* factory) {
151 MockSourceAddrFactory* mock =
152 reinterpret_cast<MockSourceAddrFactory*>(factory);
156 const address_sorting_source_addr_factory_vtable kMockSourceAddrFactoryVtable =
158 mock_source_addr_factory_wrapper_get_source_addr,
159 mock_source_addr_factory_wrapper_destroy,
162 void OverrideAddressSortingSourceAddrFactory(
163 bool ipv4_supported, bool ipv6_supported,
164 const std::map<std::string, TestAddress>& dest_addr_to_src_addr) {
165 address_sorting_source_addr_factory* factory = new MockSourceAddrFactory(
166 ipv4_supported, ipv6_supported, dest_addr_to_src_addr);
167 factory->vtable = &kMockSourceAddrFactoryVtable;
168 address_sorting_override_source_addr_factory_for_testing(factory);
171 grpc_core::ServerAddressList BuildLbAddrInputs(
172 const std::vector<TestAddress>& test_addrs) {
173 grpc_core::ServerAddressList addresses;
174 for (const auto& addr : test_addrs) {
175 addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr);
180 void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses,
181 std::vector<std::string> expected_addrs) {
182 EXPECT_EQ(addresses.size(), expected_addrs.size());
183 for (size_t i = 0; i < addresses.size(); ++i) {
185 grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(),
186 false /* normalize */);
187 EXPECT_EQ(expected_addrs[i], ip_addr_str);
188 gpr_free(ip_addr_str);
190 grpc_core::ExecCtx exec_ctx;
193 /* We need to run each test case inside of its own
194 * isolated grpc_init/grpc_shutdown pair, so that
195 * the "address sorting source addr factory" can be
196 * restored to its default for each test case. */
197 class AddressSortingTest : public ::testing::Test {
199 void SetUp() override { grpc_init(); }
200 void TearDown() override { grpc_shutdown_blocking(); }
203 /* Tests for rule 1 */
204 TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
205 bool ipv4_supported = true;
206 bool ipv6_supported = true;
207 OverrideAddressSortingSourceAddrFactory(
208 ipv4_supported, ipv6_supported,
210 {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}},
212 auto lb_addrs = BuildLbAddrInputs({
213 {"1.2.3.4:443", AF_INET},
214 {"5.6.7.8:443", AF_INET},
216 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
217 VerifyLbAddrOutputs(lb_addrs, {
223 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
224 bool ipv4_supported = true;
225 bool ipv6_supported = false;
226 OverrideAddressSortingSourceAddrFactory(
227 ipv4_supported, ipv6_supported,
229 {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
231 auto lb_addrs = BuildLbAddrInputs({
232 {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
233 {"1.2.3.4:443", AF_INET},
235 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
236 VerifyLbAddrOutputs(lb_addrs, {
238 "[2607:f8b0:400a:801::1002]:443",
242 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
243 bool ipv4_supported = false;
244 bool ipv6_supported = true;
245 OverrideAddressSortingSourceAddrFactory(
246 ipv4_supported, ipv6_supported,
248 {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
249 {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}},
251 auto lb_addrs = BuildLbAddrInputs({
252 {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
253 {"1.2.3.4:443", AF_INET},
255 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
256 VerifyLbAddrOutputs(lb_addrs, {
257 "[2607:f8b0:400a:801::1002]:443",
262 /* Tests for rule 2 */
264 TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
265 bool ipv4_supported = true;
266 bool ipv6_supported = true;
267 OverrideAddressSortingSourceAddrFactory(
268 ipv4_supported, ipv6_supported,
270 {"[2000:f8b0:400a:801::1002]:443",
271 {"[fec0::1000]:0", AF_INET6}}, // global and site-local scope
273 {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope
275 auto lb_addrs = BuildLbAddrInputs({
276 {"[2000:f8b0:400a:801::1002]:443", AF_INET6},
277 {"[fec0::5000]:443", AF_INET6},
279 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
280 VerifyLbAddrOutputs(lb_addrs, {
282 "[2000:f8b0:400a:801::1002]:443",
286 /* Tests for rule 5 */
288 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
289 bool ipv4_supported = true;
290 bool ipv6_supported = true;
291 OverrideAddressSortingSourceAddrFactory(
292 ipv4_supported, ipv6_supported,
294 {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
296 {"[2001::5002]:0", AF_INET6}}, // matching labels
298 auto lb_addrs = BuildLbAddrInputs({
299 {"[2002::5001]:443", AF_INET6},
300 {"[2001::5001]:443", AF_INET6},
302 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
303 VerifyLbAddrOutputs(lb_addrs, {
309 /* Flip the input on the test above to reorder the sort function's
310 * comparator's inputs. */
311 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
312 bool ipv4_supported = true;
313 bool ipv6_supported = true;
314 OverrideAddressSortingSourceAddrFactory(
315 ipv4_supported, ipv6_supported,
317 {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
319 {"[2001::5002]:0", AF_INET6}}, // matching labels
321 auto lb_addrs = BuildLbAddrInputs({
322 {"[2001::5001]:443", AF_INET6},
323 {"[2002::5001]:443", AF_INET6},
325 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
326 VerifyLbAddrOutputs(lb_addrs, {
332 /* Tests for rule 6 */
334 TEST_F(AddressSortingTest,
335 TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {
336 bool ipv4_supported = true;
337 bool ipv6_supported = true;
338 OverrideAddressSortingSourceAddrFactory(
339 ipv4_supported, ipv6_supported,
341 {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
342 {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}},
344 auto lb_addrs = BuildLbAddrInputs({
345 {"[3ffe::5001]:443", AF_INET6},
346 {"1.2.3.4:443", AF_INET},
348 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
351 // The AF_INET address should be IPv4-mapped by the sort,
353 // addresses have higher precedence than 3ffe::/16 by spec.
359 TEST_F(AddressSortingTest,
360 TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) {
361 bool ipv4_supported = true;
362 bool ipv6_supported = true;
363 // Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
365 const char* v4_compat_dest = "[::0.0.0.2]:443";
366 const char* v4_compat_src = "[::0.0.0.2]:0";
368 const char* v4_compat_dest = "[::2]:443";
369 const char* v4_compat_src = "[::2]:0";
371 OverrideAddressSortingSourceAddrFactory(
372 ipv4_supported, ipv6_supported,
374 {"[::1]:443", {"[::1]:0", AF_INET6}},
375 {v4_compat_dest, {v4_compat_src, AF_INET6}},
377 auto lb_addrs = BuildLbAddrInputs({
378 {v4_compat_dest, AF_INET6},
379 {"[::1]:443", AF_INET6},
381 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
382 VerifyLbAddrOutputs(lb_addrs, {
388 TEST_F(AddressSortingTest,
389 TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
390 bool ipv4_supported = true;
391 bool ipv6_supported = true;
392 OverrideAddressSortingSourceAddrFactory(
393 ipv4_supported, ipv6_supported,
395 // 1234::2 for src and dest to make sure that prefix matching has no
396 // influence on this test.
397 {"[1234::2]:443", {"[1234::2]:0", AF_INET6}},
398 {"[::1]:443", {"[::1]:0", AF_INET6}},
400 auto lb_addrs = BuildLbAddrInputs({
401 {"[1234::2]:443", AF_INET6},
402 {"[::1]:443", AF_INET6},
404 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
408 // ::1 should match the localhost precedence entry and be prioritized
414 TEST_F(AddressSortingTest,
415 TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
416 bool ipv4_supported = true;
417 bool ipv6_supported = true;
418 OverrideAddressSortingSourceAddrFactory(
419 ipv4_supported, ipv6_supported,
421 {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}},
422 {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
424 auto lb_addrs = BuildLbAddrInputs({
425 {"[2001::1234]:443", AF_INET6},
426 {"[2000::5001]:443", AF_INET6},
428 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
431 // The 2000::/16 address should match the ::/0 prefix rule
439 TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) {
440 bool ipv4_supported = true;
441 bool ipv6_supported = true;
442 OverrideAddressSortingSourceAddrFactory(
443 ipv4_supported, ipv6_supported,
445 {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}},
446 {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
448 auto lb_addrs = BuildLbAddrInputs({
449 {"[2001::1231]:443", AF_INET6},
450 {"[2000::5001]:443", AF_INET6},
452 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
453 VerifyLbAddrOutputs(lb_addrs, {
459 TEST_F(AddressSortingTest,
460 TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {
461 bool ipv4_supported = true;
462 bool ipv6_supported = true;
463 OverrideAddressSortingSourceAddrFactory(
464 ipv4_supported, ipv6_supported,
466 {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
467 {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}},
469 auto lb_addrs = BuildLbAddrInputs({
470 {"[fec0::1234]:443", AF_INET6},
471 {"[fc00::5001]:443", AF_INET6},
473 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
474 VerifyLbAddrOutputs(lb_addrs, {
482 TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) {
483 bool ipv4_supported = true;
484 bool ipv6_supported = true;
485 // Use embedded ipv4 addresses with leading 1's instead of zero's to be
486 // compatible with inet_ntop implementations that can display such
487 // addresses with leading zero's as e.g.: "::ffff:0:2", as on windows.
488 OverrideAddressSortingSourceAddrFactory(
489 ipv4_supported, ipv6_supported,
491 {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},
492 {"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
494 auto lb_addrs = BuildLbAddrInputs({
495 {"[::ffff:1.1.1.2]:443", AF_INET6},
496 {"[1234::2]:443", AF_INET6},
498 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
499 VerifyLbAddrOutputs(lb_addrs, {
500 // ::ffff:0:2 should match the v4-mapped
501 // precedence entry and be deprioritized.
503 "[::ffff:1.1.1.2]:443",
507 /* Tests for rule 8 */
509 TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
510 bool ipv4_supported = true;
511 bool ipv6_supported = true;
512 OverrideAddressSortingSourceAddrFactory(
513 ipv4_supported, ipv6_supported,
515 // Both of these destinations have the same precedence in default
518 {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
519 {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
521 auto lb_addrs = BuildLbAddrInputs({
522 {"[3ffe::5001]:443", AF_INET6},
523 {"[fec0::1234]:443", AF_INET6},
525 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
526 VerifyLbAddrOutputs(lb_addrs, {
532 /* Tests for rule 9 */
534 TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
535 bool ipv4_supported = true;
536 bool ipv6_supported = true;
537 OverrideAddressSortingSourceAddrFactory(
538 ipv4_supported, ipv6_supported,
540 // Both of these destinations have the same precedence in default
543 {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}},
544 {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}},
546 auto lb_addrs = BuildLbAddrInputs({
547 {"[3ffe:5001::]:443", AF_INET6},
548 {"[3ffe:1234::]:443", AF_INET6},
550 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
551 VerifyLbAddrOutputs(lb_addrs, {
557 TEST_F(AddressSortingTest,
558 TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {
559 bool ipv4_supported = true;
560 bool ipv6_supported = true;
561 OverrideAddressSortingSourceAddrFactory(
562 ipv4_supported, ipv6_supported,
564 {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}},
565 {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}},
567 auto lb_addrs = BuildLbAddrInputs({
568 {"[3ffe::5001]:443", AF_INET6},
569 {"[3ffe::1234]:443", AF_INET6},
571 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
572 VerifyLbAddrOutputs(lb_addrs, {
578 TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
579 bool ipv4_supported = true;
580 bool ipv6_supported = true;
581 OverrideAddressSortingSourceAddrFactory(
582 ipv4_supported, ipv6_supported,
584 {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}},
585 {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}},
587 auto lb_addrs = BuildLbAddrInputs({
588 {"[3ffe:8000::]:443", AF_INET6},
589 {"[3ffe:2000::]:443", AF_INET6},
591 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
592 VerifyLbAddrOutputs(lb_addrs, {
598 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
599 bool ipv4_supported = true;
600 bool ipv6_supported = true;
601 OverrideAddressSortingSourceAddrFactory(
602 ipv4_supported, ipv6_supported,
604 {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}},
605 {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}},
607 auto lb_addrs = BuildLbAddrInputs({
608 {"[3ffe:6::]:443", AF_INET6},
609 {"[3ffe:c::]:443", AF_INET6},
611 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
612 VerifyLbAddrOutputs(lb_addrs, {
618 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
619 bool ipv4_supported = true;
620 bool ipv6_supported = true;
621 OverrideAddressSortingSourceAddrFactory(
622 ipv4_supported, ipv6_supported,
624 {"[3ffe:1111:1111:1111::]:443",
625 {"[3ffe:1111:1111:1111::]:0", AF_INET6}},
626 {"[3ffe:1111:1111:1110::]:443",
627 {"[3ffe:1111:1111:1111::]:0", AF_INET6}},
629 auto lb_addrs = BuildLbAddrInputs({
630 {"[3ffe:1111:1111:1110::]:443", AF_INET6},
631 {"[3ffe:1111:1111:1111::]:443", AF_INET6},
633 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
634 VerifyLbAddrOutputs(lb_addrs, {
635 "[3ffe:1111:1111:1111::]:443",
636 "[3ffe:1111:1111:1110::]:443",
640 /* Tests for rule 10 */
642 TEST_F(AddressSortingTest, TestStableSort) {
643 bool ipv4_supported = true;
644 bool ipv6_supported = true;
645 OverrideAddressSortingSourceAddrFactory(
646 ipv4_supported, ipv6_supported,
648 {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}},
649 {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}},
651 auto lb_addrs = BuildLbAddrInputs({
652 {"[3ffe::1234]:443", AF_INET6},
653 {"[3ffe::1235]:443", AF_INET6},
655 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
656 VerifyLbAddrOutputs(lb_addrs, {
662 TEST_F(AddressSortingTest, TestStableSortFiveElements) {
663 bool ipv4_supported = true;
664 bool ipv6_supported = true;
665 OverrideAddressSortingSourceAddrFactory(
666 ipv4_supported, ipv6_supported,
668 {"[3ffe::1231]:443", {"[3ffe::1201]:0", AF_INET6}},
669 {"[3ffe::1232]:443", {"[3ffe::1202]:0", AF_INET6}},
670 {"[3ffe::1233]:443", {"[3ffe::1203]:0", AF_INET6}},
671 {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}},
672 {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}},
674 auto lb_addrs = BuildLbAddrInputs({
675 {"[3ffe::1231]:443", AF_INET6},
676 {"[3ffe::1232]:443", AF_INET6},
677 {"[3ffe::1233]:443", AF_INET6},
678 {"[3ffe::1234]:443", AF_INET6},
679 {"[3ffe::1235]:443", AF_INET6},
681 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
682 VerifyLbAddrOutputs(lb_addrs, {
691 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
692 bool ipv4_supported = true;
693 bool ipv6_supported = true;
694 OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
695 auto lb_addrs = BuildLbAddrInputs({
696 {"[3ffe::1231]:443", AF_INET6},
697 {"[3ffe::1232]:443", AF_INET6},
698 {"[3ffe::1233]:443", AF_INET6},
699 {"[3ffe::1234]:443", AF_INET6},
700 {"[3ffe::1235]:443", AF_INET6},
702 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
703 VerifyLbAddrOutputs(lb_addrs, {
712 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
713 bool ipv4_supported = true;
714 bool ipv6_supported = true;
715 OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
716 auto lb_addrs = BuildLbAddrInputs({
717 {"[::ffff:5.6.7.8]:443", AF_INET6},
718 {"1.2.3.4:443", AF_INET},
720 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
721 VerifyLbAddrOutputs(lb_addrs, {
722 "[::ffff:5.6.7.8]:443",
727 TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
728 bool ipv4_supported = true;
729 bool ipv6_supported = true;
730 // Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
732 const char* v4_compat_dest = "[::0.0.0.2]:443";
733 const char* v4_compat_src = "[::0.0.0.3]:0";
735 const char* v4_compat_dest = "[::2]:443";
736 const char* v4_compat_src = "[::3]:0";
738 OverrideAddressSortingSourceAddrFactory(
739 ipv4_supported, ipv6_supported,
741 {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}},
742 {v4_compat_dest, {v4_compat_src, AF_INET6}},
744 auto lb_addrs = BuildLbAddrInputs({
745 {"[fec0::2000]:443", AF_INET6},
746 {v4_compat_dest, AF_INET6},
748 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
749 VerifyLbAddrOutputs(lb_addrs,
751 // The sort should be stable since
752 // v4-compatible has same precedence as site-local.
758 /* TestPrefersIpv6Loopback tests the actual "address probing" code
759 * for the current platform, without any mocks.
760 * This test relies on the assumption that the ipv6 loopback address is
761 * available in the hosts/containers that grpc C/C++ tests run on
762 * (whether ipv4 loopback is available or not, an available ipv6
763 * loopback should be preferred). */
764 TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
765 auto lb_addrs = BuildLbAddrInputs({
766 {"[::1]:443", AF_INET6},
767 {"127.0.0.1:443", AF_INET},
769 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
770 VerifyLbAddrOutputs(lb_addrs, {
776 /* Flip the order of the inputs above and expect the same output order
777 * (try to rule out influence of arbitrary qsort ordering) */
778 TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
779 auto lb_addrs = BuildLbAddrInputs({
780 {"127.0.0.1:443", AF_INET},
781 {"[::1]:443", AF_INET6},
783 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
784 VerifyLbAddrOutputs(lb_addrs, {
790 /* Try to rule out false positives in the above two tests in which
791 * the sorter might think that neither ipv6 or ipv4 loopback is
792 * available, but ipv6 loopback is still preferred only due
793 * to precedence table lookups. */
794 TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {
795 sockaddr_in6 ipv6_loopback;
796 memset(&ipv6_loopback, 0, sizeof(ipv6_loopback));
797 ipv6_loopback.sin6_family = AF_INET6;
798 ((char*)&ipv6_loopback.sin6_addr)[15] = 1;
799 ipv6_loopback.sin6_port = htons(443);
800 // Set up the source and destination parameters of
801 // address_sorting_get_source_addr
802 address_sorting_address sort_input_dest;
803 memcpy(&sort_input_dest.addr, &ipv6_loopback, sizeof(ipv6_loopback));
804 sort_input_dest.len = sizeof(ipv6_loopback);
805 address_sorting_address source_for_sort_input_dest;
806 memset(&source_for_sort_input_dest, 0, sizeof(source_for_sort_input_dest));
807 // address_sorting_get_source_addr returns true if a source address was found
808 // for the destination address, otherwise false.
809 EXPECT_TRUE(address_sorting_get_source_addr_for_testing(
810 &sort_input_dest, &source_for_sort_input_dest));
811 // Now also check that the source address was filled in correctly.
812 EXPECT_GT(source_for_sort_input_dest.len, 0u);
813 sockaddr_in6* source_addr_output =
814 (sockaddr_in6*)source_for_sort_input_dest.addr;
815 EXPECT_EQ(source_addr_output->sin6_family, AF_INET6);
816 char* buf = static_cast<char*>(gpr_zalloc(100));
817 EXPECT_NE(inet_ntop(AF_INET6, &source_addr_output->sin6_addr, buf, 100),
819 << "inet_ntop failed. Errno: " + std::to_string(errno);
820 std::string source_addr_str(buf);
823 // assumes that the source address for any loopback destination is also the
825 EXPECT_EQ(source_addr_str, "::1");
830 int main(int argc, char** argv) {
831 char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
832 if (resolver == nullptr || strlen(resolver) == 0) {
833 gpr_setenv("GRPC_DNS_RESOLVER", "ares");
834 } else if (strcmp("ares", resolver)) {
835 gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver);
838 grpc::testing::TestEnvironment env(argc, argv);
839 ::testing::InitGoogleTest(&argc, argv);
840 auto result = RUN_ALL_TESTS();
841 // Test sequential and nested inits and shutdowns.