ares-test-mock-ai.cc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. #include "ares-test-ai.h"
  2. #include "dns-proto.h"
  3. #ifdef HAVE_NETINET_IN_H
  4. #include <netinet/in.h>
  5. #endif
  6. #include <sstream>
  7. #include <vector>
  8. using testing::InvokeWithoutArgs;
  9. using testing::DoAll;
  10. namespace ares {
  11. namespace test {
  12. MATCHER_P(IncludesNumAddresses, n, "") {
  13. if(!arg)
  14. return false;
  15. int cnt = 0;
  16. for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
  17. cnt++;
  18. return n == cnt;
  19. }
  20. MATCHER_P(IncludesV4Address, address, "") {
  21. if(!arg)
  22. return false;
  23. in_addr addressnum = {};
  24. if (!ares_inet_pton(AF_INET, address, &addressnum))
  25. return false; // wrong number format?
  26. for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
  27. if (ai->ai_family != AF_INET)
  28. continue;
  29. if (ai->ai_addrlen != sizeof(struct sockaddr_in))
  30. continue;
  31. if (reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr.s_addr ==
  32. addressnum.s_addr)
  33. return true; // found
  34. }
  35. return false;
  36. }
  37. MATCHER_P(IncludesV6Address, address, "") {
  38. if(!arg)
  39. return false;
  40. in6_addr addressnum = {};
  41. if (!ares_inet_pton(AF_INET6, address, &addressnum)) {
  42. return false; // wrong number format?
  43. }
  44. for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
  45. if (ai->ai_family != AF_INET6)
  46. continue;
  47. if (ai->ai_addrlen != sizeof(struct sockaddr_in6))
  48. continue;
  49. if (!memcmp(
  50. reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr.s6_addr,
  51. addressnum.s6_addr, sizeof(addressnum.s6_addr)))
  52. return true; // found
  53. }
  54. return false;
  55. }
  56. // UDP only so mock server doesn't get confused by concatenated requests
  57. TEST_P(MockUDPChannelTestAI, GetAddrInfoParallelLookups) {
  58. DNSPacket rsp1;
  59. rsp1.set_response().set_aa()
  60. .add_question(new DNSQuestion("www.google.com", T_A))
  61. .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
  62. ON_CALL(server_, OnRequest("www.google.com", T_A))
  63. .WillByDefault(SetReply(&server_, &rsp1));
  64. DNSPacket rsp2;
  65. rsp2.set_response().set_aa()
  66. .add_question(new DNSQuestion("www.example.com", T_A))
  67. .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
  68. ON_CALL(server_, OnRequest("www.example.com", T_A))
  69. .WillByDefault(SetReply(&server_, &rsp2));
  70. struct ares_addrinfo_hints hints = {};
  71. hints.ai_family = AF_INET;
  72. hints.ai_flags = ARES_AI_NOSORT;
  73. AddrInfoResult result1;
  74. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result1);
  75. AddrInfoResult result2;
  76. ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result2);
  77. AddrInfoResult result3;
  78. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result3);
  79. Process();
  80. EXPECT_TRUE(result1.done_);
  81. EXPECT_EQ(result1.status_, ARES_SUCCESS);
  82. EXPECT_THAT(result1.ai_, IncludesNumAddresses(1));
  83. EXPECT_THAT(result1.ai_, IncludesV4Address("2.3.4.5"));
  84. EXPECT_TRUE(result2.done_);
  85. EXPECT_EQ(result2.status_, ARES_SUCCESS);
  86. EXPECT_THAT(result2.ai_, IncludesNumAddresses(1));
  87. EXPECT_THAT(result2.ai_, IncludesV4Address("1.2.3.4"));
  88. EXPECT_TRUE(result3.done_);
  89. EXPECT_EQ(result3.status_, ARES_SUCCESS);
  90. EXPECT_THAT(result3.ai_, IncludesNumAddresses(1));
  91. EXPECT_THAT(result3.ai_, IncludesV4Address("2.3.4.5"));
  92. }
  93. // UDP to TCP specific test
  94. TEST_P(MockUDPChannelTestAI, TruncationRetry) {
  95. DNSPacket rsptruncated;
  96. rsptruncated.set_response().set_aa().set_tc()
  97. .add_question(new DNSQuestion("www.google.com", T_A));
  98. DNSPacket rspok;
  99. rspok.set_response()
  100. .add_question(new DNSQuestion("www.google.com", T_A))
  101. .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
  102. EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
  103. .WillOnce(SetReply(&server_, &rsptruncated))
  104. .WillOnce(SetReply(&server_, &rspok));
  105. AddrInfoResult result;
  106. struct ares_addrinfo_hints hints = {};
  107. hints.ai_family = AF_INET;
  108. hints.ai_flags = ARES_AI_NOSORT;
  109. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  110. Process();
  111. EXPECT_TRUE(result.done_);
  112. EXPECT_EQ(result.status_, ARES_SUCCESS);
  113. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  114. EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
  115. }
  116. // TCP only to prevent retries
  117. TEST_P(MockTCPChannelTestAI, MalformedResponse) {
  118. std::vector<byte> one = {0x01};
  119. EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
  120. .WillOnce(SetReplyData(&server_, one));
  121. AddrInfoResult result;
  122. struct ares_addrinfo_hints hints = {};
  123. hints.ai_family = AF_INET;
  124. hints.ai_flags = ARES_AI_NOSORT;
  125. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  126. Process();
  127. EXPECT_TRUE(result.done_);
  128. EXPECT_EQ(ARES_ETIMEOUT, result.status_);
  129. }
  130. TEST_P(MockTCPChannelTestAI, FormErrResponse) {
  131. DNSPacket rsp;
  132. rsp.set_response().set_aa()
  133. .add_question(new DNSQuestion("www.google.com", T_A));
  134. rsp.set_rcode(FORMERR);
  135. EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
  136. .WillOnce(SetReply(&server_, &rsp));
  137. AddrInfoResult result;
  138. struct ares_addrinfo_hints hints = {};
  139. hints.ai_family = AF_INET;
  140. hints.ai_flags = ARES_AI_NOSORT;
  141. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  142. Process();
  143. EXPECT_TRUE(result.done_);
  144. EXPECT_EQ(ARES_EFORMERR, result.status_);
  145. }
  146. TEST_P(MockTCPChannelTestAI, ServFailResponse) {
  147. DNSPacket rsp;
  148. rsp.set_response().set_aa()
  149. .add_question(new DNSQuestion("www.google.com", T_A));
  150. rsp.set_rcode(SERVFAIL);
  151. EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
  152. .WillOnce(SetReply(&server_, &rsp));
  153. AddrInfoResult result;
  154. struct ares_addrinfo_hints hints = {};
  155. hints.ai_family = AF_INET;
  156. hints.ai_flags = ARES_AI_NOSORT;
  157. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  158. Process();
  159. EXPECT_TRUE(result.done_);
  160. // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
  161. EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
  162. }
  163. TEST_P(MockTCPChannelTestAI, NotImplResponse) {
  164. DNSPacket rsp;
  165. rsp.set_response().set_aa()
  166. .add_question(new DNSQuestion("www.google.com", T_A));
  167. rsp.set_rcode(NOTIMP);
  168. EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
  169. .WillOnce(SetReply(&server_, &rsp));
  170. AddrInfoResult result;
  171. struct ares_addrinfo_hints hints = {};
  172. hints.ai_family = AF_INET;
  173. hints.ai_flags = ARES_AI_NOSORT;
  174. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  175. Process();
  176. EXPECT_TRUE(result.done_);
  177. // ARES_FLAG_NOCHECKRESP not set, so NOTIMP consumed
  178. EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
  179. }
  180. TEST_P(MockTCPChannelTestAI, RefusedResponse) {
  181. DNSPacket rsp;
  182. rsp.set_response().set_aa()
  183. .add_question(new DNSQuestion("www.google.com", T_A));
  184. rsp.set_rcode(REFUSED);
  185. EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
  186. .WillOnce(SetReply(&server_, &rsp));
  187. AddrInfoResult result;
  188. struct ares_addrinfo_hints hints = {};
  189. hints.ai_family = AF_INET;
  190. hints.ai_flags = ARES_AI_NOSORT;
  191. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  192. Process();
  193. EXPECT_TRUE(result.done_);
  194. // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
  195. EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
  196. }
  197. TEST_P(MockTCPChannelTestAI, YXDomainResponse) {
  198. DNSPacket rsp;
  199. rsp.set_response().set_aa()
  200. .add_question(new DNSQuestion("www.google.com", T_A));
  201. rsp.set_rcode(YXDOMAIN);
  202. EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
  203. .WillOnce(SetReply(&server_, &rsp));
  204. AddrInfoResult result;
  205. struct ares_addrinfo_hints hints = {};
  206. hints.ai_family = AF_INET;
  207. hints.ai_flags = ARES_AI_NOSORT;
  208. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  209. Process();
  210. EXPECT_TRUE(result.done_);
  211. EXPECT_EQ(ARES_ENODATA, result.status_);
  212. }
  213. class MockExtraOptsTestAI
  214. : public MockChannelOptsTest,
  215. public ::testing::WithParamInterface< std::pair<int, bool> > {
  216. public:
  217. MockExtraOptsTestAI()
  218. : MockChannelOptsTest(1, GetParam().first, GetParam().second,
  219. FillOptions(&opts_),
  220. ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
  221. static struct ares_options* FillOptions(struct ares_options * opts) {
  222. memset(opts, 0, sizeof(struct ares_options));
  223. // Set a few options that affect socket communications
  224. opts->socket_send_buffer_size = 514;
  225. opts->socket_receive_buffer_size = 514;
  226. return opts;
  227. }
  228. private:
  229. struct ares_options opts_;
  230. };
  231. TEST_P(MockExtraOptsTestAI, SimpleQuery) {
  232. ares_set_local_ip4(channel_, 0x7F000001);
  233. byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  234. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
  235. ares_set_local_ip6(channel_, addr6);
  236. ares_set_local_dev(channel_, "dummy");
  237. DNSPacket rsp;
  238. rsp.set_response().set_aa()
  239. .add_question(new DNSQuestion("www.google.com", T_A))
  240. .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
  241. ON_CALL(server_, OnRequest("www.google.com", T_A))
  242. .WillByDefault(SetReply(&server_, &rsp));
  243. AddrInfoResult result;
  244. struct ares_addrinfo_hints hints = {};
  245. hints.ai_family = AF_INET;
  246. hints.ai_flags = ARES_AI_NOSORT;
  247. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  248. Process();
  249. EXPECT_TRUE(result.done_);
  250. EXPECT_EQ(ARES_SUCCESS, result.status_);
  251. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  252. EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
  253. }
  254. class MockExtraOptsNDotsTestAI
  255. : public MockChannelOptsTest,
  256. public ::testing::WithParamInterface< std::pair<int, bool> > {
  257. public:
  258. MockExtraOptsNDotsTestAI(int ndots)
  259. : MockChannelOptsTest(1, GetParam().first, GetParam().second,
  260. FillOptions(&opts_, ndots),
  261. ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF|ARES_OPT_NDOTS) {}
  262. static struct ares_options* FillOptions(struct ares_options * opts, int ndots) {
  263. memset(opts, 0, sizeof(struct ares_options));
  264. // Set a few options that affect socket communications
  265. opts->socket_send_buffer_size = 514;
  266. opts->socket_receive_buffer_size = 514;
  267. opts->ndots = ndots;
  268. return opts;
  269. }
  270. private:
  271. struct ares_options opts_;
  272. };
  273. class MockExtraOptsNDots5TestAI : public MockExtraOptsNDotsTestAI {
  274. public:
  275. MockExtraOptsNDots5TestAI() : MockExtraOptsNDotsTestAI(5) {}
  276. };
  277. TEST_P(MockExtraOptsNDots5TestAI, SimpleQuery) {
  278. ares_set_local_ip4(channel_, 0x7F000001);
  279. byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  280. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
  281. ares_set_local_ip6(channel_, addr6);
  282. ares_set_local_dev(channel_, "dummy");
  283. DNSPacket rsp;
  284. rsp.set_response().set_aa()
  285. .add_question(new DNSQuestion("dynamodb.us-east-1.amazonaws.com", T_A))
  286. .add_answer(new DNSARR("dynamodb.us-east-1.amazonaws.com", 100, {123, 45, 67, 8}));
  287. ON_CALL(server_, OnRequest("dynamodb.us-east-1.amazonaws.com", T_A))
  288. .WillByDefault(SetReply(&server_, &rsp));
  289. AddrInfoResult result;
  290. struct ares_addrinfo_hints hints = {};
  291. hints.ai_family = AF_INET;
  292. hints.ai_flags = ARES_AI_NOSORT;
  293. ares_getaddrinfo(channel_, "dynamodb.us-east-1.amazonaws.com.", NULL, &hints, AddrInfoCallback, &result);
  294. Process();
  295. EXPECT_TRUE(result.done_);
  296. EXPECT_EQ(ARES_SUCCESS, result.status_);
  297. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  298. EXPECT_THAT(result.ai_, IncludesV4Address("123.45.67.8"));
  299. }
  300. class MockFlagsChannelOptsTestAI
  301. : public MockChannelOptsTest,
  302. public ::testing::WithParamInterface< std::pair<int, bool> > {
  303. public:
  304. MockFlagsChannelOptsTestAI(int flags)
  305. : MockChannelOptsTest(1, GetParam().first, GetParam().second,
  306. FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
  307. static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
  308. memset(opts, 0, sizeof(struct ares_options));
  309. opts->flags = flags;
  310. return opts;
  311. }
  312. private:
  313. struct ares_options opts_;
  314. };
  315. class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI {
  316. public:
  317. MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {}
  318. };
  319. TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) {
  320. DNSPacket rsp;
  321. rsp.set_response().set_aa()
  322. .add_question(new DNSQuestion("www.google.com", T_A));
  323. rsp.set_rcode(SERVFAIL);
  324. ON_CALL(server_, OnRequest("www.google.com", T_A))
  325. .WillByDefault(SetReply(&server_, &rsp));
  326. AddrInfoResult result;
  327. struct ares_addrinfo_hints hints = {};
  328. hints.ai_family = AF_INET;
  329. hints.ai_flags = ARES_AI_NOSORT;
  330. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  331. Process();
  332. EXPECT_TRUE(result.done_);
  333. EXPECT_EQ(ARES_ESERVFAIL, result.status_);
  334. }
  335. TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) {
  336. DNSPacket rsp;
  337. rsp.set_response().set_aa()
  338. .add_question(new DNSQuestion("www.google.com", T_A));
  339. rsp.set_rcode(NOTIMP);
  340. ON_CALL(server_, OnRequest("www.google.com", T_A))
  341. .WillByDefault(SetReply(&server_, &rsp));
  342. AddrInfoResult result;
  343. struct ares_addrinfo_hints hints = {};
  344. hints.ai_family = AF_INET;
  345. hints.ai_flags = ARES_AI_NOSORT;
  346. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  347. Process();
  348. EXPECT_TRUE(result.done_);
  349. EXPECT_EQ(ARES_ENOTIMP, result.status_);
  350. }
  351. TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) {
  352. DNSPacket rsp;
  353. rsp.set_response().set_aa()
  354. .add_question(new DNSQuestion("www.google.com", T_A));
  355. rsp.set_rcode(REFUSED);
  356. ON_CALL(server_, OnRequest("www.google.com", T_A))
  357. .WillByDefault(SetReply(&server_, &rsp));
  358. AddrInfoResult result;
  359. struct ares_addrinfo_hints hints = {};
  360. hints.ai_family = AF_INET;
  361. hints.ai_flags = ARES_AI_NOSORT;
  362. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  363. Process();
  364. EXPECT_TRUE(result.done_);
  365. EXPECT_EQ(ARES_EREFUSED, result.status_);
  366. }
  367. TEST_P(MockChannelTestAI, FamilyV6) {
  368. DNSPacket rsp6;
  369. rsp6.set_response().set_aa()
  370. .add_question(new DNSQuestion("example.com", T_AAAA))
  371. .add_answer(new DNSAaaaRR("example.com", 100,
  372. {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  373. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
  374. ON_CALL(server_, OnRequest("example.com", T_AAAA))
  375. .WillByDefault(SetReply(&server_, &rsp6));
  376. AddrInfoResult result;
  377. struct ares_addrinfo_hints hints = {};
  378. hints.ai_family = AF_INET6;
  379. hints.ai_flags = ARES_AI_NOSORT;
  380. ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
  381. AddrInfoCallback, &result);
  382. Process();
  383. EXPECT_TRUE(result.done_);
  384. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  385. EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
  386. }
  387. TEST_P(MockChannelTestAI, FamilyV4) {
  388. DNSPacket rsp4;
  389. rsp4.set_response().set_aa()
  390. .add_question(new DNSQuestion("example.com", T_A))
  391. .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
  392. ON_CALL(server_, OnRequest("example.com", T_A))
  393. .WillByDefault(SetReply(&server_, &rsp4));
  394. AddrInfoResult result = {};
  395. struct ares_addrinfo_hints hints = {};
  396. hints.ai_family = AF_INET;
  397. hints.ai_flags = ARES_AI_NOSORT;
  398. ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
  399. AddrInfoCallback, &result);
  400. Process();
  401. EXPECT_TRUE(result.done_);
  402. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  403. EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
  404. }
  405. TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) {
  406. DNSPacket rsp4;
  407. rsp4.set_response().set_aa()
  408. .add_question(new DNSQuestion("example.com", T_A))
  409. .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}))
  410. .add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0}));
  411. ON_CALL(server_, OnRequest("example.com", T_A))
  412. .WillByDefault(SetReply(&server_, &rsp4));
  413. AddrInfoResult result = {};
  414. struct ares_addrinfo_hints hints = {};
  415. hints.ai_family = AF_INET;
  416. hints.ai_flags = ARES_AI_NOSORT;
  417. ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
  418. AddrInfoCallback, &result);
  419. Process();
  420. EXPECT_TRUE(result.done_);
  421. std::stringstream ss;
  422. ss << result.ai_;
  423. EXPECT_EQ("{addr=[2.3.4.5], addr=[7.8.9.0]}", ss.str());
  424. }
  425. TEST_P(MockChannelTestAI, FamilyUnspecified) {
  426. DNSPacket rsp6;
  427. rsp6.set_response().set_aa()
  428. .add_question(new DNSQuestion("example.com", T_AAAA))
  429. .add_answer(new DNSAaaaRR("example.com", 100,
  430. {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  431. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
  432. ON_CALL(server_, OnRequest("example.com", T_AAAA))
  433. .WillByDefault(SetReply(&server_, &rsp6));
  434. DNSPacket rsp4;
  435. rsp4.set_response().set_aa()
  436. .add_question(new DNSQuestion("example.com", T_A))
  437. .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
  438. ON_CALL(server_, OnRequest("example.com", T_A))
  439. .WillByDefault(SetReply(&server_, &rsp4));
  440. AddrInfoResult result;
  441. struct ares_addrinfo_hints hints = {};
  442. hints.ai_family = AF_UNSPEC;
  443. hints.ai_flags = ARES_AI_NOSORT;
  444. ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
  445. AddrInfoCallback, &result);
  446. Process();
  447. EXPECT_TRUE(result.done_);
  448. EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
  449. EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
  450. EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
  451. }
  452. class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI {
  453. public:
  454. MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {}
  455. };
  456. TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) {
  457. DNSPacket rspfail;
  458. rspfail.set_response().set_aa().set_rcode(FORMERR)
  459. .add_question(new DNSQuestion("www.google.com", T_A));
  460. DNSPacket rspok;
  461. rspok.set_response()
  462. .add_question(new DNSQuestion("www.google.com", T_A))
  463. .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
  464. EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
  465. .WillOnce(SetReply(&server_, &rspfail))
  466. .WillOnce(SetReply(&server_, &rspok));
  467. AddrInfoResult result;
  468. struct ares_addrinfo_hints hints = {};
  469. hints.ai_family = AF_INET;
  470. hints.ai_flags = ARES_AI_NOSORT;
  471. ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
  472. Process();
  473. EXPECT_TRUE(result.done_);
  474. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  475. EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
  476. }
  477. TEST_P(MockChannelTestAI, SearchDomains) {
  478. DNSPacket nofirst;
  479. nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
  480. .add_question(new DNSQuestion("www.first.com", T_A));
  481. ON_CALL(server_, OnRequest("www.first.com", T_A))
  482. .WillByDefault(SetReply(&server_, &nofirst));
  483. DNSPacket nosecond;
  484. nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
  485. .add_question(new DNSQuestion("www.second.org", T_A));
  486. ON_CALL(server_, OnRequest("www.second.org", T_A))
  487. .WillByDefault(SetReply(&server_, &nosecond));
  488. DNSPacket yesthird;
  489. yesthird.set_response().set_aa()
  490. .add_question(new DNSQuestion("www.third.gov", T_A))
  491. .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
  492. ON_CALL(server_, OnRequest("www.third.gov", T_A))
  493. .WillByDefault(SetReply(&server_, &yesthird));
  494. AddrInfoResult result;
  495. struct ares_addrinfo_hints hints = {};
  496. hints.ai_family = AF_INET;
  497. hints.ai_flags = ARES_AI_NOSORT;
  498. ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
  499. Process();
  500. EXPECT_TRUE(result.done_);
  501. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  502. EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
  503. }
  504. TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) {
  505. DNSPacket nofirst;
  506. nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
  507. .add_question(new DNSQuestion("www.first.com", T_AAAA));
  508. ON_CALL(server_, OnRequest("www.first.com", T_AAAA))
  509. .WillByDefault(SetReply(&server_, &nofirst));
  510. DNSPacket nofirst4;
  511. nofirst4.set_response().set_aa().set_rcode(NXDOMAIN)
  512. .add_question(new DNSQuestion("www.first.com", T_A));
  513. ON_CALL(server_, OnRequest("www.first.com", T_A))
  514. .WillByDefault(SetReply(&server_, &nofirst4));
  515. DNSPacket nosecond;
  516. nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
  517. .add_question(new DNSQuestion("www.second.org", T_AAAA));
  518. ON_CALL(server_, OnRequest("www.second.org", T_AAAA))
  519. .WillByDefault(SetReply(&server_, &nosecond));
  520. DNSPacket yessecond4;
  521. yessecond4.set_response().set_aa()
  522. .add_question(new DNSQuestion("www.second.org", T_A))
  523. .add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5}));
  524. ON_CALL(server_, OnRequest("www.second.org", T_A))
  525. .WillByDefault(SetReply(&server_, &yessecond4));
  526. DNSPacket failthird;
  527. failthird.set_response().set_aa().set_rcode(SERVFAIL)
  528. .add_question(new DNSQuestion("www.third.gov", T_AAAA));
  529. ON_CALL(server_, OnRequest("www.third.gov", T_AAAA))
  530. .WillByDefault(SetReply(&server_, &failthird));
  531. DNSPacket failthird4;
  532. failthird4.set_response().set_aa().set_rcode(SERVFAIL)
  533. .add_question(new DNSQuestion("www.third.gov", T_A));
  534. ON_CALL(server_, OnRequest("www.third.gov", T_A))
  535. .WillByDefault(SetReply(&server_, &failthird4));
  536. AddrInfoResult result;
  537. struct ares_addrinfo_hints hints = {};
  538. hints.ai_family = AF_UNSPEC;
  539. hints.ai_flags = ARES_AI_NOSORT;
  540. ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
  541. Process();
  542. EXPECT_TRUE(result.done_);
  543. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  544. EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
  545. }
  546. class MockMultiServerChannelTestAI
  547. : public MockChannelOptsTest,
  548. public ::testing::WithParamInterface< std::pair<int, bool> > {
  549. public:
  550. MockMultiServerChannelTestAI(bool rotate)
  551. : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
  552. void CheckExample() {
  553. AddrInfoResult result;
  554. struct ares_addrinfo_hints hints = {};
  555. hints.ai_family = AF_INET;
  556. hints.ai_flags = ARES_AI_NOSORT;
  557. ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
  558. Process();
  559. EXPECT_TRUE(result.done_);
  560. EXPECT_EQ(result.status_, ARES_SUCCESS);
  561. EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
  562. EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
  563. }
  564. };
  565. class RotateMultiMockTestAI : public MockMultiServerChannelTestAI {
  566. public:
  567. RotateMultiMockTestAI() : MockMultiServerChannelTestAI(true) {}
  568. };
  569. class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI {
  570. public:
  571. NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(false) {}
  572. };
  573. TEST_P(RotateMultiMockTestAI, ThirdServer) {
  574. struct ares_options opts = {0};
  575. int optmask = 0;
  576. EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
  577. EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE));
  578. ares_destroy_options(&opts);
  579. DNSPacket servfailrsp;
  580. servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
  581. .add_question(new DNSQuestion("www.example.com", T_A));
  582. DNSPacket notimplrsp;
  583. notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
  584. .add_question(new DNSQuestion("www.example.com", T_A));
  585. DNSPacket okrsp;
  586. okrsp.set_response().set_aa()
  587. .add_question(new DNSQuestion("www.example.com", T_A))
  588. .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
  589. EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
  590. .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
  591. EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
  592. .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
  593. EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
  594. .WillOnce(SetReply(servers_[2].get(), &okrsp));
  595. CheckExample();
  596. // Second time around, starts from server [1].
  597. EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
  598. .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
  599. EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
  600. .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
  601. EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
  602. .WillOnce(SetReply(servers_[0].get(), &okrsp));
  603. CheckExample();
  604. // Third time around, starts from server [2].
  605. EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
  606. .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
  607. EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
  608. .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
  609. EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
  610. .WillOnce(SetReply(servers_[1].get(), &okrsp));
  611. CheckExample();
  612. }
  613. TEST_P(NoRotateMultiMockTestAI, ThirdServer) {
  614. struct ares_options opts = {0};
  615. int optmask = 0;
  616. EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
  617. EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
  618. ares_destroy_options(&opts);
  619. DNSPacket servfailrsp;
  620. servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
  621. .add_question(new DNSQuestion("www.example.com", T_A));
  622. DNSPacket notimplrsp;
  623. notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
  624. .add_question(new DNSQuestion("www.example.com", T_A));
  625. DNSPacket okrsp;
  626. okrsp.set_response().set_aa()
  627. .add_question(new DNSQuestion("www.example.com", T_A))
  628. .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
  629. EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
  630. .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
  631. EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
  632. .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
  633. EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
  634. .WillOnce(SetReply(servers_[2].get(), &okrsp));
  635. CheckExample();
  636. // Second time around, still starts from server [0].
  637. EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
  638. .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
  639. EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
  640. .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
  641. EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
  642. .WillOnce(SetReply(servers_[2].get(), &okrsp));
  643. CheckExample();
  644. // Third time around, still starts from server [0].
  645. EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
  646. .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
  647. EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
  648. .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
  649. EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
  650. .WillOnce(SetReply(servers_[2].get(), &okrsp));
  651. CheckExample();
  652. }
  653. TEST_P(MockChannelTestAI, FamilyV4ServiceName) {
  654. DNSPacket rsp4;
  655. rsp4.set_response().set_aa()
  656. .add_question(new DNSQuestion("example.com", T_A))
  657. .add_answer(new DNSARR("example.com", 100, {1, 1, 1, 1}))
  658. .add_answer(new DNSARR("example.com", 100, {2, 2, 2, 2}));
  659. ON_CALL(server_, OnRequest("example.com", T_A))
  660. .WillByDefault(SetReply(&server_, &rsp4));
  661. AddrInfoResult result = {};
  662. struct ares_addrinfo_hints hints = {};
  663. hints.ai_family = AF_INET;
  664. hints.ai_flags = ARES_AI_NOSORT;
  665. ares_getaddrinfo(channel_, "example.com", "http", &hints, AddrInfoCallback, &result);
  666. Process();
  667. EXPECT_TRUE(result.done_);
  668. std::stringstream ss;
  669. ss << result.ai_;
  670. EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str());
  671. }
  672. INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockChannelTestAI,
  673. ::testing::ValuesIn(ares::test::families_modes));
  674. INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockUDPChannelTestAI,
  675. ::testing::ValuesIn(ares::test::families));
  676. INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockTCPChannelTestAI,
  677. ::testing::ValuesIn(ares::test::families));
  678. INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockExtraOptsTestAI,
  679. ::testing::ValuesIn(ares::test::families_modes));
  680. INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockExtraOptsNDots5TestAI,
  681. ::testing::ValuesIn(ares::test::families_modes));
  682. INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI,
  683. ::testing::ValuesIn(ares::test::families_modes));
  684. INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockEDNSChannelTestAI,
  685. ::testing::ValuesIn(ares::test::families_modes));
  686. INSTANTIATE_TEST_SUITE_P(TransportModesAI, RotateMultiMockTestAI,
  687. ::testing::ValuesIn(ares::test::families_modes));
  688. INSTANTIATE_TEST_SUITE_P(TransportModesAI, NoRotateMultiMockTestAI,
  689. ::testing::ValuesIn(ares::test::families_modes));
  690. } // namespace test
  691. } // namespace ares