resolve_address_test.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /*
  2. *
  3. * Copyright 2015 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 "src/core/lib/iomgr/resolve_address.h"
  19. #include <string.h>
  20. #include <address_sorting/address_sorting.h>
  21. #include <gmock/gmock.h>
  22. #include <gtest/gtest.h>
  23. #include "absl/functional/bind_front.h"
  24. #include "absl/strings/match.h"
  25. #include <grpc/grpc.h>
  26. #include <grpc/support/alloc.h>
  27. #include <grpc/support/log.h>
  28. #include <grpc/support/sync.h>
  29. #include <grpc/support/time.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/event_engine/sockaddr.h"
  33. #include "src/core/lib/gpr/string.h"
  34. #include "src/core/lib/gprpp/sync.h"
  35. #include "src/core/lib/gprpp/time.h"
  36. #include "src/core/lib/iomgr/executor.h"
  37. #include "src/core/lib/iomgr/iomgr.h"
  38. #include "test/core/util/cmdline.h"
  39. #include "test/core/util/fake_udp_and_tcp_server.h"
  40. #include "test/core/util/test_config.h"
  41. #include "test/cpp/util/test_config.h"
  42. namespace {
  43. grpc_core::Timestamp NSecDeadline(int seconds) {
  44. return grpc_core::Timestamp::FromTimespecRoundUp(
  45. grpc_timeout_seconds_to_deadline(seconds));
  46. }
  47. const char* g_resolver_type = "";
  48. class ResolveAddressTest : public ::testing::Test {
  49. public:
  50. ResolveAddressTest() {
  51. grpc_init();
  52. grpc_core::ExecCtx exec_ctx;
  53. pollset_ = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
  54. grpc_pollset_init(pollset_, &mu_);
  55. pollset_set_ = grpc_pollset_set_create();
  56. grpc_pollset_set_add_pollset(pollset_set_, pollset_);
  57. default_inject_config_ = grpc_ares_test_only_inject_config;
  58. }
  59. ~ResolveAddressTest() override {
  60. {
  61. grpc_core::ExecCtx exec_ctx;
  62. grpc_pollset_set_del_pollset(pollset_set_, pollset_);
  63. grpc_pollset_set_destroy(pollset_set_);
  64. grpc_closure do_nothing_cb;
  65. GRPC_CLOSURE_INIT(&do_nothing_cb, DoNothing, nullptr,
  66. grpc_schedule_on_exec_ctx);
  67. gpr_mu_lock(mu_);
  68. grpc_pollset_shutdown(pollset_, &do_nothing_cb);
  69. gpr_mu_unlock(mu_);
  70. // exec_ctx needs to be flushed before calling grpc_pollset_destroy()
  71. grpc_core::ExecCtx::Get()->Flush();
  72. grpc_pollset_destroy(pollset_);
  73. gpr_free(pollset_);
  74. // reset this since it might have been altered
  75. grpc_ares_test_only_inject_config = default_inject_config_;
  76. }
  77. grpc_shutdown();
  78. }
  79. void PollPollsetUntilRequestDone() {
  80. // Try to give enough time for c-ares to run through its retries
  81. // a few times if needed.
  82. grpc_core::Timestamp deadline = NSecDeadline(90);
  83. while (true) {
  84. grpc_core::ExecCtx exec_ctx;
  85. {
  86. grpc_core::MutexLockForGprMu lock(mu_);
  87. if (done_) {
  88. break;
  89. }
  90. grpc_core::Duration time_left =
  91. deadline - grpc_core::ExecCtx::Get()->Now();
  92. gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64, done_,
  93. time_left.millis());
  94. ASSERT_GE(time_left, grpc_core::Duration::Zero());
  95. grpc_pollset_worker* worker = nullptr;
  96. GRPC_LOG_IF_ERROR("pollset_work", grpc_pollset_work(pollset_, &worker,
  97. NSecDeadline(1)));
  98. }
  99. }
  100. }
  101. void MustSucceed(absl::StatusOr<std::vector<grpc_resolved_address>> result) {
  102. EXPECT_EQ(result.status(), absl::OkStatus());
  103. EXPECT_FALSE(result->empty());
  104. Finish();
  105. }
  106. void MustFail(absl::StatusOr<std::vector<grpc_resolved_address>> result) {
  107. EXPECT_NE(result.status(), absl::OkStatus());
  108. Finish();
  109. }
  110. void MustFailExpectCancelledErrorMessage(
  111. absl::StatusOr<std::vector<grpc_resolved_address>> result) {
  112. EXPECT_NE(result.status(), absl::OkStatus());
  113. EXPECT_THAT(result.status().ToString(),
  114. testing::HasSubstr("DNS query cancelled"));
  115. Finish();
  116. }
  117. void DontCare(
  118. absl::StatusOr<std::vector<grpc_resolved_address>> /* result */) {
  119. Finish();
  120. }
  121. // This test assumes the environment has an ipv6 loopback
  122. void MustSucceedWithIPv6First(
  123. absl::StatusOr<std::vector<grpc_resolved_address>> result) {
  124. EXPECT_EQ(result.status(), absl::OkStatus());
  125. EXPECT_TRUE(!result->empty() &&
  126. reinterpret_cast<const struct sockaddr*>((*result)[0].addr)
  127. ->sa_family == AF_INET6);
  128. Finish();
  129. }
  130. void MustSucceedWithIPv4First(
  131. absl::StatusOr<std::vector<grpc_resolved_address>> result) {
  132. EXPECT_EQ(result.status(), absl::OkStatus());
  133. EXPECT_TRUE(!result->empty() &&
  134. reinterpret_cast<const struct sockaddr*>((*result)[0].addr)
  135. ->sa_family == AF_INET);
  136. Finish();
  137. }
  138. grpc_pollset_set* pollset_set() const { return pollset_set_; }
  139. private:
  140. static void DoNothing(void* /*arg*/, grpc_error_handle /*error*/) {}
  141. void Finish() {
  142. grpc_core::MutexLockForGprMu lock(mu_);
  143. done_ = true;
  144. GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(pollset_, nullptr));
  145. }
  146. gpr_mu* mu_;
  147. bool done_ = false; // guarded by mu
  148. grpc_pollset* pollset_; // guarded by mu
  149. grpc_pollset_set* pollset_set_;
  150. // the default value of grpc_ares_test_only_inject_config, which might
  151. // be modified during a test
  152. void (*default_inject_config_)(ares_channel channel) = nullptr;
  153. };
  154. } // namespace
  155. TEST_F(ResolveAddressTest, Localhost) {
  156. grpc_core::ExecCtx exec_ctx;
  157. auto r = grpc_core::GetDNSResolver()->ResolveName(
  158. "localhost:1", "", pollset_set(),
  159. absl::bind_front(&ResolveAddressTest::MustSucceed, this));
  160. r->Start();
  161. grpc_core::ExecCtx::Get()->Flush();
  162. PollPollsetUntilRequestDone();
  163. }
  164. TEST_F(ResolveAddressTest, DefaultPort) {
  165. grpc_core::ExecCtx exec_ctx;
  166. auto r = grpc_core::GetDNSResolver()->ResolveName(
  167. "localhost", "1", pollset_set(),
  168. absl::bind_front(&ResolveAddressTest::MustSucceed, this));
  169. r->Start();
  170. grpc_core::ExecCtx::Get()->Flush();
  171. PollPollsetUntilRequestDone();
  172. }
  173. TEST_F(ResolveAddressTest, LocalhostResultHasIPv6First) {
  174. if (std::string(g_resolver_type) != "ares") {
  175. GTEST_SKIP() << "this test is only valid with the c-ares resolver";
  176. }
  177. grpc_core::ExecCtx exec_ctx;
  178. auto r = grpc_core::GetDNSResolver()->ResolveName(
  179. "localhost:1", "", pollset_set(),
  180. absl::bind_front(&ResolveAddressTest::MustSucceedWithIPv6First, this));
  181. r->Start();
  182. grpc_core::ExecCtx::Get()->Flush();
  183. PollPollsetUntilRequestDone();
  184. }
  185. namespace {
  186. bool IPv6DisabledGetSourceAddr(address_sorting_source_addr_factory* /*factory*/,
  187. const address_sorting_address* dest_addr,
  188. address_sorting_address* source_addr) {
  189. // Mock lack of IPv6. For IPv4, set the source addr to be the same
  190. // as the destination; tests won't actually connect on the result anyways.
  191. if (address_sorting_abstract_get_family(dest_addr) ==
  192. ADDRESS_SORTING_AF_INET6) {
  193. return false;
  194. }
  195. memcpy(source_addr->addr, &dest_addr->addr, dest_addr->len);
  196. source_addr->len = dest_addr->len;
  197. return true;
  198. }
  199. void DeleteSourceAddrFactory(address_sorting_source_addr_factory* factory) {
  200. delete factory;
  201. }
  202. const address_sorting_source_addr_factory_vtable
  203. kMockIpv6DisabledSourceAddrFactoryVtable = {
  204. IPv6DisabledGetSourceAddr,
  205. DeleteSourceAddrFactory,
  206. };
  207. } // namespace
  208. TEST_F(ResolveAddressTest, LocalhostResultHasIPv4FirstWhenIPv6IsntAvalailable) {
  209. if (std::string(g_resolver_type) != "ares") {
  210. GTEST_SKIP() << "this test is only valid with the c-ares resolver";
  211. }
  212. // Mock the kernel source address selection. Note that source addr factory
  213. // is reset to its default value during grpc initialization for each test.
  214. address_sorting_source_addr_factory* mock =
  215. new address_sorting_source_addr_factory();
  216. mock->vtable = &kMockIpv6DisabledSourceAddrFactoryVtable;
  217. address_sorting_override_source_addr_factory_for_testing(mock);
  218. // run the test
  219. grpc_core::ExecCtx exec_ctx;
  220. auto r = grpc_core::GetDNSResolver()->ResolveName(
  221. "localhost:1", "", pollset_set(),
  222. absl::bind_front(&ResolveAddressTest::MustSucceedWithIPv4First, this));
  223. r->Start();
  224. grpc_core::ExecCtx::Get()->Flush();
  225. PollPollsetUntilRequestDone();
  226. }
  227. TEST_F(ResolveAddressTest, NonNumericDefaultPort) {
  228. grpc_core::ExecCtx exec_ctx;
  229. auto r = grpc_core::GetDNSResolver()->ResolveName(
  230. "localhost", "http", pollset_set(),
  231. absl::bind_front(&ResolveAddressTest::MustSucceed, this));
  232. r->Start();
  233. grpc_core::ExecCtx::Get()->Flush();
  234. PollPollsetUntilRequestDone();
  235. }
  236. TEST_F(ResolveAddressTest, MissingDefaultPort) {
  237. grpc_core::ExecCtx exec_ctx;
  238. auto r = grpc_core::GetDNSResolver()->ResolveName(
  239. "localhost", "", pollset_set(),
  240. absl::bind_front(&ResolveAddressTest::MustFail, this));
  241. r->Start();
  242. grpc_core::ExecCtx::Get()->Flush();
  243. PollPollsetUntilRequestDone();
  244. }
  245. TEST_F(ResolveAddressTest, IPv6WithPort) {
  246. grpc_core::ExecCtx exec_ctx;
  247. auto r = grpc_core::GetDNSResolver()->ResolveName(
  248. "[2001:db8::1]:1", "", pollset_set(),
  249. absl::bind_front(&ResolveAddressTest::MustSucceed, this));
  250. r->Start();
  251. grpc_core::ExecCtx::Get()->Flush();
  252. PollPollsetUntilRequestDone();
  253. }
  254. void TestIPv6WithoutPort(ResolveAddressTest* test, const char* target) {
  255. grpc_core::ExecCtx exec_ctx;
  256. auto r = grpc_core::GetDNSResolver()->ResolveName(
  257. target, "80", test->pollset_set(),
  258. absl::bind_front(&ResolveAddressTest::MustSucceed, test));
  259. r->Start();
  260. grpc_core::ExecCtx::Get()->Flush();
  261. test->PollPollsetUntilRequestDone();
  262. }
  263. TEST_F(ResolveAddressTest, IPv6WithoutPortNoBrackets) {
  264. TestIPv6WithoutPort(this, "2001:db8::1");
  265. }
  266. TEST_F(ResolveAddressTest, IPv6WithoutPortWithBrackets) {
  267. TestIPv6WithoutPort(this, "[2001:db8::1]");
  268. }
  269. TEST_F(ResolveAddressTest, IPv6WithoutPortV4MappedV6) {
  270. TestIPv6WithoutPort(this, "2001:db8::1.2.3.4");
  271. }
  272. void TestInvalidIPAddress(ResolveAddressTest* test, const char* target) {
  273. grpc_core::ExecCtx exec_ctx;
  274. auto r = grpc_core::GetDNSResolver()->ResolveName(
  275. target, "", test->pollset_set(),
  276. absl::bind_front(&ResolveAddressTest::MustFail, test));
  277. r->Start();
  278. grpc_core::ExecCtx::Get()->Flush();
  279. test->PollPollsetUntilRequestDone();
  280. }
  281. TEST_F(ResolveAddressTest, InvalidIPv4Addresses) {
  282. TestInvalidIPAddress(this, "293.283.1238.3:1");
  283. }
  284. TEST_F(ResolveAddressTest, InvalidIPv6Addresses) {
  285. TestInvalidIPAddress(this, "[2001:db8::11111]:1");
  286. }
  287. void TestUnparseableHostPort(ResolveAddressTest* test, const char* target) {
  288. grpc_core::ExecCtx exec_ctx;
  289. auto r = grpc_core::GetDNSResolver()->ResolveName(
  290. target, "1", test->pollset_set(),
  291. absl::bind_front(&ResolveAddressTest::MustFail, test));
  292. r->Start();
  293. grpc_core::ExecCtx::Get()->Flush();
  294. test->PollPollsetUntilRequestDone();
  295. }
  296. TEST_F(ResolveAddressTest, UnparseableHostPortsOnlyBracket) {
  297. TestUnparseableHostPort(this, "[");
  298. }
  299. TEST_F(ResolveAddressTest, UnparseableHostPortsMissingRightBracket) {
  300. TestUnparseableHostPort(this, "[::1");
  301. }
  302. TEST_F(ResolveAddressTest, UnparseableHostPortsBadPort) {
  303. TestUnparseableHostPort(this, "[::1]bad");
  304. }
  305. TEST_F(ResolveAddressTest, UnparseableHostPortsBadIPv6) {
  306. TestUnparseableHostPort(this, "[1.2.3.4]");
  307. }
  308. TEST_F(ResolveAddressTest, UnparseableHostPortsBadLocalhost) {
  309. TestUnparseableHostPort(this, "[localhost]");
  310. }
  311. TEST_F(ResolveAddressTest, UnparseableHostPortsBadLocalhostWithPort) {
  312. TestUnparseableHostPort(this, "[localhost]:1");
  313. }
  314. // Kick off a simple DNS resolution and then immediately cancel. This
  315. // test doesn't care what the result is, just that we don't crash etc.
  316. TEST_F(ResolveAddressTest, ImmediateCancel) {
  317. grpc_core::ExecCtx exec_ctx;
  318. auto r = grpc_core::GetDNSResolver()->ResolveName(
  319. "localhost:1", "1", pollset_set(),
  320. absl::bind_front(&ResolveAddressTest::DontCare, this));
  321. r->Start();
  322. r.reset(); // cancel the resolution
  323. grpc_core::ExecCtx::Get()->Flush();
  324. PollPollsetUntilRequestDone();
  325. }
  326. namespace {
  327. int g_fake_non_responsive_dns_server_port;
  328. void InjectNonResponsiveDNSServer(ares_channel channel) {
  329. gpr_log(GPR_DEBUG,
  330. "Injecting broken nameserver list. Bad server address:|[::1]:%d|.",
  331. g_fake_non_responsive_dns_server_port);
  332. // Configure a non-responsive DNS server at the front of c-ares's nameserver
  333. // list.
  334. struct ares_addr_port_node dns_server_addrs[1];
  335. memset(dns_server_addrs, 0, sizeof(dns_server_addrs));
  336. dns_server_addrs[0].family = AF_INET6;
  337. (reinterpret_cast<char*>(&dns_server_addrs[0].addr.addr6))[15] = 0x1;
  338. dns_server_addrs[0].tcp_port = g_fake_non_responsive_dns_server_port;
  339. dns_server_addrs[0].udp_port = g_fake_non_responsive_dns_server_port;
  340. dns_server_addrs[0].next = nullptr;
  341. ASSERT_EQ(ares_set_servers_ports(channel, dns_server_addrs), ARES_SUCCESS);
  342. }
  343. } // namespace
  344. TEST_F(ResolveAddressTest, CancelWithNonResponsiveDNSServer) {
  345. if (std::string(g_resolver_type) != "ares") {
  346. GTEST_SKIP() << "the native resolver doesn't support cancellation, so we "
  347. "can only test this with c-ares";
  348. }
  349. // Inject an unresponsive DNS server into the resolver's DNS server config
  350. grpc_core::testing::FakeUdpAndTcpServer fake_dns_server(
  351. grpc_core::testing::FakeUdpAndTcpServer::AcceptMode::
  352. kWaitForClientToSendFirstBytes,
  353. grpc_core::testing::FakeUdpAndTcpServer::CloseSocketUponCloseFromPeer);
  354. g_fake_non_responsive_dns_server_port = fake_dns_server.port();
  355. grpc_ares_test_only_inject_config = InjectNonResponsiveDNSServer;
  356. // Run the test
  357. grpc_core::ExecCtx exec_ctx;
  358. auto r = grpc_core::GetDNSResolver()->ResolveName(
  359. "foo.bar.com:1", "1", pollset_set(),
  360. absl::bind_front(&ResolveAddressTest::MustFailExpectCancelledErrorMessage,
  361. this));
  362. r->Start();
  363. grpc_core::ExecCtx::Get()->Flush(); // initiate DNS requests
  364. r.reset(); // cancel the resolution
  365. grpc_core::ExecCtx::Get()->Flush(); // let cancellation work finish
  366. PollPollsetUntilRequestDone();
  367. }
  368. int main(int argc, char** argv) {
  369. // Configure the DNS resolver (c-ares vs. native) based on the
  370. // name of the binary. TODO(apolcyn): is there a way to pass command
  371. // line flags to a gtest that it works in all of our test environments?
  372. if (absl::StrContains(std::string(argv[0]), "using_native_resolver")) {
  373. g_resolver_type = "native";
  374. } else if (absl::StrContains(std::string(argv[0]), "using_ares_resolver")) {
  375. g_resolver_type = "ares";
  376. } else {
  377. GPR_ASSERT(0);
  378. }
  379. GPR_GLOBAL_CONFIG_SET(grpc_dns_resolver, g_resolver_type);
  380. ::testing::InitGoogleTest(&argc, argv);
  381. grpc::testing::TestEnvironment env(argc, argv);
  382. const auto result = RUN_ALL_TESTS();
  383. return result;
  384. }