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