dns_config_service_linux_unittest.cc 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. // Copyright 2021 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_linux.h"
  5. #include <arpa/inet.h>
  6. #include <resolv.h>
  7. #include <memory>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/bind.h"
  11. #include "base/cancelable_callback.h"
  12. #include "base/check.h"
  13. #include "base/files/file_util.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "base/memory/scoped_refptr.h"
  16. #include "base/run_loop.h"
  17. #include "base/sys_byteorder.h"
  18. #include "base/task/sequenced_task_runner.h"
  19. #include "base/task/single_thread_task_runner.h"
  20. #include "base/task/task_traits.h"
  21. #include "base/task/thread_pool.h"
  22. #include "base/test/metrics/histogram_tester.h"
  23. #include "base/test/task_environment.h"
  24. #include "base/test/test_waitable_event.h"
  25. #include "base/threading/thread_task_runner_handle.h"
  26. #include "net/base/ip_address.h"
  27. #include "net/base/test_completion_callback.h"
  28. #include "net/dns/dns_config.h"
  29. #include "net/dns/dns_config_service.h"
  30. #include "net/dns/nsswitch_reader.h"
  31. #include "net/dns/public/dns_protocol.h"
  32. #include "net/test/test_with_task_environment.h"
  33. #include "testing/gmock/include/gmock/gmock.h"
  34. #include "testing/gtest/include/gtest/gtest.h"
  35. #include "third_party/abseil-cpp/absl/types/optional.h"
  36. namespace net {
  37. namespace {
  38. const char kNsswitchNisServiceInHostsHistogramName[] =
  39. "Net.DNS.DnsConfig.Nsswitch.NisServiceInHosts";
  40. // MAXNS is normally 3, but let's test 4 if possible.
  41. const char* const kNameserversIPv4[] = {
  42. "8.8.8.8",
  43. "192.168.1.1",
  44. "63.1.2.4",
  45. "1.0.0.1",
  46. };
  47. const char* const kNameserversIPv6[] = {
  48. nullptr,
  49. "2001:db8::42",
  50. nullptr,
  51. "::FFFF:129.144.52.38",
  52. };
  53. const std::vector<NsswitchReader::ServiceSpecification> kBasicNsswitchConfig = {
  54. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  55. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)};
  56. void DummyConfigCallback(const DnsConfig& config) {
  57. // Do nothing
  58. }
  59. // Fills in |res| with sane configuration.
  60. void InitializeResState(res_state res) {
  61. memset(res, 0, sizeof(*res));
  62. res->options =
  63. RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH | RES_ROTATE;
  64. res->ndots = 2;
  65. res->retrans = 4;
  66. res->retry = 7;
  67. const char kDnsrch[] =
  68. "chromium.org"
  69. "\0"
  70. "example.com";
  71. memcpy(res->defdname, kDnsrch, sizeof(kDnsrch));
  72. res->dnsrch[0] = res->defdname;
  73. res->dnsrch[1] = res->defdname + sizeof("chromium.org");
  74. for (unsigned i = 0; i < std::size(kNameserversIPv4) && i < MAXNS; ++i) {
  75. struct sockaddr_in sa;
  76. sa.sin_family = AF_INET;
  77. sa.sin_port = base::HostToNet16(NS_DEFAULTPORT + i);
  78. inet_pton(AF_INET, kNameserversIPv4[i], &sa.sin_addr);
  79. res->nsaddr_list[i] = sa;
  80. ++res->nscount;
  81. }
  82. // Install IPv6 addresses, replacing the corresponding IPv4 addresses.
  83. unsigned nscount6 = 0;
  84. for (unsigned i = 0; i < std::size(kNameserversIPv6) && i < MAXNS; ++i) {
  85. if (!kNameserversIPv6[i])
  86. continue;
  87. // Must use malloc to mimic res_ninit. Expect to be freed in
  88. // `TestResolvReader::CloseResState()`.
  89. struct sockaddr_in6* sa6;
  90. sa6 = static_cast<sockaddr_in6*>(malloc(sizeof(*sa6)));
  91. sa6->sin6_family = AF_INET6;
  92. sa6->sin6_port = base::HostToNet16(NS_DEFAULTPORT - i);
  93. inet_pton(AF_INET6, kNameserversIPv6[i], &sa6->sin6_addr);
  94. res->_u._ext.nsaddrs[i] = sa6;
  95. memset(&res->nsaddr_list[i], 0, sizeof res->nsaddr_list[i]);
  96. ++nscount6;
  97. }
  98. res->_u._ext.nscount6 = nscount6;
  99. }
  100. void InitializeExpectedConfig(DnsConfig* config) {
  101. config->ndots = 2;
  102. config->fallback_period = kDnsDefaultFallbackPeriod;
  103. config->attempts = 7;
  104. config->rotate = true;
  105. config->append_to_multi_label_name = true;
  106. config->search.clear();
  107. config->search.push_back("chromium.org");
  108. config->search.push_back("example.com");
  109. config->nameservers.clear();
  110. for (unsigned i = 0; i < std::size(kNameserversIPv4) && i < MAXNS; ++i) {
  111. IPAddress ip;
  112. EXPECT_TRUE(ip.AssignFromIPLiteral(kNameserversIPv4[i]));
  113. config->nameservers.emplace_back(ip, NS_DEFAULTPORT + i);
  114. }
  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. }
  123. class CallbackHelper {
  124. public:
  125. absl::optional<DnsConfig> WaitForResult() {
  126. run_loop_.Run();
  127. return GetResult();
  128. }
  129. absl::optional<DnsConfig> GetResult() {
  130. absl::optional<DnsConfig> result = std::move(config_);
  131. return result;
  132. }
  133. DnsConfigService::CallbackType GetCallback() {
  134. return base::BindRepeating(&CallbackHelper::OnComplete,
  135. base::Unretained(this));
  136. }
  137. private:
  138. void OnComplete(const DnsConfig& config) {
  139. config_ = config;
  140. run_loop_.Quit();
  141. }
  142. absl::optional<DnsConfig> config_;
  143. base::RunLoop run_loop_;
  144. };
  145. // Helper to allow blocking on some point in the ThreadPool.
  146. class BlockingHelper {
  147. public:
  148. ~BlockingHelper() { EXPECT_EQ(state_, State::kUnblocked); }
  149. // Called by the test code to wait for the block point to be reached.
  150. void WaitUntilBlocked() {
  151. CHECK_EQ(state_, State::kUnblocked);
  152. state_ = State::kRunningUntilBlock;
  153. CHECK(!run_loop_ || !run_loop_->running());
  154. run_loop_.emplace();
  155. run_loop_->Run();
  156. CHECK_EQ(state_, State::kBlocked);
  157. }
  158. // Called by the ThreadPool code on reaching the block point.
  159. void WaitUntilUnblocked() {
  160. block_event_.Reset();
  161. task_runner_->PostTask(FROM_HERE,
  162. base::BindOnce(&BlockingHelper::OnBlockedCallback,
  163. base::Unretained(this)));
  164. block_event_.Wait();
  165. blocker_event_.Signal();
  166. }
  167. // Called by the test code to unblock the ThreadPool code.
  168. void Unblock() {
  169. CHECK_EQ(state_, State::kBlocked);
  170. CHECK(!block_event_.IsSignaled());
  171. state_ = State::kUnblocked;
  172. blocker_event_.Reset();
  173. block_event_.Signal();
  174. blocker_event_.Wait();
  175. }
  176. private:
  177. enum class State {
  178. kRunningUntilBlock,
  179. kBlocked,
  180. kUnblocked,
  181. };
  182. void OnBlockedCallback() {
  183. CHECK_EQ(state_, State::kRunningUntilBlock);
  184. CHECK(run_loop_.has_value());
  185. CHECK(run_loop_->running());
  186. state_ = State::kBlocked;
  187. run_loop_->Quit();
  188. }
  189. State state_ = State::kUnblocked;
  190. absl::optional<base::RunLoop> run_loop_;
  191. base::TestWaitableEvent block_event_;
  192. base::TestWaitableEvent blocker_event_;
  193. scoped_refptr<base::SingleThreadTaskRunner> task_runner_ =
  194. base::ThreadTaskRunnerHandle::Get();
  195. };
  196. class TestScopedResState : public ScopedResState {
  197. public:
  198. explicit TestScopedResState(std::unique_ptr<struct __res_state> res)
  199. : res_(std::move(res)) {}
  200. ~TestScopedResState() override {
  201. if (res_) {
  202. // Assume `res->_u._ext.nsaddrs` memory allocated via malloc, e.g. by
  203. // `InitializeResState()`.
  204. for (int i = 0; i < res_->nscount; ++i) {
  205. if (res_->_u._ext.nsaddrs[i] != nullptr)
  206. free(res_->_u._ext.nsaddrs[i]);
  207. }
  208. }
  209. }
  210. const struct __res_state& state() const override {
  211. EXPECT_TRUE(res_);
  212. return *res_;
  213. }
  214. private:
  215. std::unique_ptr<struct __res_state> res_;
  216. };
  217. class TestResolvReader : public ResolvReader {
  218. public:
  219. ~TestResolvReader() override = default;
  220. void set_value(std::unique_ptr<struct __res_state> value) {
  221. CHECK(!value_);
  222. value_ = std::make_unique<TestScopedResState>(std::move(value));
  223. }
  224. bool closed() { return !value_; }
  225. // ResolvReader:
  226. std::unique_ptr<ScopedResState> GetResState() override {
  227. if (blocking_helper_)
  228. blocking_helper_->WaitUntilUnblocked();
  229. CHECK(value_);
  230. return std::move(value_);
  231. }
  232. void set_blocking_helper(BlockingHelper* blocking_helper) {
  233. blocking_helper_ = blocking_helper;
  234. }
  235. private:
  236. std::unique_ptr<TestScopedResState> value_;
  237. BlockingHelper* blocking_helper_ = nullptr;
  238. };
  239. class TestNsswitchReader : public NsswitchReader {
  240. public:
  241. void set_value(std::vector<ServiceSpecification> value) {
  242. value_ = std::move(value);
  243. }
  244. // NsswitchReader:
  245. std::vector<ServiceSpecification> ReadAndParseHosts() override {
  246. return value_;
  247. }
  248. private:
  249. std::vector<ServiceSpecification> value_;
  250. };
  251. class DnsConfigServiceLinuxTest : public ::testing::Test,
  252. public WithTaskEnvironment {
  253. public:
  254. DnsConfigServiceLinuxTest()
  255. : WithTaskEnvironment(
  256. base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
  257. auto resolv_reader = std::make_unique<TestResolvReader>();
  258. resolv_reader_ = resolv_reader.get();
  259. service_.set_resolv_reader_for_testing(std::move(resolv_reader));
  260. auto nsswitch_reader = std::make_unique<TestNsswitchReader>();
  261. nsswitch_reader_ = nsswitch_reader.get();
  262. service_.set_nsswitch_reader_for_testing(std::move(nsswitch_reader));
  263. }
  264. protected:
  265. internal::DnsConfigServiceLinux service_;
  266. raw_ptr<TestResolvReader> resolv_reader_;
  267. raw_ptr<TestNsswitchReader> nsswitch_reader_;
  268. };
  269. // Regression test to verify crash does not occur if DnsConfigServiceLinux
  270. // instance is destroyed without calling WatchConfig()
  271. TEST_F(DnsConfigServiceLinuxTest, CreateAndDestroy) {
  272. auto service = std::make_unique<internal::DnsConfigServiceLinux>();
  273. service.reset();
  274. RunUntilIdle();
  275. }
  276. TEST_F(DnsConfigServiceLinuxTest, ConvertResStateToDnsConfig) {
  277. auto res = std::make_unique<struct __res_state>();
  278. InitializeResState(res.get());
  279. resolv_reader_->set_value(std::move(res));
  280. nsswitch_reader_->set_value(kBasicNsswitchConfig);
  281. CallbackHelper callback_helper;
  282. service_.ReadConfig(callback_helper.GetCallback());
  283. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  284. ASSERT_TRUE(config.has_value());
  285. EXPECT_TRUE(config->IsValid());
  286. DnsConfig expected_config;
  287. EXPECT_FALSE(expected_config.EqualsIgnoreHosts(config.value()));
  288. InitializeExpectedConfig(&expected_config);
  289. EXPECT_TRUE(expected_config.EqualsIgnoreHosts(config.value()));
  290. EXPECT_TRUE(resolv_reader_->closed());
  291. }
  292. TEST_F(DnsConfigServiceLinuxTest, RejectEmptyNameserver) {
  293. auto res = std::make_unique<struct __res_state>();
  294. res->options = RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
  295. const char kDnsrch[] = "chromium.org";
  296. memcpy(res->defdname, kDnsrch, sizeof(kDnsrch));
  297. res->dnsrch[0] = res->defdname;
  298. struct sockaddr_in sa = {};
  299. sa.sin_family = AF_INET;
  300. sa.sin_port = base::HostToNet16(NS_DEFAULTPORT);
  301. sa.sin_addr.s_addr = INADDR_ANY;
  302. res->nsaddr_list[0] = sa;
  303. sa.sin_addr.s_addr = 0xCAFE1337;
  304. res->nsaddr_list[1] = sa;
  305. res->nscount = 2;
  306. resolv_reader_->set_value(std::move(res));
  307. nsswitch_reader_->set_value(kBasicNsswitchConfig);
  308. CallbackHelper callback_helper;
  309. service_.ReadConfig(callback_helper.GetCallback());
  310. RunUntilIdle();
  311. absl::optional<DnsConfig> config = callback_helper.GetResult();
  312. EXPECT_FALSE(config.has_value());
  313. EXPECT_TRUE(resolv_reader_->closed());
  314. }
  315. TEST_F(DnsConfigServiceLinuxTest, AcceptNonEmptyNameserver) {
  316. auto res = std::make_unique<struct __res_state>();
  317. res->options = RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
  318. const char kDnsrch[] = "chromium.org";
  319. memcpy(res->defdname, kDnsrch, sizeof(kDnsrch));
  320. res->dnsrch[0] = res->defdname;
  321. struct sockaddr_in sa = {};
  322. sa.sin_family = AF_INET;
  323. sa.sin_port = base::HostToNet16(NS_DEFAULTPORT);
  324. sa.sin_addr.s_addr = 0xDEADBEEF;
  325. res->nsaddr_list[0] = sa;
  326. sa.sin_addr.s_addr = 0xCAFE1337;
  327. res->nsaddr_list[1] = sa;
  328. res->nscount = 2;
  329. resolv_reader_->set_value(std::move(res));
  330. nsswitch_reader_->set_value(kBasicNsswitchConfig);
  331. CallbackHelper callback_helper;
  332. service_.ReadConfig(callback_helper.GetCallback());
  333. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  334. EXPECT_TRUE(config.has_value());
  335. EXPECT_TRUE(resolv_reader_->closed());
  336. }
  337. // Regression test to verify crash does not occur if DnsConfigServiceLinux
  338. // instance is destroyed while SerialWorker jobs have posted to worker pool.
  339. TEST_F(DnsConfigServiceLinuxTest, DestroyWhileJobsWorking) {
  340. auto service = std::make_unique<internal::DnsConfigServiceLinux>();
  341. // Call WatchConfig() which also tests ReadConfig().
  342. service->WatchConfig(base::BindRepeating(&DummyConfigCallback));
  343. service.reset();
  344. FastForwardUntilNoTasksRemain();
  345. }
  346. // Regression test to verify crash does not occur if DnsConfigServiceLinux
  347. // instance is destroyed on another thread.
  348. TEST_F(DnsConfigServiceLinuxTest, DestroyOnDifferentThread) {
  349. scoped_refptr<base::SequencedTaskRunner> runner =
  350. base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
  351. std::unique_ptr<internal::DnsConfigServiceLinux, base::OnTaskRunnerDeleter>
  352. service(new internal::DnsConfigServiceLinux(),
  353. base::OnTaskRunnerDeleter(runner));
  354. runner->PostTask(FROM_HERE,
  355. base::BindOnce(&internal::DnsConfigServiceLinux::WatchConfig,
  356. base::Unretained(service.get()),
  357. base::BindRepeating(&DummyConfigCallback)));
  358. service.reset();
  359. RunUntilIdle();
  360. }
  361. TEST_F(DnsConfigServiceLinuxTest, AcceptsBasicNsswitchConfig) {
  362. auto res = std::make_unique<struct __res_state>();
  363. InitializeResState(res.get());
  364. resolv_reader_->set_value(std::move(res));
  365. nsswitch_reader_->set_value(kBasicNsswitchConfig);
  366. CallbackHelper callback_helper;
  367. service_.ReadConfig(callback_helper.GetCallback());
  368. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  369. EXPECT_TRUE(resolv_reader_->closed());
  370. ASSERT_TRUE(config.has_value());
  371. EXPECT_TRUE(config->IsValid());
  372. EXPECT_FALSE(config->unhandled_options);
  373. }
  374. TEST_F(DnsConfigServiceLinuxTest,
  375. IgnoresBasicNsswitchConfigIfResolvConfigUnhandled) {
  376. auto res = std::make_unique<struct __res_state>();
  377. InitializeResState(res.get());
  378. res->options |= RES_USE_DNSSEC; // Expect unhandled.
  379. resolv_reader_->set_value(std::move(res));
  380. nsswitch_reader_->set_value(kBasicNsswitchConfig);
  381. CallbackHelper callback_helper;
  382. service_.ReadConfig(callback_helper.GetCallback());
  383. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  384. EXPECT_TRUE(resolv_reader_->closed());
  385. ASSERT_TRUE(config.has_value());
  386. EXPECT_TRUE(config->IsValid());
  387. EXPECT_TRUE(config->unhandled_options);
  388. }
  389. TEST_F(DnsConfigServiceLinuxTest, RejectsNsswitchWithoutFiles) {
  390. auto res = std::make_unique<struct __res_state>();
  391. InitializeResState(res.get());
  392. resolv_reader_->set_value(std::move(res));
  393. nsswitch_reader_->set_value(
  394. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  395. CallbackHelper callback_helper;
  396. service_.ReadConfig(callback_helper.GetCallback());
  397. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  398. EXPECT_TRUE(resolv_reader_->closed());
  399. ASSERT_TRUE(config.has_value());
  400. EXPECT_TRUE(config->IsValid());
  401. EXPECT_TRUE(config->unhandled_options);
  402. }
  403. TEST_F(DnsConfigServiceLinuxTest, RejectsWithExtraFiles) {
  404. auto res = std::make_unique<struct __res_state>();
  405. InitializeResState(res.get());
  406. resolv_reader_->set_value(std::move(res));
  407. nsswitch_reader_->set_value(
  408. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  409. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  410. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  411. CallbackHelper callback_helper;
  412. service_.ReadConfig(callback_helper.GetCallback());
  413. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  414. EXPECT_TRUE(resolv_reader_->closed());
  415. ASSERT_TRUE(config.has_value());
  416. EXPECT_TRUE(config->IsValid());
  417. EXPECT_TRUE(config->unhandled_options);
  418. }
  419. TEST_F(DnsConfigServiceLinuxTest, IgnoresRedundantActions) {
  420. auto res = std::make_unique<struct __res_state>();
  421. InitializeResState(res.get());
  422. resolv_reader_->set_value(std::move(res));
  423. nsswitch_reader_->set_value(
  424. {NsswitchReader::ServiceSpecification(
  425. NsswitchReader::Service::kFiles,
  426. {{/*negated=*/false, NsswitchReader::Status::kSuccess,
  427. NsswitchReader::Action::kReturn},
  428. {/*negated=*/true, NsswitchReader::Status::kSuccess,
  429. NsswitchReader::Action::kContinue}}),
  430. NsswitchReader::ServiceSpecification(
  431. NsswitchReader::Service::kDns,
  432. {{/*negated=*/false, NsswitchReader::Status::kSuccess,
  433. NsswitchReader::Action::kReturn},
  434. {/*negated=*/true, NsswitchReader::Status::kSuccess,
  435. NsswitchReader::Action::kContinue}})});
  436. CallbackHelper callback_helper;
  437. service_.ReadConfig(callback_helper.GetCallback());
  438. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  439. EXPECT_TRUE(resolv_reader_->closed());
  440. ASSERT_TRUE(config.has_value());
  441. EXPECT_TRUE(config->IsValid());
  442. EXPECT_FALSE(config->unhandled_options);
  443. }
  444. TEST_F(DnsConfigServiceLinuxTest, RejectsInconsistentActions) {
  445. auto res = std::make_unique<struct __res_state>();
  446. InitializeResState(res.get());
  447. resolv_reader_->set_value(std::move(res));
  448. nsswitch_reader_->set_value(
  449. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  450. NsswitchReader::ServiceSpecification(
  451. NsswitchReader::Service::kDns,
  452. {{/*negated=*/false, NsswitchReader::Status::kUnavailable,
  453. NsswitchReader::Action::kReturn},
  454. {/*negated=*/true, NsswitchReader::Status::kSuccess,
  455. NsswitchReader::Action::kContinue}})});
  456. CallbackHelper callback_helper;
  457. service_.ReadConfig(callback_helper.GetCallback());
  458. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  459. EXPECT_TRUE(resolv_reader_->closed());
  460. ASSERT_TRUE(config.has_value());
  461. EXPECT_TRUE(config->IsValid());
  462. EXPECT_TRUE(config->unhandled_options);
  463. }
  464. TEST_F(DnsConfigServiceLinuxTest, RejectsWithBadFilesSuccessAction) {
  465. auto res = std::make_unique<struct __res_state>();
  466. InitializeResState(res.get());
  467. resolv_reader_->set_value(std::move(res));
  468. nsswitch_reader_->set_value(
  469. {NsswitchReader::ServiceSpecification(
  470. NsswitchReader::Service::kFiles,
  471. {{/*negated=*/false, NsswitchReader::Status::kSuccess,
  472. NsswitchReader::Action::kContinue}}),
  473. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  474. CallbackHelper callback_helper;
  475. service_.ReadConfig(callback_helper.GetCallback());
  476. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  477. EXPECT_TRUE(resolv_reader_->closed());
  478. ASSERT_TRUE(config.has_value());
  479. EXPECT_TRUE(config->IsValid());
  480. EXPECT_TRUE(config->unhandled_options);
  481. }
  482. TEST_F(DnsConfigServiceLinuxTest, RejectsWithBadFilesNotFoundAction) {
  483. auto res = std::make_unique<struct __res_state>();
  484. InitializeResState(res.get());
  485. resolv_reader_->set_value(std::move(res));
  486. nsswitch_reader_->set_value(
  487. {NsswitchReader::ServiceSpecification(
  488. NsswitchReader::Service::kFiles,
  489. {{/*negated=*/false, NsswitchReader::Status::kNotFound,
  490. NsswitchReader::Action::kReturn}}),
  491. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  492. CallbackHelper callback_helper;
  493. service_.ReadConfig(callback_helper.GetCallback());
  494. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  495. EXPECT_TRUE(resolv_reader_->closed());
  496. ASSERT_TRUE(config.has_value());
  497. EXPECT_TRUE(config->IsValid());
  498. EXPECT_TRUE(config->unhandled_options);
  499. }
  500. TEST_F(DnsConfigServiceLinuxTest, RejectsNsswitchWithoutDns) {
  501. auto res = std::make_unique<struct __res_state>();
  502. InitializeResState(res.get());
  503. resolv_reader_->set_value(std::move(res));
  504. nsswitch_reader_->set_value(
  505. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles)});
  506. CallbackHelper callback_helper;
  507. service_.ReadConfig(callback_helper.GetCallback());
  508. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  509. EXPECT_TRUE(resolv_reader_->closed());
  510. ASSERT_TRUE(config.has_value());
  511. EXPECT_TRUE(config->IsValid());
  512. EXPECT_TRUE(config->unhandled_options);
  513. }
  514. TEST_F(DnsConfigServiceLinuxTest, RejectsWithBadDnsSuccessAction) {
  515. auto res = std::make_unique<struct __res_state>();
  516. InitializeResState(res.get());
  517. resolv_reader_->set_value(std::move(res));
  518. nsswitch_reader_->set_value(
  519. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  520. NsswitchReader::ServiceSpecification(
  521. NsswitchReader::Service::kDns,
  522. {{/*negated=*/false, NsswitchReader::Status::kSuccess,
  523. NsswitchReader::Action::kContinue}})});
  524. CallbackHelper callback_helper;
  525. service_.ReadConfig(callback_helper.GetCallback());
  526. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  527. EXPECT_TRUE(resolv_reader_->closed());
  528. ASSERT_TRUE(config.has_value());
  529. EXPECT_TRUE(config->IsValid());
  530. EXPECT_TRUE(config->unhandled_options);
  531. }
  532. TEST_F(DnsConfigServiceLinuxTest, RejectsNsswitchWithMisorderedServices) {
  533. auto res = std::make_unique<struct __res_state>();
  534. InitializeResState(res.get());
  535. resolv_reader_->set_value(std::move(res));
  536. nsswitch_reader_->set_value(
  537. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns),
  538. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles)});
  539. CallbackHelper callback_helper;
  540. service_.ReadConfig(callback_helper.GetCallback());
  541. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  542. EXPECT_TRUE(resolv_reader_->closed());
  543. ASSERT_TRUE(config.has_value());
  544. EXPECT_TRUE(config->IsValid());
  545. EXPECT_TRUE(config->unhandled_options);
  546. }
  547. TEST_F(DnsConfigServiceLinuxTest, AcceptsIncompatibleNsswitchServicesAfterDns) {
  548. auto res = std::make_unique<struct __res_state>();
  549. InitializeResState(res.get());
  550. resolv_reader_->set_value(std::move(res));
  551. nsswitch_reader_->set_value(
  552. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  553. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns),
  554. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kMdns)});
  555. CallbackHelper callback_helper;
  556. service_.ReadConfig(callback_helper.GetCallback());
  557. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  558. EXPECT_TRUE(resolv_reader_->closed());
  559. ASSERT_TRUE(config.has_value());
  560. EXPECT_TRUE(config->IsValid());
  561. EXPECT_FALSE(config->unhandled_options);
  562. }
  563. TEST_F(DnsConfigServiceLinuxTest, RejectsNsswitchMdns) {
  564. auto res = std::make_unique<struct __res_state>();
  565. InitializeResState(res.get());
  566. resolv_reader_->set_value(std::move(res));
  567. nsswitch_reader_->set_value(
  568. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  569. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kMdns),
  570. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  571. CallbackHelper callback_helper;
  572. service_.ReadConfig(callback_helper.GetCallback());
  573. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  574. EXPECT_TRUE(resolv_reader_->closed());
  575. ASSERT_TRUE(config.has_value());
  576. EXPECT_TRUE(config->IsValid());
  577. EXPECT_TRUE(config->unhandled_options);
  578. }
  579. TEST_F(DnsConfigServiceLinuxTest, RejectsNsswitchMdns4) {
  580. auto res = std::make_unique<struct __res_state>();
  581. InitializeResState(res.get());
  582. resolv_reader_->set_value(std::move(res));
  583. nsswitch_reader_->set_value(
  584. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  585. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kMdns4),
  586. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  587. CallbackHelper callback_helper;
  588. service_.ReadConfig(callback_helper.GetCallback());
  589. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  590. EXPECT_TRUE(resolv_reader_->closed());
  591. ASSERT_TRUE(config.has_value());
  592. EXPECT_TRUE(config->IsValid());
  593. EXPECT_TRUE(config->unhandled_options);
  594. }
  595. TEST_F(DnsConfigServiceLinuxTest, RejectsNsswitchMdns6) {
  596. auto res = std::make_unique<struct __res_state>();
  597. InitializeResState(res.get());
  598. resolv_reader_->set_value(std::move(res));
  599. nsswitch_reader_->set_value(
  600. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  601. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kMdns6),
  602. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  603. CallbackHelper callback_helper;
  604. service_.ReadConfig(callback_helper.GetCallback());
  605. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  606. EXPECT_TRUE(resolv_reader_->closed());
  607. ASSERT_TRUE(config.has_value());
  608. EXPECT_TRUE(config->IsValid());
  609. EXPECT_TRUE(config->unhandled_options);
  610. }
  611. TEST_F(DnsConfigServiceLinuxTest, AcceptsNsswitchMdnsMinimal) {
  612. auto res = std::make_unique<struct __res_state>();
  613. InitializeResState(res.get());
  614. resolv_reader_->set_value(std::move(res));
  615. nsswitch_reader_->set_value(
  616. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  617. NsswitchReader::ServiceSpecification(
  618. NsswitchReader::Service::kMdnsMinimal),
  619. NsswitchReader::ServiceSpecification(
  620. NsswitchReader::Service::kMdns4Minimal),
  621. NsswitchReader::ServiceSpecification(
  622. NsswitchReader::Service::kMdns6Minimal),
  623. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  624. CallbackHelper callback_helper;
  625. service_.ReadConfig(callback_helper.GetCallback());
  626. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  627. EXPECT_TRUE(resolv_reader_->closed());
  628. ASSERT_TRUE(config.has_value());
  629. EXPECT_TRUE(config->IsValid());
  630. EXPECT_FALSE(config->unhandled_options);
  631. }
  632. // mdns*_minimal is often paired with [!UNAVAIL=RETURN] or [NOTFOUND=RETURN]
  633. // actions. Ensure that is accepted.
  634. TEST_F(DnsConfigServiceLinuxTest, AcceptsNsswitchMdnsMinimalWithCommonActions) {
  635. auto res = std::make_unique<struct __res_state>();
  636. InitializeResState(res.get());
  637. resolv_reader_->set_value(std::move(res));
  638. nsswitch_reader_->set_value(
  639. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  640. NsswitchReader::ServiceSpecification(
  641. NsswitchReader::Service::kMdnsMinimal,
  642. {{/*negated=*/true, NsswitchReader::Status::kUnavailable,
  643. NsswitchReader::Action::kReturn}}),
  644. NsswitchReader::ServiceSpecification(
  645. NsswitchReader::Service::kMdns4Minimal,
  646. {{/*negated=*/false, NsswitchReader::Status::kNotFound,
  647. NsswitchReader::Action::kReturn}}),
  648. NsswitchReader::ServiceSpecification(
  649. NsswitchReader::Service::kMdns6Minimal,
  650. {{/*negated=*/true, NsswitchReader::Status::kUnavailable,
  651. NsswitchReader::Action::kReturn}}),
  652. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  653. CallbackHelper callback_helper;
  654. service_.ReadConfig(callback_helper.GetCallback());
  655. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  656. EXPECT_TRUE(resolv_reader_->closed());
  657. ASSERT_TRUE(config.has_value());
  658. EXPECT_TRUE(config->IsValid());
  659. EXPECT_FALSE(config->unhandled_options);
  660. }
  661. TEST_F(DnsConfigServiceLinuxTest, RejectsWithBadMdnsMinimalUnavailableAction) {
  662. auto res = std::make_unique<struct __res_state>();
  663. InitializeResState(res.get());
  664. resolv_reader_->set_value(std::move(res));
  665. nsswitch_reader_->set_value(
  666. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  667. NsswitchReader::ServiceSpecification(
  668. NsswitchReader::Service::kMdnsMinimal,
  669. {{/*negated=*/false, NsswitchReader::Status::kUnavailable,
  670. NsswitchReader::Action::kReturn}}),
  671. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  672. CallbackHelper callback_helper;
  673. service_.ReadConfig(callback_helper.GetCallback());
  674. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  675. EXPECT_TRUE(resolv_reader_->closed());
  676. ASSERT_TRUE(config.has_value());
  677. EXPECT_TRUE(config->IsValid());
  678. EXPECT_TRUE(config->unhandled_options);
  679. }
  680. TEST_F(DnsConfigServiceLinuxTest, AcceptsNsswitchMyHostname) {
  681. auto res = std::make_unique<struct __res_state>();
  682. InitializeResState(res.get());
  683. resolv_reader_->set_value(std::move(res));
  684. nsswitch_reader_->set_value(
  685. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  686. NsswitchReader::ServiceSpecification(
  687. NsswitchReader::Service::kMyHostname),
  688. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  689. CallbackHelper callback_helper;
  690. service_.ReadConfig(callback_helper.GetCallback());
  691. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  692. EXPECT_TRUE(resolv_reader_->closed());
  693. ASSERT_TRUE(config.has_value());
  694. EXPECT_TRUE(config->IsValid());
  695. EXPECT_FALSE(config->unhandled_options);
  696. }
  697. TEST_F(DnsConfigServiceLinuxTest, RejectsWithBadMyHostnameNotFoundAction) {
  698. auto res = std::make_unique<struct __res_state>();
  699. InitializeResState(res.get());
  700. resolv_reader_->set_value(std::move(res));
  701. nsswitch_reader_->set_value(
  702. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  703. NsswitchReader::ServiceSpecification(
  704. NsswitchReader::Service::kMyHostname,
  705. {{/*negated=*/false, NsswitchReader::Status::kNotFound,
  706. NsswitchReader::Action::kReturn}}),
  707. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  708. CallbackHelper callback_helper;
  709. service_.ReadConfig(callback_helper.GetCallback());
  710. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  711. EXPECT_TRUE(resolv_reader_->closed());
  712. ASSERT_TRUE(config.has_value());
  713. EXPECT_TRUE(config->IsValid());
  714. EXPECT_TRUE(config->unhandled_options);
  715. }
  716. TEST_F(DnsConfigServiceLinuxTest, RejectsNsswitchResolve) {
  717. auto res = std::make_unique<struct __res_state>();
  718. InitializeResState(res.get());
  719. resolv_reader_->set_value(std::move(res));
  720. nsswitch_reader_->set_value(
  721. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  722. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kResolve),
  723. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  724. CallbackHelper callback_helper;
  725. service_.ReadConfig(callback_helper.GetCallback());
  726. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  727. EXPECT_TRUE(resolv_reader_->closed());
  728. ASSERT_TRUE(config.has_value());
  729. EXPECT_TRUE(config->IsValid());
  730. EXPECT_TRUE(config->unhandled_options);
  731. }
  732. TEST_F(DnsConfigServiceLinuxTest, HistogramNoNisServiceInHosts) {
  733. auto res = std::make_unique<struct __res_state>();
  734. InitializeResState(res.get());
  735. resolv_reader_->set_value(std::move(res));
  736. nsswitch_reader_->set_value(
  737. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  738. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  739. base::HistogramTester histogram_tester;
  740. CallbackHelper callback_helper;
  741. service_.ReadConfig(callback_helper.GetCallback());
  742. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  743. EXPECT_TRUE(resolv_reader_->closed());
  744. histogram_tester.ExpectBucketCount(kNsswitchNisServiceInHostsHistogramName,
  745. false, 1);
  746. ASSERT_TRUE(config.has_value());
  747. EXPECT_TRUE(config->IsValid());
  748. EXPECT_FALSE(config->unhandled_options);
  749. }
  750. TEST_F(DnsConfigServiceLinuxTest, AcceptsNsswitchNis) {
  751. auto res = std::make_unique<struct __res_state>();
  752. InitializeResState(res.get());
  753. resolv_reader_->set_value(std::move(res));
  754. nsswitch_reader_->set_value(
  755. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  756. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kNis),
  757. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  758. base::HistogramTester histogram_tester;
  759. CallbackHelper callback_helper;
  760. service_.ReadConfig(callback_helper.GetCallback());
  761. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  762. EXPECT_TRUE(resolv_reader_->closed());
  763. histogram_tester.ExpectBucketCount(kNsswitchNisServiceInHostsHistogramName,
  764. true, 1);
  765. ASSERT_TRUE(config.has_value());
  766. EXPECT_TRUE(config->IsValid());
  767. EXPECT_FALSE(config->unhandled_options);
  768. }
  769. TEST_F(DnsConfigServiceLinuxTest, RejectsWithBadNisNotFoundAction) {
  770. auto res = std::make_unique<struct __res_state>();
  771. InitializeResState(res.get());
  772. resolv_reader_->set_value(std::move(res));
  773. nsswitch_reader_->set_value(
  774. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  775. NsswitchReader::ServiceSpecification(
  776. NsswitchReader::Service::kNis,
  777. {{/*negated=*/false, NsswitchReader::Status::kNotFound,
  778. NsswitchReader::Action::kReturn}}),
  779. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  780. CallbackHelper callback_helper;
  781. service_.ReadConfig(callback_helper.GetCallback());
  782. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  783. EXPECT_TRUE(resolv_reader_->closed());
  784. ASSERT_TRUE(config.has_value());
  785. EXPECT_TRUE(config->IsValid());
  786. EXPECT_TRUE(config->unhandled_options);
  787. }
  788. TEST_F(DnsConfigServiceLinuxTest, RejectsNsswitchUnknown) {
  789. auto res = std::make_unique<struct __res_state>();
  790. InitializeResState(res.get());
  791. resolv_reader_->set_value(std::move(res));
  792. nsswitch_reader_->set_value(
  793. {NsswitchReader::ServiceSpecification(NsswitchReader::Service::kFiles),
  794. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kUnknown),
  795. NsswitchReader::ServiceSpecification(NsswitchReader::Service::kDns)});
  796. CallbackHelper callback_helper;
  797. service_.ReadConfig(callback_helper.GetCallback());
  798. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  799. EXPECT_TRUE(resolv_reader_->closed());
  800. ASSERT_TRUE(config.has_value());
  801. EXPECT_TRUE(config->IsValid());
  802. EXPECT_TRUE(config->unhandled_options);
  803. }
  804. TEST_F(DnsConfigServiceLinuxTest, FreshReadsAfterAdditionalTriggers) {
  805. BlockingHelper blocking_helper;
  806. resolv_reader_->set_blocking_helper(&blocking_helper);
  807. CallbackHelper callback_helper;
  808. service_.ReadConfig(callback_helper.GetCallback());
  809. // Expect work to be blocked.
  810. blocking_helper.WaitUntilBlocked();
  811. ASSERT_FALSE(callback_helper.GetResult());
  812. // Signal config changes (trigger a few times to confirm only one fresh read
  813. // is performed).
  814. service_.TriggerOnConfigChangedForTesting(/*succeeded=*/true);
  815. service_.TriggerOnConfigChangedForTesting(/*succeeded=*/true);
  816. service_.TriggerOnConfigChangedForTesting(/*succeeded=*/true);
  817. // Initial results (expect to be replaced with second read)
  818. auto res = std::make_unique<struct __res_state>();
  819. InitializeResState(res.get());
  820. resolv_reader_->set_value(std::move(res));
  821. nsswitch_reader_->set_value(kBasicNsswitchConfig);
  822. // Unblock first read (expect no completion because second read should begin
  823. // immediately)
  824. blocking_helper.Unblock();
  825. blocking_helper.WaitUntilBlocked();
  826. ASSERT_FALSE(callback_helper.GetResult());
  827. EXPECT_TRUE(resolv_reader_->closed());
  828. // Setup a new config to confirm a fresh read is performed.
  829. res = std::make_unique<struct __res_state>();
  830. res->options = RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH;
  831. struct sockaddr_in sa = {};
  832. sa.sin_family = AF_INET;
  833. sa.sin_port = base::HostToNet16(1000);
  834. inet_pton(AF_INET, "1.2.3.4", &sa.sin_addr);
  835. res->nsaddr_list[0] = sa;
  836. res->nscount = 1;
  837. resolv_reader_->set_value(std::move(res));
  838. // Unblock second read (expect completion)
  839. blocking_helper.Unblock();
  840. absl::optional<DnsConfig> config = callback_helper.WaitForResult();
  841. ASSERT_TRUE(config.has_value());
  842. EXPECT_TRUE(config->IsValid());
  843. IPEndPoint expected(IPAddress(1, 2, 3, 4), 1000);
  844. EXPECT_THAT(config.value().nameservers, testing::ElementsAre(expected));
  845. EXPECT_TRUE(resolv_reader_->closed());
  846. }
  847. } // namespace
  848. } // namespace net