address_sorting_test.cc 30 KB

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