20 #include <sys/types.h>
25 #include <gmock/gmock.h>
54 #include <arpa/inet.h>
55 #include <netinet/in.h>
56 #include <sys/socket.h>
71 if (test_addr.family == AF_INET) {
73 memset(&in_dest, 0,
sizeof(sockaddr_in));
74 in_dest.sin_port = htons(atoi(
port.c_str()));
75 in_dest.sin_family = AF_INET;
76 GPR_ASSERT(inet_pton(AF_INET, host.c_str(), &in_dest.sin_addr) == 1);
77 memcpy(&resolved_addr.
addr, &in_dest,
sizeof(sockaddr_in));
78 resolved_addr.
len =
sizeof(sockaddr_in);
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) {}
112 memcpy(&dest_addr_as_resolved_addr.
addr, dest_addr, dest_addr->
len);
113 dest_addr_as_resolved_addr.
len = dest_addr->
len;
118 auto it = dest_addr_to_src_addr_.find(ip_addr_str);
119 if (
it == dest_addr_to_src_addr_.end()) {
121 ip_addr_str.c_str());
125 TestAddressToGrpcResolvedAddress(
it->second);
127 source_addr_as_resolved_addr.
len);
128 source_addr->
len = source_addr_as_resolved_addr.
len;
134 bool ipv4_supported_;
135 bool ipv6_supported_;
136 std::map<std::string, TestAddress> dest_addr_to_src_addr_;
139 bool mock_source_addr_factory_wrapper_get_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(
150 MockSourceAddrFactory* mock =
151 reinterpret_cast<MockSourceAddrFactory*
>(factory);
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) {
165 ipv4_supported, ipv6_supported, dest_addr_to_src_addr);
166 factory->
vtable = &kMockSourceAddrFactoryVtable;
171 const std::vector<TestAddress>& test_addrs) {
173 for (
const auto&
addr : test_addrs) {
174 addresses.emplace_back(TestAddressToGrpcResolvedAddress(
addr),
nullptr);
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) {
201 TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
202 bool ipv4_supported =
true;
203 bool ipv6_supported =
true;
204 OverrideAddressSortingSourceAddrFactory(
205 ipv4_supported, ipv6_supported,
207 {
"1.2.3.4:443", {
"4.3.2.1:443", AF_INET}},
209 auto lb_addrs = BuildLbAddrInputs({
210 {
"1.2.3.4:443", AF_INET},
211 {
"5.6.7.8:443", AF_INET},
214 VerifyLbAddrOutputs(lb_addrs, {
220 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
221 bool ipv4_supported =
true;
222 bool ipv6_supported =
false;
223 OverrideAddressSortingSourceAddrFactory(
224 ipv4_supported, ipv6_supported,
226 {
"1.2.3.4:443", {
"4.3.2.1:0", AF_INET}},
228 auto lb_addrs = BuildLbAddrInputs({
229 {
"[2607:f8b0:400a:801::1002]:443",
AF_INET6},
230 {
"1.2.3.4:443", AF_INET},
233 VerifyLbAddrOutputs(lb_addrs, {
235 "[2607:f8b0:400a:801::1002]:443",
239 TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
240 bool ipv4_supported =
false;
241 bool ipv6_supported =
true;
242 OverrideAddressSortingSourceAddrFactory(
243 ipv4_supported, ipv6_supported,
245 {
"1.2.3.4:443", {
"4.3.2.1:0", AF_INET}},
246 {
"[2607:f8b0:400a:801::1002]:443", {
"[fec0::1234]:0",
AF_INET6}},
248 auto lb_addrs = BuildLbAddrInputs({
249 {
"[2607:f8b0:400a:801::1002]:443",
AF_INET6},
250 {
"1.2.3.4:443", AF_INET},
253 VerifyLbAddrOutputs(lb_addrs, {
254 "[2607:f8b0:400a:801::1002]:443",
261 TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
262 bool ipv4_supported =
true;
263 bool ipv6_supported =
true;
264 OverrideAddressSortingSourceAddrFactory(
265 ipv4_supported, ipv6_supported,
267 {
"[2000:f8b0:400a:801::1002]:443",
272 auto lb_addrs = BuildLbAddrInputs({
273 {
"[2000:f8b0:400a:801::1002]:443",
AF_INET6},
277 VerifyLbAddrOutputs(lb_addrs, {
279 "[2000:f8b0:400a:801::1002]:443",
285 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
286 bool ipv4_supported =
true;
287 bool ipv6_supported =
true;
288 OverrideAddressSortingSourceAddrFactory(
289 ipv4_supported, ipv6_supported,
291 {
"[2002::5001]:443", {
"[2001::5002]:0",
AF_INET6}},
295 auto lb_addrs = BuildLbAddrInputs({
300 VerifyLbAddrOutputs(lb_addrs, {
308 TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
309 bool ipv4_supported =
true;
310 bool ipv6_supported =
true;
311 OverrideAddressSortingSourceAddrFactory(
312 ipv4_supported, ipv6_supported,
314 {
"[2002::5001]:443", {
"[2001::5002]:0",
AF_INET6}},
318 auto lb_addrs = BuildLbAddrInputs({
323 VerifyLbAddrOutputs(lb_addrs, {
331 TEST_F(AddressSortingTest,
332 TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {
333 bool ipv4_supported =
true;
334 bool ipv6_supported =
true;
335 OverrideAddressSortingSourceAddrFactory(
336 ipv4_supported, ipv6_supported,
338 {
"[3ffe::5001]:443", {
"[3ffe::5002]:0",
AF_INET6}},
339 {
"1.2.3.4:443", {
"5.6.7.8:0", AF_INET}},
341 auto lb_addrs = BuildLbAddrInputs({
343 {
"1.2.3.4:443", AF_INET},
356 TEST_F(AddressSortingTest,
357 TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) {
358 bool ipv4_supported =
true;
359 bool ipv6_supported =
true;
360 const char* v4_compat_dest =
"[::2]:443";
361 const char* v4_compat_src =
"[::2]:0";
362 OverrideAddressSortingSourceAddrFactory(
363 ipv4_supported, ipv6_supported,
365 {
"[::1]:443", {
"[::1]:0",
AF_INET6}},
366 {v4_compat_dest, {v4_compat_src,
AF_INET6}},
368 auto lb_addrs = BuildLbAddrInputs({
382 std::vector<std::string> acceptable_addresses = {
387 acceptable_addresses,
393 TEST_F(AddressSortingTest,
394 TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
395 bool ipv4_supported =
true;
396 bool ipv6_supported =
true;
397 OverrideAddressSortingSourceAddrFactory(
398 ipv4_supported, ipv6_supported,
402 {
"[1234::2]:443", {
"[1234::2]:0",
AF_INET6}},
403 {
"[::1]:443", {
"[::1]:0",
AF_INET6}},
405 auto lb_addrs = BuildLbAddrInputs({
419 TEST_F(AddressSortingTest,
420 TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
421 bool ipv4_supported =
true;
422 bool ipv6_supported =
true;
423 OverrideAddressSortingSourceAddrFactory(
424 ipv4_supported, ipv6_supported,
426 {
"[2001::1234]:443", {
"[2001::5678]:0",
AF_INET6}},
427 {
"[2000::5001]:443", {
"[2000::5002]:0",
AF_INET6}},
429 auto lb_addrs = BuildLbAddrInputs({
444 TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) {
445 bool ipv4_supported =
true;
446 bool ipv6_supported =
true;
447 OverrideAddressSortingSourceAddrFactory(
448 ipv4_supported, ipv6_supported,
450 {
"[2001::1231]:443", {
"[2001::1232]:0",
AF_INET6}},
451 {
"[2000::5001]:443", {
"[2000::5002]:0",
AF_INET6}},
453 auto lb_addrs = BuildLbAddrInputs({
458 VerifyLbAddrOutputs(lb_addrs, {
464 TEST_F(AddressSortingTest,
465 TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {
466 bool ipv4_supported =
true;
467 bool ipv6_supported =
true;
468 OverrideAddressSortingSourceAddrFactory(
469 ipv4_supported, ipv6_supported,
471 {
"[fec0::1234]:443", {
"[fec0::5678]:0",
AF_INET6}},
472 {
"[fc00::5001]:443", {
"[fc00::5002]:0",
AF_INET6}},
474 auto lb_addrs = BuildLbAddrInputs({
479 VerifyLbAddrOutputs(lb_addrs, {
487 TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) {
488 bool ipv4_supported =
true;
489 bool ipv6_supported =
true;
493 OverrideAddressSortingSourceAddrFactory(
494 ipv4_supported, ipv6_supported,
496 {
"[::ffff:1.1.1.2]:443", {
"[::ffff:1.1.1.3]:0",
AF_INET6}},
497 {
"[1234::2]:443", {
"[1234::3]:0",
AF_INET6}},
499 auto lb_addrs = BuildLbAddrInputs({
504 VerifyLbAddrOutputs(lb_addrs, {
508 "[::ffff:1.1.1.2]:443",
514 TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
515 bool ipv4_supported =
true;
516 bool ipv6_supported =
true;
517 OverrideAddressSortingSourceAddrFactory(
518 ipv4_supported, ipv6_supported,
523 {
"[fec0::1234]:443", {
"[fec0::5678]:0",
AF_INET6}},
524 {
"[3ffe::5001]:443", {
"[3ffe::5002]:0",
AF_INET6}},
526 auto lb_addrs = BuildLbAddrInputs({
531 VerifyLbAddrOutputs(lb_addrs, {
539 TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
540 bool ipv4_supported =
true;
541 bool ipv6_supported =
true;
542 OverrideAddressSortingSourceAddrFactory(
543 ipv4_supported, ipv6_supported,
548 {
"[3ffe:1234::]:443", {
"[3ffe:1235::]:0",
AF_INET6}},
549 {
"[3ffe:5001::]:443", {
"[3ffe:4321::]:0",
AF_INET6}},
551 auto lb_addrs = BuildLbAddrInputs({
556 VerifyLbAddrOutputs(lb_addrs, {
562 TEST_F(AddressSortingTest,
563 TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {
564 bool ipv4_supported =
true;
565 bool ipv6_supported =
true;
566 OverrideAddressSortingSourceAddrFactory(
567 ipv4_supported, ipv6_supported,
569 {
"[3ffe::1234]:443", {
"[3ffe::1235]:0",
AF_INET6}},
570 {
"[3ffe::5001]:443", {
"[3ffe::4321]:0",
AF_INET6}},
572 auto lb_addrs = BuildLbAddrInputs({
577 VerifyLbAddrOutputs(lb_addrs, {
583 TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
584 bool ipv4_supported =
true;
585 bool ipv6_supported =
true;
586 OverrideAddressSortingSourceAddrFactory(
587 ipv4_supported, ipv6_supported,
589 {
"[3ffe:8000::]:443", {
"[3ffe:C000::]:0",
AF_INET6}},
590 {
"[3ffe:2000::]:443", {
"[3ffe:3000::]:0",
AF_INET6}},
592 auto lb_addrs = BuildLbAddrInputs({
597 VerifyLbAddrOutputs(lb_addrs, {
603 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
604 bool ipv4_supported =
true;
605 bool ipv6_supported =
true;
606 OverrideAddressSortingSourceAddrFactory(
607 ipv4_supported, ipv6_supported,
609 {
"[3ffe:6::]:443", {
"[3ffe:8::]:0",
AF_INET6}},
610 {
"[3ffe:c::]:443", {
"[3ffe:8::]:0",
AF_INET6}},
612 auto lb_addrs = BuildLbAddrInputs({
617 VerifyLbAddrOutputs(lb_addrs, {
623 TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
624 bool ipv4_supported =
true;
625 bool ipv6_supported =
true;
626 OverrideAddressSortingSourceAddrFactory(
627 ipv4_supported, ipv6_supported,
629 {
"[3ffe:1111:1111:1111::]:443",
630 {
"[3ffe:1111:1111:1111::]:0",
AF_INET6}},
631 {
"[3ffe:1111:1111:1110::]:443",
632 {
"[3ffe:1111:1111:1111::]:0",
AF_INET6}},
634 auto lb_addrs = BuildLbAddrInputs({
635 {
"[3ffe:1111:1111:1110::]:443",
AF_INET6},
636 {
"[3ffe:1111:1111:1111::]:443",
AF_INET6},
639 VerifyLbAddrOutputs(lb_addrs, {
640 "[3ffe:1111:1111:1111::]:443",
641 "[3ffe:1111:1111:1110::]:443",
647 TEST_F(AddressSortingTest, TestStableSort) {
648 bool ipv4_supported =
true;
649 bool ipv6_supported =
true;
650 OverrideAddressSortingSourceAddrFactory(
651 ipv4_supported, ipv6_supported,
653 {
"[3ffe::1234]:443", {
"[3ffe::1236]:0",
AF_INET6}},
654 {
"[3ffe::1235]:443", {
"[3ffe::1237]:0",
AF_INET6}},
656 auto lb_addrs = BuildLbAddrInputs({
661 VerifyLbAddrOutputs(lb_addrs, {
667 TEST_F(AddressSortingTest, TestStableSortFiveElements) {
668 bool ipv4_supported =
true;
669 bool ipv6_supported =
true;
670 OverrideAddressSortingSourceAddrFactory(
671 ipv4_supported, ipv6_supported,
673 {
"[3ffe::1231]:443", {
"[3ffe::1201]:0",
AF_INET6}},
674 {
"[3ffe::1232]:443", {
"[3ffe::1202]:0",
AF_INET6}},
675 {
"[3ffe::1233]:443", {
"[3ffe::1203]:0",
AF_INET6}},
676 {
"[3ffe::1234]:443", {
"[3ffe::1204]:0",
AF_INET6}},
677 {
"[3ffe::1235]:443", {
"[3ffe::1205]:0",
AF_INET6}},
679 auto lb_addrs = BuildLbAddrInputs({
687 VerifyLbAddrOutputs(lb_addrs, {
696 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
697 bool ipv4_supported =
true;
698 bool ipv6_supported =
true;
699 OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
700 auto lb_addrs = BuildLbAddrInputs({
708 VerifyLbAddrOutputs(lb_addrs, {
717 TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
718 bool ipv4_supported =
true;
719 bool ipv6_supported =
true;
720 OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
721 auto lb_addrs = BuildLbAddrInputs({
723 {
"1.2.3.4:443", AF_INET},
726 VerifyLbAddrOutputs(lb_addrs, {
727 "[::ffff:5.6.7.8]:443",
732 TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
733 bool ipv4_supported =
true;
734 bool ipv6_supported =
true;
735 const char* v4_compat_dest =
"[::2]:443";
736 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({
759 std::vector<std::string> acceptable_addresses = {
764 acceptable_addresses,
776 TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
777 auto lb_addrs = BuildLbAddrInputs({
779 {
"127.0.0.1:443", AF_INET},
782 VerifyLbAddrOutputs(lb_addrs, {
790 TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
791 auto lb_addrs = BuildLbAddrInputs({
792 {
"127.0.0.1:443", AF_INET},
796 VerifyLbAddrOutputs(lb_addrs, {
806 TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {
808 memset(&ipv6_loopback, 0,
sizeof(ipv6_loopback));
810 (
reinterpret_cast<char*
>(&ipv6_loopback.
sin6_addr))[15] = 1;
815 memcpy(&sort_input_dest.
addr, &ipv6_loopback,
sizeof(ipv6_loopback));
816 sort_input_dest.
len =
sizeof(ipv6_loopback);
818 memset(&source_for_sort_input_dest, 0,
sizeof(source_for_sort_input_dest));
822 &sort_input_dest, &source_for_sort_input_dest));
842 int main(
int argc,
char** argv) {
845 if (strlen(resolver.get()) == 0) {
847 }
else if (strcmp(
"ares", resolver.get()) != 0) {