ares-test-init.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. #include "ares-test.h"
  2. // library initialization is only needed for windows builds
  3. #ifdef WIN32
  4. #define EXPECTED_NONINIT ARES_ENOTINITIALIZED
  5. #else
  6. #define EXPECTED_NONINIT ARES_SUCCESS
  7. #endif
  8. namespace ares {
  9. namespace test {
  10. TEST(LibraryInit, Basic) {
  11. EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
  12. EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
  13. EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
  14. ares_library_cleanup();
  15. EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
  16. }
  17. TEST(LibraryInit, UnexpectedCleanup) {
  18. EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
  19. ares_library_cleanup();
  20. EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
  21. }
  22. TEST(LibraryInit, DISABLED_InvalidParam) {
  23. // TODO: police flags argument to ares_library_init()
  24. EXPECT_EQ(ARES_EBADQUERY, ares_library_init(ARES_LIB_INIT_ALL << 2));
  25. EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
  26. ares_library_cleanup();
  27. }
  28. TEST(LibraryInit, Nested) {
  29. EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
  30. EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
  31. EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
  32. EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
  33. EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
  34. ares_library_cleanup();
  35. EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
  36. ares_library_cleanup();
  37. EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
  38. }
  39. TEST(LibraryInit, BasicChannelInit) {
  40. EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
  41. ares_channel channel = nullptr;
  42. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  43. EXPECT_NE(nullptr, channel);
  44. ares_destroy(channel);
  45. ares_library_cleanup();
  46. }
  47. TEST_F(LibraryTest, OptionsChannelInit) {
  48. struct ares_options opts = {0};
  49. int optmask = 0;
  50. opts.flags = ARES_FLAG_USEVC | ARES_FLAG_PRIMARY;
  51. optmask |= ARES_OPT_FLAGS;
  52. opts.timeout = 2000;
  53. optmask |= ARES_OPT_TIMEOUTMS;
  54. opts.tries = 2;
  55. optmask |= ARES_OPT_TRIES;
  56. opts.ndots = 4;
  57. optmask |= ARES_OPT_NDOTS;
  58. opts.udp_port = 54;
  59. optmask |= ARES_OPT_UDP_PORT;
  60. opts.tcp_port = 54;
  61. optmask |= ARES_OPT_TCP_PORT;
  62. opts.socket_send_buffer_size = 514;
  63. optmask |= ARES_OPT_SOCK_SNDBUF;
  64. opts.socket_receive_buffer_size = 514;
  65. optmask |= ARES_OPT_SOCK_RCVBUF;
  66. opts.ednspsz = 1280;
  67. optmask |= ARES_OPT_EDNSPSZ;
  68. opts.nservers = 2;
  69. opts.servers = (struct in_addr *)malloc(opts.nservers * sizeof(struct in_addr));
  70. opts.servers[0].s_addr = htonl(0x01020304);
  71. opts.servers[1].s_addr = htonl(0x02030405);
  72. optmask |= ARES_OPT_SERVERS;
  73. opts.ndomains = 2;
  74. opts.domains = (char **)malloc(opts.ndomains * sizeof(char *));
  75. opts.domains[0] = strdup("example.com");
  76. opts.domains[1] = strdup("example2.com");
  77. optmask |= ARES_OPT_DOMAINS;
  78. opts.lookups = strdup("b");
  79. optmask |= ARES_OPT_LOOKUPS;
  80. optmask |= ARES_OPT_ROTATE;
  81. opts.resolvconf_path = strdup("/etc/resolv.conf");
  82. optmask |= ARES_OPT_RESOLVCONF;
  83. ares_channel channel = nullptr;
  84. EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
  85. EXPECT_NE(nullptr, channel);
  86. ares_channel channel2 = nullptr;
  87. EXPECT_EQ(ARES_SUCCESS, ares_dup(&channel2, channel));
  88. struct ares_options opts2 = {0};
  89. int optmask2 = 0;
  90. EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel2, &opts2, &optmask2));
  91. // Note that not all opts-settable fields are saved (e.g.
  92. // ednspsz, socket_{send,receive}_buffer_size).
  93. EXPECT_EQ(opts.flags, opts2.flags);
  94. EXPECT_EQ(opts.timeout, opts2.timeout);
  95. EXPECT_EQ(opts.tries, opts2.tries);
  96. EXPECT_EQ(opts.ndots, opts2.ndots);
  97. EXPECT_EQ(opts.udp_port, opts2.udp_port);
  98. EXPECT_EQ(opts.tcp_port, opts2.tcp_port);
  99. EXPECT_EQ(1, opts2.nservers); // Truncated by ARES_FLAG_PRIMARY
  100. EXPECT_EQ(opts.servers[0].s_addr, opts2.servers[0].s_addr);
  101. EXPECT_EQ(opts.ndomains, opts2.ndomains);
  102. EXPECT_EQ(std::string(opts.domains[0]), std::string(opts2.domains[0]));
  103. EXPECT_EQ(std::string(opts.domains[1]), std::string(opts2.domains[1]));
  104. EXPECT_EQ(std::string(opts.lookups), std::string(opts2.lookups));
  105. EXPECT_EQ(std::string(opts.resolvconf_path), std::string(opts2.resolvconf_path));
  106. ares_destroy_options(&opts);
  107. ares_destroy_options(&opts2);
  108. ares_destroy(channel);
  109. ares_destroy(channel2);
  110. }
  111. TEST_F(LibraryTest, ChannelAllocFail) {
  112. ares_channel channel;
  113. for (int ii = 1; ii <= 25; ii++) {
  114. ClearFails();
  115. SetAllocFail(ii);
  116. channel = nullptr;
  117. int rc = ares_init(&channel);
  118. // The number of allocations depends on local environment, so don't expect ENOMEM.
  119. if (rc == ARES_ENOMEM) {
  120. EXPECT_EQ(nullptr, channel);
  121. } else {
  122. ares_destroy(channel);
  123. }
  124. }
  125. }
  126. TEST_F(LibraryTest, OptionsChannelAllocFail) {
  127. struct ares_options opts = {0};
  128. int optmask = 0;
  129. opts.flags = ARES_FLAG_USEVC;
  130. optmask |= ARES_OPT_FLAGS;
  131. opts.timeout = 2;
  132. optmask |= ARES_OPT_TIMEOUT;
  133. opts.tries = 2;
  134. optmask |= ARES_OPT_TRIES;
  135. opts.ndots = 4;
  136. optmask |= ARES_OPT_NDOTS;
  137. opts.udp_port = 54;
  138. optmask |= ARES_OPT_UDP_PORT;
  139. opts.tcp_port = 54;
  140. optmask |= ARES_OPT_TCP_PORT;
  141. opts.socket_send_buffer_size = 514;
  142. optmask |= ARES_OPT_SOCK_SNDBUF;
  143. opts.socket_receive_buffer_size = 514;
  144. optmask |= ARES_OPT_SOCK_RCVBUF;
  145. opts.ednspsz = 1280;
  146. optmask |= ARES_OPT_EDNSPSZ;
  147. opts.nservers = 2;
  148. opts.servers = (struct in_addr *)malloc(opts.nservers * sizeof(struct in_addr));
  149. opts.servers[0].s_addr = htonl(0x01020304);
  150. opts.servers[1].s_addr = htonl(0x02030405);
  151. optmask |= ARES_OPT_SERVERS;
  152. opts.ndomains = 2;
  153. opts.domains = (char **)malloc(opts.ndomains * sizeof(char *));
  154. opts.domains[0] = strdup("example.com");
  155. opts.domains[1] = strdup("example2.com");
  156. optmask |= ARES_OPT_DOMAINS;
  157. opts.lookups = strdup("b");
  158. optmask |= ARES_OPT_LOOKUPS;
  159. optmask |= ARES_OPT_ROTATE;
  160. opts.resolvconf_path = strdup("/etc/resolv.conf");
  161. optmask |= ARES_OPT_RESOLVCONF;
  162. ares_channel channel = nullptr;
  163. for (int ii = 1; ii <= 8; ii++) {
  164. ClearFails();
  165. SetAllocFail(ii);
  166. int rc = ares_init_options(&channel, &opts, optmask);
  167. if (rc == ARES_ENOMEM) {
  168. EXPECT_EQ(nullptr, channel);
  169. } else {
  170. EXPECT_EQ(ARES_SUCCESS, rc);
  171. ares_destroy(channel);
  172. channel = nullptr;
  173. }
  174. }
  175. ClearFails();
  176. EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
  177. EXPECT_NE(nullptr, channel);
  178. // Add some servers and a sortlist for flavour.
  179. EXPECT_EQ(ARES_SUCCESS,
  180. ares_set_servers_csv(channel, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
  181. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel, "1.2.3.4 2.3.4.5"));
  182. ares_channel channel2 = nullptr;
  183. for (int ii = 1; ii <= 18; ii++) {
  184. ClearFails();
  185. SetAllocFail(ii);
  186. EXPECT_EQ(ARES_ENOMEM, ares_dup(&channel2, channel)) << ii;
  187. EXPECT_EQ(nullptr, channel2) << ii;
  188. }
  189. struct ares_options opts2;
  190. int optmask2 = 0;
  191. for (int ii = 1; ii <= 6; ii++) {
  192. memset(&opts2, 0, sizeof(opts2));
  193. ClearFails();
  194. SetAllocFail(ii);
  195. EXPECT_EQ(ARES_ENOMEM, ares_save_options(channel, &opts2, &optmask2)) << ii;
  196. // May still have allocations even after ARES_ENOMEM return code.
  197. ares_destroy_options(&opts2);
  198. }
  199. ares_destroy_options(&opts);
  200. ares_destroy(channel);
  201. }
  202. TEST_F(LibraryTest, FailChannelInit) {
  203. EXPECT_EQ(ARES_SUCCESS,
  204. ares_library_init_mem(ARES_LIB_INIT_ALL,
  205. &LibraryTest::amalloc,
  206. &LibraryTest::afree,
  207. &LibraryTest::arealloc));
  208. SetAllocFail(1);
  209. ares_channel channel = nullptr;
  210. EXPECT_EQ(ARES_ENOMEM, ares_init(&channel));
  211. EXPECT_EQ(nullptr, channel);
  212. ares_library_cleanup();
  213. }
  214. #ifndef WIN32
  215. TEST_F(LibraryTest, EnvInit) {
  216. ares_channel channel = nullptr;
  217. EnvValue v1("LOCALDOMAIN", "this.is.local");
  218. EnvValue v2("RES_OPTIONS", "options debug ndots:3 retry:3 rotate retrans:2");
  219. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  220. ares_destroy(channel);
  221. }
  222. TEST_F(LibraryTest, EnvInitAllocFail) {
  223. ares_channel channel;
  224. EnvValue v1("LOCALDOMAIN", "this.is.local");
  225. EnvValue v2("RES_OPTIONS", "options debug ndots:3 retry:3 rotate retrans:2");
  226. for (int ii = 1; ii <= 10; ii++) {
  227. ClearFails();
  228. SetAllocFail(ii);
  229. channel = nullptr;
  230. int rc = ares_init(&channel);
  231. if (rc == ARES_SUCCESS) {
  232. ares_destroy(channel);
  233. } else {
  234. EXPECT_EQ(ARES_ENOMEM, rc);
  235. }
  236. }
  237. }
  238. #endif
  239. TEST_F(DefaultChannelTest, SetAddresses) {
  240. ares_set_local_ip4(channel_, 0x01020304);
  241. byte addr6[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  242. 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
  243. ares_set_local_ip6(channel_, addr6);
  244. ares_set_local_dev(channel_, "dummy");
  245. }
  246. TEST_F(DefaultChannelTest, SetSortlistFailures) {
  247. EXPECT_EQ(ARES_ENODATA, ares_set_sortlist(nullptr, "1.2.3.4"));
  248. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "xyzzy ; lwk"));
  249. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "xyzzy ; 0x123"));
  250. }
  251. TEST_F(DefaultChannelTest, SetSortlistVariants) {
  252. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "1.2.3.4"));
  253. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "1.2.3.4 ; 2.3.4.5"));
  254. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "129.1.1.1"));
  255. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "192.1.1.1"));
  256. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "224.1.1.1"));
  257. EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "225.1.1.1"));
  258. }
  259. TEST_F(DefaultChannelTest, SetSortlistAllocFail) {
  260. for (int ii = 1; ii <= 3; ii++) {
  261. ClearFails();
  262. SetAllocFail(ii);
  263. EXPECT_EQ(ARES_ENOMEM, ares_set_sortlist(channel_, "12.13.0.0/16 1234::5678/40 1.2.3.4")) << ii;
  264. }
  265. }
  266. #ifdef USE_WINSOCK
  267. TEST(Init, NoLibraryInit) {
  268. ares_channel channel = nullptr;
  269. EXPECT_EQ(ARES_ENOTINITIALIZED, ares_init(&channel));
  270. }
  271. #endif
  272. #ifdef HAVE_CONTAINER
  273. // These tests rely on the ability of non-root users to create a chroot
  274. // using Linux namespaces.
  275. // The library uses a variety of information sources to initialize a channel,
  276. // in particular to determine:
  277. // - search: the search domains to use
  278. // - servers: the name servers to use
  279. // - lookup: whether to check files or DNS or both (e.g. "fb")
  280. // - options: various resolver options
  281. // - sortlist: the order of preference for IP addresses
  282. //
  283. // The first source from the following list is used:
  284. // - init_by_options(): explicitly specified values in struct ares_options
  285. // - init_by_environment(): values from the environment:
  286. // - LOCALDOMAIN -> search (single value)
  287. // - RES_OPTIONS -> options
  288. // - init_by_resolv_conf(): values from various config files:
  289. // - /etc/resolv.conf -> search, lookup, servers, sortlist, options
  290. // - /etc/nsswitch.conf -> lookup
  291. // - /etc/host.conf -> lookup
  292. // - /etc/svc.conf -> lookup
  293. // - init_by_defaults(): fallback values:
  294. // - gethostname(3) -> domain
  295. // - "fb" -> lookup
  296. NameContentList filelist = {
  297. {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
  298. "sortlist 1.2.3.4/16 2.3.4.5\n"
  299. "search first.com second.com\n"},
  300. {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
  301. {"/etc/nsswitch.conf", "hosts: files\n"}};
  302. CONTAINED_TEST_F(LibraryTest, ContainerChannelInit,
  303. "myhostname", "mydomainname.org", filelist) {
  304. ares_channel channel = nullptr;
  305. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  306. std::vector<std::string> actual = GetNameServers(channel);
  307. std::vector<std::string> expected = {"1.2.3.4"};
  308. EXPECT_EQ(expected, actual);
  309. struct ares_options opts;
  310. int optmask = 0;
  311. ares_save_options(channel, &opts, &optmask);
  312. EXPECT_EQ(2, opts.ndomains);
  313. EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
  314. EXPECT_EQ(std::string("second.com"), std::string(opts.domains[1]));
  315. ares_destroy_options(&opts);
  316. HostResult result;
  317. ares_gethostbyname(channel, "ahostname.com", AF_INET, HostCallback, &result);
  318. ProcessWork(channel, NoExtraFDs, nullptr);
  319. EXPECT_TRUE(result.done_);
  320. std::stringstream ss;
  321. ss << result.host_;
  322. EXPECT_EQ("{'ahostname.com' aliases=[] addrs=[3.4.5.6]}", ss.str());
  323. ares_destroy(channel);
  324. return HasFailure();
  325. }
  326. CONTAINED_TEST_F(LibraryTest, ContainerSortlistOptionInit,
  327. "myhostname", "mydomainname.org", filelist) {
  328. ares_channel channel = nullptr;
  329. struct ares_options opts = {0};
  330. int optmask = 0;
  331. optmask |= ARES_OPT_SORTLIST;
  332. opts.nsort = 0;
  333. // Explicitly specifying an empty sortlist in the options should override the
  334. // environment.
  335. EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
  336. ares_save_options(channel, &opts, &optmask);
  337. EXPECT_EQ(0, opts.nsort);
  338. EXPECT_EQ(nullptr, opts.sortlist);
  339. EXPECT_EQ(ARES_OPT_SORTLIST, (optmask & ARES_OPT_SORTLIST));
  340. ares_destroy_options(&opts);
  341. ares_destroy(channel);
  342. return HasFailure();
  343. }
  344. NameContentList fullresolv = {
  345. {"/etc/resolv.conf", " nameserver 1.2.3.4 \n"
  346. "search first.com second.com\n"
  347. "lookup bind\n"
  348. "options debug ndots:5\n"
  349. "sortlist 1.2.3.4/16 2.3.4.5\n"}};
  350. CONTAINED_TEST_F(LibraryTest, ContainerFullResolvInit,
  351. "myhostname", "mydomainname.org", fullresolv) {
  352. ares_channel channel = nullptr;
  353. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  354. struct ares_options opts;
  355. int optmask = 0;
  356. ares_save_options(channel, &opts, &optmask);
  357. EXPECT_EQ(std::string("b"), std::string(opts.lookups));
  358. EXPECT_EQ(5, opts.ndots);
  359. ares_destroy_options(&opts);
  360. ares_destroy(channel);
  361. return HasFailure();
  362. }
  363. // Allow path for resolv.conf to be configurable
  364. NameContentList myresolvconf = {
  365. {"/tmp/myresolv.cnf", " nameserver 1.2.3.4 \n"
  366. "search first.com second.com\n"
  367. "lookup bind\n"
  368. "options debug ndots:5\n"
  369. "sortlist 1.2.3.4/16 2.3.4.5\n"}};
  370. CONTAINED_TEST_F(LibraryTest, ContainerMyResolvConfInit,
  371. "myhostname", "mydomain.org", myresolvconf) {
  372. char filename[] = "/tmp/myresolv.cnf";
  373. ares_channel channel = nullptr;
  374. struct ares_options options = {0};
  375. options.resolvconf_path = strdup(filename);
  376. int optmask = ARES_OPT_RESOLVCONF;
  377. EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &options, optmask));
  378. optmask = 0;
  379. free(options.resolvconf_path);
  380. options.resolvconf_path = NULL;
  381. EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel, &options, &optmask));
  382. EXPECT_EQ(ARES_OPT_RESOLVCONF, (optmask & ARES_OPT_RESOLVCONF));
  383. EXPECT_EQ(std::string(filename), std::string(options.resolvconf_path));
  384. ares_destroy_options(&options);
  385. ares_destroy(channel);
  386. return HasFailure();
  387. }
  388. NameContentList hostconf = {
  389. {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
  390. "sortlist1.2.3.4\n" // malformed line
  391. "search first.com second.com\n"},
  392. {"/etc/host.conf", "order bind hosts\n"}};
  393. CONTAINED_TEST_F(LibraryTest, ContainerHostConfInit,
  394. "myhostname", "mydomainname.org", hostconf) {
  395. ares_channel channel = nullptr;
  396. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  397. struct ares_options opts;
  398. int optmask = 0;
  399. ares_save_options(channel, &opts, &optmask);
  400. EXPECT_EQ(std::string("bf"), std::string(opts.lookups));
  401. ares_destroy_options(&opts);
  402. ares_destroy(channel);
  403. return HasFailure();
  404. }
  405. NameContentList svcconf = {
  406. {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
  407. "search first.com second.com\n"},
  408. {"/etc/svc.conf", "hosts= bind\n"}};
  409. CONTAINED_TEST_F(LibraryTest, ContainerSvcConfInit,
  410. "myhostname", "mydomainname.org", svcconf) {
  411. ares_channel channel = nullptr;
  412. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  413. struct ares_options opts;
  414. int optmask = 0;
  415. ares_save_options(channel, &opts, &optmask);
  416. EXPECT_EQ(std::string("b"), std::string(opts.lookups));
  417. ares_destroy_options(&opts);
  418. ares_destroy(channel);
  419. return HasFailure();
  420. }
  421. NameContentList malformedresolvconflookup = {
  422. {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
  423. "lookup garbage\n"}}; // malformed line
  424. CONTAINED_TEST_F(LibraryTest, ContainerMalformedResolvConfLookup,
  425. "myhostname", "mydomainname.org", malformedresolvconflookup) {
  426. ares_channel channel = nullptr;
  427. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  428. struct ares_options opts;
  429. int optmask = 0;
  430. ares_save_options(channel, &opts, &optmask);
  431. EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
  432. ares_destroy_options(&opts);
  433. ares_destroy(channel);
  434. return HasFailure();
  435. }
  436. // Failures when expected config filenames are inaccessible.
  437. class MakeUnreadable {
  438. public:
  439. explicit MakeUnreadable(const std::string& filename)
  440. : filename_(filename) {
  441. chmod(filename_.c_str(), 0000);
  442. }
  443. ~MakeUnreadable() { chmod(filename_.c_str(), 0644); }
  444. private:
  445. std::string filename_;
  446. };
  447. CONTAINED_TEST_F(LibraryTest, ContainerResolvConfNotReadable,
  448. "myhostname", "mydomainname.org", filelist) {
  449. ares_channel channel = nullptr;
  450. MakeUnreadable hide("/etc/resolv.conf");
  451. // Unavailable /etc/resolv.conf falls back to defaults
  452. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  453. return HasFailure();
  454. }
  455. CONTAINED_TEST_F(LibraryTest, ContainerNsswitchConfNotReadable,
  456. "myhostname", "mydomainname.org", filelist) {
  457. ares_channel channel = nullptr;
  458. // Unavailable /etc/nsswitch.conf falls back to defaults.
  459. MakeUnreadable hide("/etc/nsswitch.conf");
  460. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  461. struct ares_options opts;
  462. int optmask = 0;
  463. ares_save_options(channel, &opts, &optmask);
  464. EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
  465. ares_destroy_options(&opts);
  466. ares_destroy(channel);
  467. return HasFailure();
  468. }
  469. CONTAINED_TEST_F(LibraryTest, ContainerHostConfNotReadable,
  470. "myhostname", "mydomainname.org", hostconf) {
  471. ares_channel channel = nullptr;
  472. // Unavailable /etc/host.conf falls back to defaults.
  473. MakeUnreadable hide("/etc/host.conf");
  474. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  475. ares_destroy(channel);
  476. return HasFailure();
  477. }
  478. CONTAINED_TEST_F(LibraryTest, ContainerSvcConfNotReadable,
  479. "myhostname", "mydomainname.org", svcconf) {
  480. ares_channel channel = nullptr;
  481. // Unavailable /etc/svc.conf falls back to defaults.
  482. MakeUnreadable hide("/etc/svc.conf");
  483. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  484. ares_destroy(channel);
  485. return HasFailure();
  486. }
  487. NameContentList rotateenv = {
  488. {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
  489. "search first.com second.com\n"
  490. "options rotate\n"}};
  491. CONTAINED_TEST_F(LibraryTest, ContainerRotateInit,
  492. "myhostname", "mydomainname.org", rotateenv) {
  493. ares_channel channel = nullptr;
  494. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  495. struct ares_options opts;
  496. int optmask = 0;
  497. ares_save_options(channel, &opts, &optmask);
  498. EXPECT_EQ(ARES_OPT_ROTATE, (optmask & ARES_OPT_ROTATE));
  499. ares_destroy_options(&opts);
  500. ares_destroy(channel);
  501. return HasFailure();
  502. }
  503. CONTAINED_TEST_F(LibraryTest, ContainerRotateOverride,
  504. "myhostname", "mydomainname.org", rotateenv) {
  505. ares_channel channel = nullptr;
  506. struct ares_options opts = {0};
  507. int optmask = ARES_OPT_NOROTATE;
  508. EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
  509. optmask = 0;
  510. ares_save_options(channel, &opts, &optmask);
  511. EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
  512. ares_destroy_options(&opts);
  513. ares_destroy(channel);
  514. return HasFailure();
  515. }
  516. // Test that blacklisted IPv6 resolves are ignored. They're filtered from any
  517. // source, so resolv.conf is as good as any.
  518. NameContentList blacklistedIpv6 = {
  519. {"/etc/resolv.conf", " nameserver 254.192.1.1\n" // 0xfe.0xc0.0x01.0x01
  520. " nameserver fec0::dead\n" // Blacklisted
  521. " nameserver ffc0::c001\n" // Not blacklisted
  522. " domain first.com\n"},
  523. {"/etc/nsswitch.conf", "hosts: files\n"}};
  524. CONTAINED_TEST_F(LibraryTest, ContainerBlacklistedIpv6,
  525. "myhostname", "mydomainname.org", blacklistedIpv6) {
  526. ares_channel channel = nullptr;
  527. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  528. std::vector<std::string> actual = GetNameServers(channel);
  529. std::vector<std::string> expected = {
  530. "254.192.1.1",
  531. "ffc0:0000:0000:0000:0000:0000:0000:c001"
  532. };
  533. EXPECT_EQ(expected, actual);
  534. struct ares_options opts;
  535. int optmask = 0;
  536. ares_save_options(channel, &opts, &optmask);
  537. EXPECT_EQ(1, opts.ndomains);
  538. EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
  539. ares_destroy_options(&opts);
  540. ares_destroy(channel);
  541. return HasFailure();
  542. }
  543. NameContentList multiresolv = {
  544. {"/etc/resolv.conf", " nameserver 1::2 ; ;;\n"
  545. " domain first.com\n"},
  546. {"/etc/nsswitch.conf", "hosts: files\n"}};
  547. CONTAINED_TEST_F(LibraryTest, ContainerMultiResolvInit,
  548. "myhostname", "mydomainname.org", multiresolv) {
  549. ares_channel channel = nullptr;
  550. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  551. std::vector<std::string> actual = GetNameServers(channel);
  552. std::vector<std::string> expected = {"0001:0000:0000:0000:0000:0000:0000:0002"};
  553. EXPECT_EQ(expected, actual);
  554. struct ares_options opts;
  555. int optmask = 0;
  556. ares_save_options(channel, &opts, &optmask);
  557. EXPECT_EQ(1, opts.ndomains);
  558. EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
  559. ares_destroy_options(&opts);
  560. ares_destroy(channel);
  561. return HasFailure();
  562. }
  563. NameContentList systemdresolv = {
  564. {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
  565. "domain first.com\n"},
  566. {"/etc/nsswitch.conf", "hosts: junk resolve files\n"}};
  567. CONTAINED_TEST_F(LibraryTest, ContainerSystemdResolvInit,
  568. "myhostname", "mydomainname.org", systemdresolv) {
  569. ares_channel channel = nullptr;
  570. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  571. struct ares_options opts;
  572. int optmask = 0;
  573. ares_save_options(channel, &opts, &optmask);
  574. EXPECT_EQ(std::string("bf"), std::string(opts.lookups));
  575. ares_destroy_options(&opts);
  576. ares_destroy(channel);
  577. return HasFailure();
  578. }
  579. NameContentList empty = {}; // no files
  580. CONTAINED_TEST_F(LibraryTest, ContainerEmptyInit,
  581. "host.domain.org", "domain.org", empty) {
  582. ares_channel channel = nullptr;
  583. EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
  584. std::vector<std::string> actual = GetNameServers(channel);
  585. std::vector<std::string> expected = {"127.0.0.1"};
  586. EXPECT_EQ(expected, actual);
  587. struct ares_options opts;
  588. int optmask = 0;
  589. ares_save_options(channel, &opts, &optmask);
  590. EXPECT_EQ(1, opts.ndomains);
  591. EXPECT_EQ(std::string("domain.org"), std::string(opts.domains[0]));
  592. EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
  593. ares_destroy_options(&opts);
  594. ares_destroy(channel);
  595. return HasFailure();
  596. }
  597. #endif
  598. } // namespace test
  599. } // namespace ares