dns_config_service_posix_unittest.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/dns/dns_config_service_posix.h"
  5. #include <resolv.h>
  6. #include <memory>
  7. #include "base/bind.h"
  8. #include "base/cancelable_callback.h"
  9. #include "base/files/file_util.h"
  10. #include "base/run_loop.h"
  11. #include "base/sys_byteorder.h"
  12. #include "base/task/sequenced_task_runner.h"
  13. #include "base/task/task_traits.h"
  14. #include "base/task/thread_pool.h"
  15. #include "base/test/task_environment.h"
  16. #include "base/test/test_timeouts.h"
  17. #include "build/build_config.h"
  18. #include "net/base/ip_address.h"
  19. #include "net/dns/dns_config.h"
  20. #include "net/dns/public/dns_protocol.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. #include "third_party/abseil-cpp/absl/types/optional.h"
  23. #if BUILDFLAG(IS_ANDROID)
  24. #include "base/android/path_utils.h"
  25. #endif // BUILDFLAG(IS_ANDROID)
  26. // Required for inet_pton()
  27. #if BUILDFLAG(IS_WIN)
  28. #include <winsock2.h>
  29. #else
  30. #include <arpa/inet.h>
  31. #endif
  32. namespace net {
  33. namespace {
  34. // MAXNS is normally 3, but let's test 4 if possible.
  35. const char* const kNameserversIPv4[] = {
  36. "8.8.8.8",
  37. "192.168.1.1",
  38. "63.1.2.4",
  39. "1.0.0.1",
  40. };
  41. #if BUILDFLAG(IS_CHROMEOS)
  42. const char* const kNameserversIPv6[] = {
  43. nullptr,
  44. "2001:DB8:0::42",
  45. nullptr,
  46. "::FFFF:129.144.52.38",
  47. };
  48. #endif
  49. void DummyConfigCallback(const DnsConfig& config) {
  50. // Do nothing
  51. }
  52. // Fills in |res| with sane configuration.
  53. void InitializeResState(res_state res) {
  54. memset(res, 0, sizeof(*res));
  55. res->options = RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH |
  56. RES_ROTATE;
  57. res->ndots = 2;
  58. res->retrans = 4;
  59. res->retry = 7;
  60. const char kDnsrch[] = "chromium.org" "\0" "example.com";
  61. memcpy(res->defdname, kDnsrch, sizeof(kDnsrch));
  62. res->dnsrch[0] = res->defdname;
  63. res->dnsrch[1] = res->defdname + sizeof("chromium.org");
  64. for (unsigned i = 0; i < std::size(kNameserversIPv4) && i < MAXNS; ++i) {
  65. struct sockaddr_in sa;
  66. sa.sin_family = AF_INET;
  67. sa.sin_port = base::HostToNet16(NS_DEFAULTPORT + i);
  68. inet_pton(AF_INET, kNameserversIPv4[i], &sa.sin_addr);
  69. res->nsaddr_list[i] = sa;
  70. ++res->nscount;
  71. }
  72. #if BUILDFLAG(IS_CHROMEOS)
  73. // Install IPv6 addresses, replacing the corresponding IPv4 addresses.
  74. unsigned nscount6 = 0;
  75. for (unsigned i = 0; i < std::size(kNameserversIPv6) && i < MAXNS; ++i) {
  76. if (!kNameserversIPv6[i])
  77. continue;
  78. // Must use malloc to mimick res_ninit.
  79. struct sockaddr_in6 *sa6;
  80. sa6 = (struct sockaddr_in6 *)malloc(sizeof(*sa6));
  81. sa6->sin6_family = AF_INET6;
  82. sa6->sin6_port = base::HostToNet16(NS_DEFAULTPORT - i);
  83. inet_pton(AF_INET6, kNameserversIPv6[i], &sa6->sin6_addr);
  84. res->_u._ext.nsaddrs[i] = sa6;
  85. memset(&res->nsaddr_list[i], 0, sizeof res->nsaddr_list[i]);
  86. ++nscount6;
  87. }
  88. res->_u._ext.nscount6 = nscount6;
  89. #endif
  90. }
  91. void CloseResState(res_state res) {
  92. #if BUILDFLAG(IS_CHROMEOS)
  93. for (int i = 0; i < res->nscount; ++i) {
  94. if (res->_u._ext.nsaddrs[i] != nullptr)
  95. free(res->_u._ext.nsaddrs[i]);
  96. }
  97. #endif
  98. }
  99. void InitializeExpectedConfig(DnsConfig* config) {
  100. config->ndots = 2;
  101. config->fallback_period = base::Seconds(4);
  102. config->attempts = 7;
  103. config->rotate = true;
  104. config->append_to_multi_label_name = true;
  105. config->search.clear();
  106. config->search.push_back("chromium.org");
  107. config->search.push_back("example.com");
  108. config->nameservers.clear();
  109. for (unsigned i = 0; i < std::size(kNameserversIPv4) && i < MAXNS; ++i) {
  110. IPAddress ip;
  111. EXPECT_TRUE(ip.AssignFromIPLiteral(kNameserversIPv4[i]));
  112. config->nameservers.push_back(IPEndPoint(ip, NS_DEFAULTPORT + i));
  113. }
  114. #if BUILDFLAG(IS_CHROMEOS)
  115. for (unsigned i = 0; i < std::size(kNameserversIPv6) && i < MAXNS; ++i) {
  116. if (!kNameserversIPv6[i])
  117. continue;
  118. IPAddress ip;
  119. EXPECT_TRUE(ip.AssignFromIPLiteral(kNameserversIPv6[i]));
  120. config->nameservers[i] = IPEndPoint(ip, NS_DEFAULTPORT - i);
  121. }
  122. #endif
  123. }
  124. TEST(DnsConfigServicePosixTest, CreateAndDestroy) {
  125. // Regression test to verify crash does not occur if DnsConfigServicePosix
  126. // instance is destroyed without calling WatchConfig()
  127. base::test::TaskEnvironment task_environment(
  128. base::test::TaskEnvironment::MainThreadType::IO);
  129. auto service = std::make_unique<internal::DnsConfigServicePosix>();
  130. service.reset();
  131. task_environment.RunUntilIdle();
  132. }
  133. TEST(DnsConfigServicePosixTest, ConvertResStateToDnsConfig) {
  134. struct __res_state res;
  135. InitializeResState(&res);
  136. absl::optional<DnsConfig> config = internal::ConvertResStateToDnsConfig(res);
  137. CloseResState(&res);
  138. ASSERT_TRUE(config.has_value());
  139. EXPECT_TRUE(config->IsValid());
  140. DnsConfig expected_config;
  141. EXPECT_FALSE(expected_config.EqualsIgnoreHosts(config.value()));
  142. InitializeExpectedConfig(&expected_config);
  143. EXPECT_TRUE(expected_config.EqualsIgnoreHosts(config.value()));
  144. }
  145. TEST(DnsConfigServicePosixTest, RejectEmptyNameserver) {
  146. struct __res_state res = {};
  147. res.options = RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
  148. const char kDnsrch[] = "chromium.org";
  149. memcpy(res.defdname, kDnsrch, sizeof(kDnsrch));
  150. res.dnsrch[0] = res.defdname;
  151. struct sockaddr_in sa = {};
  152. sa.sin_family = AF_INET;
  153. sa.sin_port = base::HostToNet16(NS_DEFAULTPORT);
  154. sa.sin_addr.s_addr = INADDR_ANY;
  155. res.nsaddr_list[0] = sa;
  156. sa.sin_addr.s_addr = 0xCAFE1337;
  157. res.nsaddr_list[1] = sa;
  158. res.nscount = 2;
  159. EXPECT_FALSE(internal::ConvertResStateToDnsConfig(res));
  160. sa.sin_addr.s_addr = 0xDEADBEEF;
  161. res.nsaddr_list[0] = sa;
  162. EXPECT_TRUE(internal::ConvertResStateToDnsConfig(res));
  163. }
  164. TEST(DnsConfigServicePosixTest, DestroyWhileJobsWorking) {
  165. // Regression test to verify crash does not occur if DnsConfigServicePosix
  166. // instance is destroyed while SerialWorker jobs have posted to worker pool.
  167. base::test::TaskEnvironment task_environment(
  168. base::test::TaskEnvironment::MainThreadType::IO,
  169. base::test::TaskEnvironment::TimeSource::MOCK_TIME);
  170. auto service = std::make_unique<internal::DnsConfigServicePosix>();
  171. // Call WatchConfig() which also tests ReadConfig().
  172. service->WatchConfig(base::BindRepeating(&DummyConfigCallback));
  173. service.reset();
  174. task_environment.FastForwardUntilNoTasksRemain();
  175. }
  176. TEST(DnsConfigServicePosixTest, DestroyOnDifferentThread) {
  177. // Regression test to verify crash does not occur if DnsConfigServicePosix
  178. // instance is destroyed on another thread.
  179. base::test::TaskEnvironment task_environment;
  180. scoped_refptr<base::SequencedTaskRunner> runner =
  181. base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
  182. std::unique_ptr<internal::DnsConfigServicePosix, base::OnTaskRunnerDeleter>
  183. service(new internal::DnsConfigServicePosix(),
  184. base::OnTaskRunnerDeleter(runner));
  185. runner->PostTask(FROM_HERE,
  186. base::BindOnce(&internal::DnsConfigServicePosix::WatchConfig,
  187. base::Unretained(service.get()),
  188. base::BindRepeating(&DummyConfigCallback)));
  189. service.reset();
  190. task_environment.RunUntilIdle();
  191. }
  192. } // namespace
  193. } // namespace net