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/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"
54 #include <arpa/inet.h>
55 #include <netinet/in.h>
56 #include <sys/socket.h>
62 std::string dest_addr;
66 grpc_resolved_address TestAddressToGrpcResolvedAddress(TestAddress test_addr) {
67 grpc_core::UniquePtr<char> host;
68 grpc_core::UniquePtr<char> port;
69 grpc_resolved_address resolved_addr;
70 grpc_core::SplitHostPort(test_addr.dest_addr.c_str(), &host, &port);
71 if (test_addr.family == AF_INET) {
73 memset(&in_dest, 0, sizeof(sockaddr_in));
74 in_dest.sin_port = htons(atoi(port.get()));
75 in_dest.sin_family = AF_INET;
76 GPR_ASSERT(inet_pton(AF_INET, host.get(), &in_dest.sin_addr) == 1);
77 memcpy(&resolved_addr.addr, &in_dest, sizeof(sockaddr_in));
78 resolved_addr.len = sizeof(sockaddr_in);
80 GPR_ASSERT(test_addr.family == AF_INET6);
81 sockaddr_in6 in6_dest;
82 memset(&in6_dest, 0, sizeof(sockaddr_in6));
83 in6_dest.sin6_port = htons(atoi(port.get()));
84 in6_dest.sin6_family = AF_INET6;
85 GPR_ASSERT(inet_pton(AF_INET6, host.get(), &in6_dest.sin6_addr) == 1);
86 memcpy(&resolved_addr.addr, &in6_dest, sizeof(sockaddr_in6));
87 resolved_addr.len = sizeof(sockaddr_in6);
92 class MockSourceAddrFactory : public address_sorting_source_addr_factory {
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) {}
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 &&
106 (address_sorting_abstract_get_family(dest_addr) ==
107 ADDRESS_SORTING_AF_INET6 &&
112 grpc_resolved_address dest_addr_as_resolved_addr;
113 memcpy(&dest_addr_as_resolved_addr.addr, dest_addr, dest_addr->len);
114 dest_addr_as_resolved_addr.len = dest_addr->len;
115 grpc_sockaddr_to_string(&ip_addr_str, &dest_addr_as_resolved_addr,
116 false /* normalize */);
117 auto it = dest_addr_to_src_addr_.find(ip_addr_str);
118 if (it == dest_addr_to_src_addr_.end()) {
119 gpr_log(GPR_DEBUG, "can't find |%s| in dest to src map", ip_addr_str);
120 gpr_free(ip_addr_str);
123 gpr_free(ip_addr_str);
124 grpc_resolved_address source_addr_as_resolved_addr =
125 TestAddressToGrpcResolvedAddress(it->second);
126 memcpy(source_addr->addr, &source_addr_as_resolved_addr.addr,
127 source_addr_as_resolved_addr.len);
128 source_addr->len = source_addr_as_resolved_addr.len;
133 // user provided test config
134 bool ipv4_supported_;
135 bool ipv6_supported_;
136 std::map<std::string, TestAddress> dest_addr_to_src_addr_;
139 static bool mock_source_addr_factory_wrapper_get_source_addr(
140 address_sorting_source_addr_factory* factory,
141 const address_sorting_address* dest_addr,
142 address_sorting_address* source_addr) {
143 MockSourceAddrFactory* mock =
144 reinterpret_cast<MockSourceAddrFactory*>(factory);
145 return mock->GetSourceAddr(dest_addr, source_addr);
148 void mock_source_addr_factory_wrapper_destroy(
149 address_sorting_source_addr_factory* factory) {
150 MockSourceAddrFactory* mock =
151 reinterpret_cast<MockSourceAddrFactory*>(factory);
155 const address_sorting_source_addr_factory_vtable kMockSourceAddrFactoryVtable =
157 mock_source_addr_factory_wrapper_get_source_addr,
158 mock_source_addr_factory_wrapper_destroy,
161 void OverrideAddressSortingSourceAddrFactory(
162 bool ipv4_supported, bool ipv6_supported,
163 const std::map<std::string, TestAddress>& dest_addr_to_src_addr) {
164 address_sorting_source_addr_factory* factory = new MockSourceAddrFactory(
165 ipv4_supported, ipv6_supported, dest_addr_to_src_addr);
166 factory->vtable = &kMockSourceAddrFactoryVtable;
167 address_sorting_override_source_addr_factory_for_testing(factory);
170 grpc_core::ServerAddressList BuildLbAddrInputs(
171 const std::vector<TestAddress>& test_addrs) {
172 grpc_core::ServerAddressList addresses;
173 for (const auto& addr : test_addrs) {
174 addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr);
179 void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses,
180 std::vector<std::string> expected_addrs) {
181 EXPECT_EQ(addresses.size(), expected_addrs.size());
182 for (size_t i = 0; i < addresses.size(); ++i) {
184 grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(),
185 false /* normalize */);
186 EXPECT_EQ(expected_addrs[i], ip_addr_str);
187 gpr_free(ip_addr_str);
189 grpc_core::ExecCtx exec_ctx;
192 /* We need to run each test case inside of its own
193 * isolated grpc_init/grpc_shutdown pair, so that
194 * the "address sorting source addr factory" can be
195 * restored to its default for each test case. */
196 class AddressSortingTest : public ::testing::Test {
198 void SetUp() override { grpc_init(); }
199 void TearDown() override { grpc_shutdown_blocking(); }
202 /* Tests for rule 1 */
203 TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
204 bool ipv4_supported = true;
205 bool ipv6_supported = true;
206 OverrideAddressSortingSourceAddrFactory(
207 ipv4_supported, ipv6_supported,
209 {"1.2.3.4:443", {"4.3.2.1:443", AF_INET}},
211 auto lb_addrs = BuildLbAddrInputs({
212 {"1.2.3.4:443", AF_INET},
213 {"5.6.7.8:443", AF_INET},
215 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
216 VerifyLbAddrOutputs(lb_addrs, {
222 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
223 bool ipv4_supported = true;
224 bool ipv6_supported = false;
225 OverrideAddressSortingSourceAddrFactory(
226 ipv4_supported, ipv6_supported,
228 {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
230 auto lb_addrs = BuildLbAddrInputs({
231 {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
232 {"1.2.3.4:443", AF_INET},
234 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
235 VerifyLbAddrOutputs(lb_addrs, {
237 "[2607:f8b0:400a:801::1002]:443",
241 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
242 bool ipv4_supported = false;
243 bool ipv6_supported = true;
244 OverrideAddressSortingSourceAddrFactory(
245 ipv4_supported, ipv6_supported,
247 {"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
248 {"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}},
250 auto lb_addrs = BuildLbAddrInputs({
251 {"[2607:f8b0:400a:801::1002]:443", AF_INET6},
252 {"1.2.3.4:443", AF_INET},
254 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
255 VerifyLbAddrOutputs(lb_addrs, {
256 "[2607:f8b0:400a:801::1002]:443",
261 /* Tests for rule 2 */
263 TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
264 bool ipv4_supported = true;
265 bool ipv6_supported = true;
266 OverrideAddressSortingSourceAddrFactory(
267 ipv4_supported, ipv6_supported,
269 {"[2000:f8b0:400a:801::1002]:443",
270 {"[fec0::1000]:0", AF_INET6}}, // global and site-local scope
272 {"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope
274 auto lb_addrs = BuildLbAddrInputs({
275 {"[2000:f8b0:400a:801::1002]:443", AF_INET6},
276 {"[fec0::5000]:443", AF_INET6},
278 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
279 VerifyLbAddrOutputs(lb_addrs, {
281 "[2000:f8b0:400a:801::1002]:443",
285 /* Tests for rule 5 */
287 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
288 bool ipv4_supported = true;
289 bool ipv6_supported = true;
290 OverrideAddressSortingSourceAddrFactory(
291 ipv4_supported, ipv6_supported,
293 {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
295 {"[2001::5002]:0", AF_INET6}}, // matching labels
297 auto lb_addrs = BuildLbAddrInputs({
298 {"[2002::5001]:443", AF_INET6},
299 {"[2001::5001]:443", AF_INET6},
301 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
302 VerifyLbAddrOutputs(lb_addrs, {
308 /* Flip the input on the test above to reorder the sort function's
309 * comparator's inputs. */
310 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
311 bool ipv4_supported = true;
312 bool ipv6_supported = true;
313 OverrideAddressSortingSourceAddrFactory(
314 ipv4_supported, ipv6_supported,
316 {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
318 {"[2001::5002]:0", AF_INET6}}, // matching labels
320 auto lb_addrs = BuildLbAddrInputs({
321 {"[2001::5001]:443", AF_INET6},
322 {"[2002::5001]:443", AF_INET6},
324 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
325 VerifyLbAddrOutputs(lb_addrs, {
331 /* Tests for rule 6 */
333 TEST_F(AddressSortingTest,
334 TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {
335 bool ipv4_supported = true;
336 bool ipv6_supported = true;
337 OverrideAddressSortingSourceAddrFactory(
338 ipv4_supported, ipv6_supported,
340 {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
341 {"1.2.3.4:443", {"5.6.7.8:0", AF_INET}},
343 auto lb_addrs = BuildLbAddrInputs({
344 {"[3ffe::5001]:443", AF_INET6},
345 {"1.2.3.4:443", AF_INET},
347 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
350 // The AF_INET address should be IPv4-mapped by the sort,
352 // addresses have higher precedence than 3ffe::/16 by spec.
358 TEST_F(AddressSortingTest,
359 TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) {
360 bool ipv4_supported = true;
361 bool ipv6_supported = true;
362 // Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
364 const char* v4_compat_dest = "[::0.0.0.2]:443";
365 const char* v4_compat_src = "[::0.0.0.2]:0";
367 const char* v4_compat_dest = "[::2]:443";
368 const char* v4_compat_src = "[::2]:0";
370 OverrideAddressSortingSourceAddrFactory(
371 ipv4_supported, ipv6_supported,
373 {"[::1]:443", {"[::1]:0", AF_INET6}},
374 {v4_compat_dest, {v4_compat_src, AF_INET6}},
376 auto lb_addrs = BuildLbAddrInputs({
377 {v4_compat_dest, AF_INET6},
378 {"[::1]:443", AF_INET6},
380 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
381 VerifyLbAddrOutputs(lb_addrs, {
387 TEST_F(AddressSortingTest,
388 TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
389 bool ipv4_supported = true;
390 bool ipv6_supported = true;
391 OverrideAddressSortingSourceAddrFactory(
392 ipv4_supported, ipv6_supported,
394 // 1234::2 for src and dest to make sure that prefix matching has no
395 // influence on this test.
396 {"[1234::2]:443", {"[1234::2]:0", AF_INET6}},
397 {"[::1]:443", {"[::1]:0", AF_INET6}},
399 auto lb_addrs = BuildLbAddrInputs({
400 {"[1234::2]:443", AF_INET6},
401 {"[::1]:443", AF_INET6},
403 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
407 // ::1 should match the localhost precedence entry and be prioritized
413 TEST_F(AddressSortingTest,
414 TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
415 bool ipv4_supported = true;
416 bool ipv6_supported = true;
417 OverrideAddressSortingSourceAddrFactory(
418 ipv4_supported, ipv6_supported,
420 {"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}},
421 {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
423 auto lb_addrs = BuildLbAddrInputs({
424 {"[2001::1234]:443", AF_INET6},
425 {"[2000::5001]:443", AF_INET6},
427 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
430 // The 2000::/16 address should match the ::/0 prefix rule
438 TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) {
439 bool ipv4_supported = true;
440 bool ipv6_supported = true;
441 OverrideAddressSortingSourceAddrFactory(
442 ipv4_supported, ipv6_supported,
444 {"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}},
445 {"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
447 auto lb_addrs = BuildLbAddrInputs({
448 {"[2001::1231]:443", AF_INET6},
449 {"[2000::5001]:443", AF_INET6},
451 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
452 VerifyLbAddrOutputs(lb_addrs, {
458 TEST_F(AddressSortingTest,
459 TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {
460 bool ipv4_supported = true;
461 bool ipv6_supported = true;
462 OverrideAddressSortingSourceAddrFactory(
463 ipv4_supported, ipv6_supported,
465 {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
466 {"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}},
468 auto lb_addrs = BuildLbAddrInputs({
469 {"[fec0::1234]:443", AF_INET6},
470 {"[fc00::5001]:443", AF_INET6},
472 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
473 VerifyLbAddrOutputs(lb_addrs, {
481 TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) {
482 bool ipv4_supported = true;
483 bool ipv6_supported = true;
484 // Use embedded ipv4 addresses with leading 1's instead of zero's to be
485 // compatible with inet_ntop implementations that can display such
486 // addresses with leading zero's as e.g.: "::ffff:0:2", as on windows.
487 OverrideAddressSortingSourceAddrFactory(
488 ipv4_supported, ipv6_supported,
490 {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},
491 {"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
493 auto lb_addrs = BuildLbAddrInputs({
494 {"[::ffff:1.1.1.2]:443", AF_INET6},
495 {"[1234::2]:443", AF_INET6},
497 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
498 VerifyLbAddrOutputs(lb_addrs, {
499 // ::ffff:0:2 should match the v4-mapped
500 // precedence entry and be deprioritized.
502 "[::ffff:1.1.1.2]:443",
506 /* Tests for rule 8 */
508 TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
509 bool ipv4_supported = true;
510 bool ipv6_supported = true;
511 OverrideAddressSortingSourceAddrFactory(
512 ipv4_supported, ipv6_supported,
514 // Both of these destinations have the same precedence in default
517 {"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
518 {"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
520 auto lb_addrs = BuildLbAddrInputs({
521 {"[3ffe::5001]:443", AF_INET6},
522 {"[fec0::1234]:443", AF_INET6},
524 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
525 VerifyLbAddrOutputs(lb_addrs, {
531 /* Tests for rule 9 */
533 TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
534 bool ipv4_supported = true;
535 bool ipv6_supported = true;
536 OverrideAddressSortingSourceAddrFactory(
537 ipv4_supported, ipv6_supported,
539 // Both of these destinations have the same precedence in default
542 {"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}},
543 {"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}},
545 auto lb_addrs = BuildLbAddrInputs({
546 {"[3ffe:5001::]:443", AF_INET6},
547 {"[3ffe:1234::]:443", AF_INET6},
549 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
550 VerifyLbAddrOutputs(lb_addrs, {
556 TEST_F(AddressSortingTest,
557 TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {
558 bool ipv4_supported = true;
559 bool ipv6_supported = true;
560 OverrideAddressSortingSourceAddrFactory(
561 ipv4_supported, ipv6_supported,
563 {"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}},
564 {"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}},
566 auto lb_addrs = BuildLbAddrInputs({
567 {"[3ffe::5001]:443", AF_INET6},
568 {"[3ffe::1234]:443", AF_INET6},
570 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
571 VerifyLbAddrOutputs(lb_addrs, {
577 TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
578 bool ipv4_supported = true;
579 bool ipv6_supported = true;
580 OverrideAddressSortingSourceAddrFactory(
581 ipv4_supported, ipv6_supported,
583 {"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}},
584 {"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}},
586 auto lb_addrs = BuildLbAddrInputs({
587 {"[3ffe:8000::]:443", AF_INET6},
588 {"[3ffe:2000::]:443", AF_INET6},
590 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
591 VerifyLbAddrOutputs(lb_addrs, {
597 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
598 bool ipv4_supported = true;
599 bool ipv6_supported = true;
600 OverrideAddressSortingSourceAddrFactory(
601 ipv4_supported, ipv6_supported,
603 {"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}},
604 {"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}},
606 auto lb_addrs = BuildLbAddrInputs({
607 {"[3ffe:6::]:443", AF_INET6},
608 {"[3ffe:c::]:443", AF_INET6},
610 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
611 VerifyLbAddrOutputs(lb_addrs, {
617 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
618 bool ipv4_supported = true;
619 bool ipv6_supported = true;
620 OverrideAddressSortingSourceAddrFactory(
621 ipv4_supported, ipv6_supported,
623 {"[3ffe:1111:1111:1111::]:443",
624 {"[3ffe:1111:1111:1111::]:0", AF_INET6}},
625 {"[3ffe:1111:1111:1110::]:443",
626 {"[3ffe:1111:1111:1111::]:0", AF_INET6}},
628 auto lb_addrs = BuildLbAddrInputs({
629 {"[3ffe:1111:1111:1110::]:443", AF_INET6},
630 {"[3ffe:1111:1111:1111::]:443", AF_INET6},
632 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
633 VerifyLbAddrOutputs(lb_addrs, {
634 "[3ffe:1111:1111:1111::]:443",
635 "[3ffe:1111:1111:1110::]:443",
639 /* Tests for rule 10 */
641 TEST_F(AddressSortingTest, TestStableSort) {
642 bool ipv4_supported = true;
643 bool ipv6_supported = true;
644 OverrideAddressSortingSourceAddrFactory(
645 ipv4_supported, ipv6_supported,
647 {"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}},
648 {"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}},
650 auto lb_addrs = BuildLbAddrInputs({
651 {"[3ffe::1234]:443", AF_INET6},
652 {"[3ffe::1235]:443", AF_INET6},
654 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
655 VerifyLbAddrOutputs(lb_addrs, {
661 TEST_F(AddressSortingTest, TestStableSortFiveElements) {
662 bool ipv4_supported = true;
663 bool ipv6_supported = true;
664 OverrideAddressSortingSourceAddrFactory(
665 ipv4_supported, ipv6_supported,
667 {"[3ffe::1231]:443", {"[3ffe::1201]:0", AF_INET6}},
668 {"[3ffe::1232]:443", {"[3ffe::1202]:0", AF_INET6}},
669 {"[3ffe::1233]:443", {"[3ffe::1203]:0", AF_INET6}},
670 {"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}},
671 {"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}},
673 auto lb_addrs = BuildLbAddrInputs({
674 {"[3ffe::1231]:443", AF_INET6},
675 {"[3ffe::1232]:443", AF_INET6},
676 {"[3ffe::1233]:443", AF_INET6},
677 {"[3ffe::1234]:443", AF_INET6},
678 {"[3ffe::1235]:443", AF_INET6},
680 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
681 VerifyLbAddrOutputs(lb_addrs, {
690 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
691 bool ipv4_supported = true;
692 bool ipv6_supported = true;
693 OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
694 auto lb_addrs = BuildLbAddrInputs({
695 {"[3ffe::1231]:443", AF_INET6},
696 {"[3ffe::1232]:443", AF_INET6},
697 {"[3ffe::1233]:443", AF_INET6},
698 {"[3ffe::1234]:443", AF_INET6},
699 {"[3ffe::1235]:443", AF_INET6},
701 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
702 VerifyLbAddrOutputs(lb_addrs, {
711 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
712 bool ipv4_supported = true;
713 bool ipv6_supported = true;
714 OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
715 auto lb_addrs = BuildLbAddrInputs({
716 {"[::ffff:5.6.7.8]:443", AF_INET6},
717 {"1.2.3.4:443", AF_INET},
719 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
720 VerifyLbAddrOutputs(lb_addrs, {
721 "[::ffff:5.6.7.8]:443",
726 TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
727 bool ipv4_supported = true;
728 bool ipv6_supported = true;
729 // Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
731 const char* v4_compat_dest = "[::0.0.0.2]:443";
732 const char* v4_compat_src = "[::0.0.0.3]:0";
734 const char* v4_compat_dest = "[::2]:443";
735 const char* v4_compat_src = "[::3]:0";
737 OverrideAddressSortingSourceAddrFactory(
738 ipv4_supported, ipv6_supported,
740 {"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}},
741 {v4_compat_dest, {v4_compat_src, AF_INET6}},
743 auto lb_addrs = BuildLbAddrInputs({
744 {"[fec0::2000]:443", AF_INET6},
745 {v4_compat_dest, AF_INET6},
747 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
748 VerifyLbAddrOutputs(lb_addrs,
750 // The sort should be stable since
751 // v4-compatible has same precedence as site-local.
757 /* TestPrefersIpv6Loopback tests the actual "address probing" code
758 * for the current platform, without any mocks.
759 * This test relies on the assumption that the ipv6 loopback address is
760 * available in the hosts/containers that grpc C/C++ tests run on
761 * (whether ipv4 loopback is available or not, an available ipv6
762 * loopback should be preferred). */
763 TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
764 auto lb_addrs = BuildLbAddrInputs({
765 {"[::1]:443", AF_INET6},
766 {"127.0.0.1:443", AF_INET},
768 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
769 VerifyLbAddrOutputs(lb_addrs, {
775 /* Flip the order of the inputs above and expect the same output order
776 * (try to rule out influence of arbitrary qsort ordering) */
777 TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
778 auto lb_addrs = BuildLbAddrInputs({
779 {"127.0.0.1:443", AF_INET},
780 {"[::1]:443", AF_INET6},
782 grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
783 VerifyLbAddrOutputs(lb_addrs, {
789 /* Try to rule out false positives in the above two tests in which
790 * the sorter might think that neither ipv6 or ipv4 loopback is
791 * available, but ipv6 loopback is still preferred only due
792 * to precedence table lookups. */
793 TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {
794 sockaddr_in6 ipv6_loopback;
795 memset(&ipv6_loopback, 0, sizeof(ipv6_loopback));
796 ipv6_loopback.sin6_family = AF_INET6;
797 ((char*)&ipv6_loopback.sin6_addr)[15] = 1;
798 ipv6_loopback.sin6_port = htons(443);
799 // Set up the source and destination parameters of
800 // address_sorting_get_source_addr
801 address_sorting_address sort_input_dest;
802 memcpy(&sort_input_dest.addr, &ipv6_loopback, sizeof(ipv6_loopback));
803 sort_input_dest.len = sizeof(ipv6_loopback);
804 address_sorting_address source_for_sort_input_dest;
805 memset(&source_for_sort_input_dest, 0, sizeof(source_for_sort_input_dest));
806 // address_sorting_get_source_addr returns true if a source address was found
807 // for the destination address, otherwise false.
808 EXPECT_TRUE(address_sorting_get_source_addr_for_testing(
809 &sort_input_dest, &source_for_sort_input_dest));
810 // Now also check that the source address was filled in correctly.
811 EXPECT_GT(source_for_sort_input_dest.len, 0u);
812 sockaddr_in6* source_addr_output =
813 (sockaddr_in6*)source_for_sort_input_dest.addr;
814 EXPECT_EQ(source_addr_output->sin6_family, AF_INET6);
815 char* buf = static_cast<char*>(gpr_zalloc(100));
816 EXPECT_NE(inet_ntop(AF_INET6, &source_addr_output->sin6_addr, buf, 100),
818 << "inet_ntop failed. Errno: " + std::to_string(errno);
819 std::string source_addr_str(buf);
822 // assumes that the source address for any loopback destination is also the
824 EXPECT_EQ(source_addr_str, "::1");
829 int main(int argc, char** argv) {
830 grpc_core::UniquePtr<char> resolver =
831 GPR_GLOBAL_CONFIG_GET(grpc_dns_resolver);
832 if (strlen(resolver.get()) == 0) {
833 GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, "ares");
834 } else if (strcmp("ares", resolver.get())) {
835 gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver.get());
837 grpc::testing::TestEnvironment env(argc, argv);
838 ::testing::InitGoogleTest(&argc, argv);
839 auto result = RUN_ALL_TESTS();
840 // Test sequential and nested inits and shutdowns.