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 <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>
28 #include <sys/types.h>
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"
52 #include <arpa/inet.h>
53 #include <netinet/in.h>
54 #include <sys/socket.h>
60 std::string dest_addr;
64 grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) {
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) {
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);
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);
90 class MockSourceAddrFactory : public address_sorting_source_addr_factory {
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) {}
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 &&
104 (address_sorting_abstract_get_family(dest_addr) ==
105 ADDRESS_SORTING_AF_INET6 &&
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());
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;
129 // user provided test config
130 bool ipv4_supported_;
131 bool ipv6_supported_;
132 std::map<std::string, TestAddress> dest_addr_to_src_addr_;
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);
144 void mock_source_addr_factory_wrapper_destroy(
145 address_sorting_source_addr_factory* factory) {
146 MockSourceAddrFactory* mock =
147 reinterpret_cast<MockSourceAddrFactory*>(factory);
151 const address_sorting_source_addr_factory_vtable kMockSourceAddrFactoryVtable =
153 mock_source_addr_factory_wrapper_get_source_addr,
154 mock_source_addr_factory_wrapper_destroy,
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);
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);
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);
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 {
191 void SetUp() override { grpc_init(); }
192 void TearDown() override { grpc_shutdown(); }
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,
202 {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}},
204 auto lb_addrs = BuildLbAddrInputs({
205 {"1.2.3.4:443", AF_INET},
206 {"5.6.7.8:443", AF_INET},
208 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
209 VerifyLbAddrOutputs(lb_addrs, {
215 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
216 bool ipv4_supported = true;
217 bool ipv6_supported = false;
218 OverrideAddressSortingSourceAddrFactory(
219 ipv4_supported, ipv6_supported,
221 {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
223 auto lb_addrs = BuildLbAddrInputs({
224 {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
225 {"1.2.3.4:443", AF_INET},
227 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
228 VerifyLbAddrOutputs(lb_addrs, {
230 "[2607:f8b0:400a:801::1002]:443",
234 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
235 bool ipv4_supported = false;
236 bool ipv6_supported = true;
237 OverrideAddressSortingSourceAddrFactory(
238 ipv4_supported, ipv6_supported,
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}},
243 auto lb_addrs = BuildLbAddrInputs({
244 {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
245 {"1.2.3.4:443", AF_INET},
247 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
248 VerifyLbAddrOutputs(lb_addrs, {
249 "[2607:f8b0:400a:801::1002]:443",
254 /* Tests for rule 2 */
256 TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
257 bool ipv4_supported = true;
258 bool ipv6_supported = true;
259 OverrideAddressSortingSourceAddrFactory(
260 ipv4_supported, ipv6_supported,
262 {"[2000:f8b0:400a:801::1002]:443",
263 {"[fec0::1000]:0", AF_INET6}}, // global and site-local scope
265 {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope
267 auto lb_addrs = BuildLbAddrInputs({
268 {"[2000:f8b0:400a:801::1002]:443", AF_INET6},
269 {"[fec0::5000]:443", AF_INET6},
271 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
272 VerifyLbAddrOutputs(lb_addrs, {
274 "[2000:f8b0:400a:801::1002]:443",
278 /* Tests for rule 5 */
280 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
281 bool ipv4_supported = true;
282 bool ipv6_supported = true;
283 OverrideAddressSortingSourceAddrFactory(
284 ipv4_supported, ipv6_supported,
286 {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
288 {"[2001::5002]:0", AF_INET6}}, // matching labels
290 auto lb_addrs = BuildLbAddrInputs({
291 {"[2002::5001]:443", AF_INET6},
292 {"[2001::5001]:443", AF_INET6},
294 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
295 VerifyLbAddrOutputs(lb_addrs, {
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,
309 {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
311 {"[2001::5002]:0", AF_INET6}}, // matching labels
313 auto lb_addrs = BuildLbAddrInputs({
314 {"[2001::5001]:443", AF_INET6},
315 {"[2002::5001]:443", AF_INET6},
317 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
318 VerifyLbAddrOutputs(lb_addrs, {
324 /* Tests for rule 6 */
326 TEST_F(AddressSortingTest,
327 TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {
328 bool ipv4_supported = true;
329 bool ipv6_supported = true;
330 OverrideAddressSortingSourceAddrFactory(
331 ipv4_supported, ipv6_supported,
333 {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
334 {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}},
336 auto lb_addrs = BuildLbAddrInputs({
337 {"[3ffe::5001]:443", AF_INET6},
338 {"1.2.3.4:443", AF_INET},
340 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
343 // The AF_INET address should be IPv4-mapped by the sort,
345 // addresses have higher precedence than 3ffe::/16 by spec.
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.
357 const char* v4_compat_dest = "[::0.0.0.2]:443";
358 const char* v4_compat_src = "[::0.0.0.2]:0";
360 const char* v4_compat_dest = "[::2]:443";
361 const char* v4_compat_src = "[::2]:0";
363 OverrideAddressSortingSourceAddrFactory(
364 ipv4_supported, ipv6_supported,
366 {"[::1]:443", {"[::1]:0", AF_INET6}},
367 {v4_compat_dest, {v4_compat_src, AF_INET6}},
369 auto lb_addrs = BuildLbAddrInputs({
370 {v4_compat_dest, AF_INET6},
371 {"[::1]:443", AF_INET6},
373 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
374 VerifyLbAddrOutputs(lb_addrs, {
380 TEST_F(AddressSortingTest,
381 TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
382 bool ipv4_supported = true;
383 bool ipv6_supported = true;
384 OverrideAddressSortingSourceAddrFactory(
385 ipv4_supported, ipv6_supported,
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}},
392 auto lb_addrs = BuildLbAddrInputs({
393 {"[1234::2]:443", AF_INET6},
394 {"[::1]:443", AF_INET6},
396 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
400 // ::1 should match the localhost precedence entry and be prioritized
406 TEST_F(AddressSortingTest,
407 TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
408 bool ipv4_supported = true;
409 bool ipv6_supported = true;
410 OverrideAddressSortingSourceAddrFactory(
411 ipv4_supported, ipv6_supported,
413 {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}},
414 {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
416 auto lb_addrs = BuildLbAddrInputs({
417 {"[2001::1234]:443", AF_INET6},
418 {"[2000::5001]:443", AF_INET6},
420 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
423 // The 2000::/16 address should match the ::/0 prefix rule
431 TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) {
432 bool ipv4_supported = true;
433 bool ipv6_supported = true;
434 OverrideAddressSortingSourceAddrFactory(
435 ipv4_supported, ipv6_supported,
437 {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}},
438 {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
440 auto lb_addrs = BuildLbAddrInputs({
441 {"[2001::1231]:443", AF_INET6},
442 {"[2000::5001]:443", AF_INET6},
444 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
445 VerifyLbAddrOutputs(lb_addrs, {
451 TEST_F(AddressSortingTest,
452 TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {
453 bool ipv4_supported = true;
454 bool ipv6_supported = true;
455 OverrideAddressSortingSourceAddrFactory(
456 ipv4_supported, ipv6_supported,
458 {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
459 {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}},
461 auto lb_addrs = BuildLbAddrInputs({
462 {"[fec0::1234]:443", AF_INET6},
463 {"[fc00::5001]:443", AF_INET6},
465 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
466 VerifyLbAddrOutputs(lb_addrs, {
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,
483 {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},
484 {"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
486 auto lb_addrs = BuildLbAddrInputs({
487 {"[::ffff:1.1.1.2]:443", AF_INET6},
488 {"[1234::2]:443", AF_INET6},
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.
495 "[::ffff:1.1.1.2]:443",
499 /* Tests for rule 8 */
501 TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
502 bool ipv4_supported = true;
503 bool ipv6_supported = true;
504 OverrideAddressSortingSourceAddrFactory(
505 ipv4_supported, ipv6_supported,
507 // Both of these destinations have the same precedence in default
510 {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
511 {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
513 auto lb_addrs = BuildLbAddrInputs({
514 {"[3ffe::5001]:443", AF_INET6},
515 {"[fec0::1234]:443", AF_INET6},
517 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
518 VerifyLbAddrOutputs(lb_addrs, {
524 /* Tests for rule 9 */
526 TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
527 bool ipv4_supported = true;
528 bool ipv6_supported = true;
529 OverrideAddressSortingSourceAddrFactory(
530 ipv4_supported, ipv6_supported,
532 // Both of these destinations have the same precedence in default
535 {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}},
536 {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}},
538 auto lb_addrs = BuildLbAddrInputs({
539 {"[3ffe:5001::]:443", AF_INET6},
540 {"[3ffe:1234::]:443", AF_INET6},
542 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
543 VerifyLbAddrOutputs(lb_addrs, {
549 TEST_F(AddressSortingTest,
550 TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {
551 bool ipv4_supported = true;
552 bool ipv6_supported = true;
553 OverrideAddressSortingSourceAddrFactory(
554 ipv4_supported, ipv6_supported,
556 {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}},
557 {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}},
559 auto lb_addrs = BuildLbAddrInputs({
560 {"[3ffe::5001]:443", AF_INET6},
561 {"[3ffe::1234]:443", AF_INET6},
563 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
564 VerifyLbAddrOutputs(lb_addrs, {
570 TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
571 bool ipv4_supported = true;
572 bool ipv6_supported = true;
573 OverrideAddressSortingSourceAddrFactory(
574 ipv4_supported, ipv6_supported,
576 {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}},
577 {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}},
579 auto lb_addrs = BuildLbAddrInputs({
580 {"[3ffe:8000::]:443", AF_INET6},
581 {"[3ffe:2000::]:443", AF_INET6},
583 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
584 VerifyLbAddrOutputs(lb_addrs, {
590 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
591 bool ipv4_supported = true;
592 bool ipv6_supported = true;
593 OverrideAddressSortingSourceAddrFactory(
594 ipv4_supported, ipv6_supported,
596 {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}},
597 {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}},
599 auto lb_addrs = BuildLbAddrInputs({
600 {"[3ffe:6::]:443", AF_INET6},
601 {"[3ffe:c::]:443", AF_INET6},
603 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
604 VerifyLbAddrOutputs(lb_addrs, {
610 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
611 bool ipv4_supported = true;
612 bool ipv6_supported = true;
613 OverrideAddressSortingSourceAddrFactory(
614 ipv4_supported, ipv6_supported,
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}},
621 auto lb_addrs = BuildLbAddrInputs({
622 {"[3ffe:1111:1111:1110::]:443", AF_INET6},
623 {"[3ffe:1111:1111:1111::]:443", AF_INET6},
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",
632 /* Tests for rule 10 */
634 TEST_F(AddressSortingTest, TestStableSort) {
635 bool ipv4_supported = true;
636 bool ipv6_supported = true;
637 OverrideAddressSortingSourceAddrFactory(
638 ipv4_supported, ipv6_supported,
640 {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}},
641 {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}},
643 auto lb_addrs = BuildLbAddrInputs({
644 {"[3ffe::1234]:443", AF_INET6},
645 {"[3ffe::1235]:443", AF_INET6},
647 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
648 VerifyLbAddrOutputs(lb_addrs, {
654 TEST_F(AddressSortingTest, TestStableSortFiveElements) {
655 bool ipv4_supported = true;
656 bool ipv6_supported = true;
657 OverrideAddressSortingSourceAddrFactory(
658 ipv4_supported, ipv6_supported,
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}},
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},
673 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
674 VerifyLbAddrOutputs(lb_addrs, {
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},
694 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
695 VerifyLbAddrOutputs(lb_addrs, {
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},
712 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
713 VerifyLbAddrOutputs(lb_addrs, {
714 "[::ffff:5.6.7.8]:443",
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.
724 const char* v4_compat_dest = "[::0.0.0.2]:443";
725 const char* v4_compat_src = "[::0.0.0.3]:0";
727 const char* v4_compat_dest = "[::2]:443";
728 const char* v4_compat_src = "[::3]:0";
730 OverrideAddressSortingSourceAddrFactory(
731 ipv4_supported, ipv6_supported,
733 {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}},
734 {v4_compat_dest, {v4_compat_src, AF_INET6}},
736 auto lb_addrs = BuildLbAddrInputs({
737 {"[fec0::2000]:443", AF_INET6},
738 {v4_compat_dest, AF_INET6},
740 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
741 VerifyLbAddrOutputs(lb_addrs,
743 // The sort should be stable since
744 // v4-compatible has same precedence as site-local.
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},
761 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
762 VerifyLbAddrOutputs(lb_addrs, {
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},
775 grpc_cares_wrapper_address_sorting_sort(nullptr, &lb_addrs);
776 VerifyLbAddrOutputs(lb_addrs, {
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),
811 << "inet_ntop failed. Errno: " + std::to_string(errno);
812 std::string source_addr_str(buf);
815 // assumes that the source address for any loopback destination is also the
817 EXPECT_EQ(source_addr_str, "::1");
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());
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.