ares-test-parse-a.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. #include "ares-test.h"
  2. #include "dns-proto.h"
  3. #include <sstream>
  4. #include <vector>
  5. namespace ares {
  6. namespace test {
  7. TEST_F(LibraryTest, ParseAReplyOK) {
  8. DNSPacket pkt;
  9. pkt.set_qid(0x1234).set_response().set_aa()
  10. .add_question(new DNSQuestion("example.com", ns_t_a))
  11. .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5}))
  12. .add_answer(new DNSAaaaRR("example.com", 0x01020304, {0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5}));
  13. std::vector<byte> data = {
  14. 0x12, 0x34, // qid
  15. 0x84, // response + query + AA + not-TC + not-RD
  16. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  17. 0x00, 0x01, // num questions
  18. 0x00, 0x02, // num answer RRs
  19. 0x00, 0x00, // num authority RRs
  20. 0x00, 0x00, // num additional RRs
  21. // Question
  22. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  23. 0x03, 'c', 'o', 'm',
  24. 0x00,
  25. 0x00, 0x01, // type A
  26. 0x00, 0x01, // class IN
  27. // Answer 1
  28. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  29. 0x03, 'c', 'o', 'm',
  30. 0x00,
  31. 0x00, 0x01, // RR type
  32. 0x00, 0x01, // class IN
  33. 0x01, 0x02, 0x03, 0x04, // TTL
  34. 0x00, 0x04, // rdata length
  35. 0x02, 0x03, 0x04, 0x05,
  36. // Answer 2
  37. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  38. 0x03, 'c', 'o', 'm',
  39. 0x00,
  40. 0x00, 0x1c, // RR type
  41. 0x00, 0x01, // class IN
  42. 0x01, 0x02, 0x03, 0x04, // TTL
  43. 0x00, 0x10, // rdata length
  44. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x05,
  45. };
  46. EXPECT_EQ(data, pkt.data());
  47. struct hostent *host = nullptr;
  48. struct ares_addrttl info[5];
  49. int count = 5;
  50. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  51. &host, info, &count));
  52. EXPECT_EQ(1, count);
  53. EXPECT_EQ(0x01020304, info[0].ttl);
  54. unsigned long expected_addr = htonl(0x02030405);
  55. EXPECT_EQ(expected_addr, info[0].ipaddr.s_addr);
  56. EXPECT_EQ("2.3.4.5", AddressToString(&(info[0].ipaddr), 4));
  57. ASSERT_NE(nullptr, host);
  58. std::stringstream ss;
  59. ss << HostEnt(host);
  60. EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
  61. ares_free_hostent(host);
  62. // Repeat without providing a hostent
  63. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  64. nullptr, info, &count));
  65. EXPECT_EQ(1, count);
  66. EXPECT_EQ(0x01020304, info[0].ttl);
  67. EXPECT_EQ(expected_addr, info[0].ipaddr.s_addr);
  68. EXPECT_EQ("2.3.4.5", AddressToString(&(info[0].ipaddr), 4));
  69. }
  70. TEST_F(LibraryTest, ParseMalformedAReply) {
  71. std::vector<byte> data = {
  72. 0x12, 0x34, // [0:2) qid
  73. 0x84, // [2] response + query + AA + not-TC + not-RD
  74. 0x00, // [3] not-RA + not-Z + not-AD + not-CD + rc=NoError
  75. 0x00, 0x01, // [4:6) num questions
  76. 0x00, 0x02, // [6:8) num answer RRs
  77. 0x00, 0x00, // [8:10) num authority RRs
  78. 0x00, 0x00, // [10:12) num additional RRs
  79. // Question
  80. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', // [12:20)
  81. 0x03, 'c', 'o', 'm', // [20,24)
  82. 0x00, // [24]
  83. 0x00, 0x01, // [25:26) type A
  84. 0x00, 0x01, // [27:29) class IN
  85. // Answer 1
  86. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', // [29:37)
  87. 0x03, 'c', 'o', 'm', // [37:41)
  88. 0x00, // [41]
  89. 0x00, 0x01, // [42:44) RR type
  90. 0x00, 0x01, // [44:46) class IN
  91. 0x01, 0x02, 0x03, 0x04, // [46:50) TTL
  92. 0x00, 0x04, // [50:52) rdata length
  93. 0x02, 0x03, 0x04, 0x05, // [52,56)
  94. };
  95. struct hostent *host = nullptr;
  96. struct ares_addrttl info[2];
  97. int count = 2;
  98. // Invalid RR-len.
  99. std::vector<byte> invalid_rrlen(data);
  100. invalid_rrlen[51] = 180;
  101. EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(invalid_rrlen.data(), invalid_rrlen.size(),
  102. &host, info, &count));
  103. // Truncate mid-question.
  104. EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), 26,
  105. &host, info, &count));
  106. // Truncate mid-answer.
  107. EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), 42,
  108. &host, info, &count));
  109. }
  110. TEST_F(LibraryTest, ParseAReplyNoData) {
  111. DNSPacket pkt;
  112. pkt.set_qid(0x1234).set_response().set_aa()
  113. .add_question(new DNSQuestion("example.com", ns_t_a));
  114. std::vector<byte> data = pkt.data();
  115. struct hostent *host = nullptr;
  116. struct ares_addrttl info[2];
  117. int count = 2;
  118. EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
  119. &host, info, &count));
  120. EXPECT_EQ(0, count);
  121. EXPECT_EQ(nullptr, host);
  122. // Again but with a CNAME.
  123. pkt.add_answer(new DNSCnameRR("example.com", 200, "c.example.com"));
  124. data = pkt.data();
  125. // Expect success as per https://github.com/c-ares/c-ares/commit/2c63440127feed70ccefb148b8f938a2df6c15f8
  126. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  127. &host, info, &count));
  128. EXPECT_EQ(0, count);
  129. EXPECT_NE(nullptr, host);
  130. std::stringstream ss;
  131. ss << HostEnt(host);
  132. EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[]}", ss.str());
  133. ares_free_hostent(host);
  134. }
  135. TEST_F(LibraryTest, ParseAReplyVariantA) {
  136. DNSPacket pkt;
  137. pkt.set_qid(6366).set_rd().set_ra()
  138. .add_question(new DNSQuestion("mit.edu", ns_t_a))
  139. .add_answer(new DNSARR("mit.edu", 52, {18,7,22,69}))
  140. .add_auth(new DNSNsRR("mit.edu", 292, "W20NS.mit.edu"))
  141. .add_auth(new DNSNsRR("mit.edu", 292, "BITSY.mit.edu"))
  142. .add_auth(new DNSNsRR("mit.edu", 292, "STRAWB.mit.edu"))
  143. .add_additional(new DNSARR("STRAWB.mit.edu", 292, {18,71,0,151}));
  144. struct hostent *host = nullptr;
  145. struct ares_addrttl info[2];
  146. int count = 2;
  147. std::vector<byte> data = pkt.data();
  148. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  149. &host, info, &count));
  150. EXPECT_EQ(1, count);
  151. EXPECT_EQ("18.7.22.69", AddressToString(&(info[0].ipaddr), 4));
  152. EXPECT_EQ(52, info[0].ttl);
  153. ares_free_hostent(host);
  154. }
  155. TEST_F(LibraryTest, ParseAReplyJustCname) {
  156. DNSPacket pkt;
  157. pkt.set_qid(6366).set_rd().set_ra()
  158. .add_question(new DNSQuestion("mit.edu", ns_t_a))
  159. .add_answer(new DNSCnameRR("mit.edu", 52, "other.mit.edu"));
  160. struct hostent *host = nullptr;
  161. struct ares_addrttl info[2];
  162. int count = 2;
  163. std::vector<byte> data = pkt.data();
  164. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  165. &host, info, &count));
  166. EXPECT_EQ(0, count);
  167. ASSERT_NE(nullptr, host);
  168. std::stringstream ss;
  169. ss << HostEnt(host);
  170. EXPECT_EQ("{'other.mit.edu' aliases=[mit.edu] addrs=[]}", ss.str());
  171. ares_free_hostent(host);
  172. }
  173. TEST_F(LibraryTest, ParseAReplyVariantCname) {
  174. DNSPacket pkt;
  175. pkt.set_qid(6366).set_rd().set_ra()
  176. .add_question(new DNSQuestion("query.example.com", ns_t_a))
  177. .add_answer(new DNSCnameRR("query.example.com", 200, "redirect.query.example.com"))
  178. .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,22}))
  179. .add_auth(new DNSNsRR("example.com", 218, "aa.ns1.example.com"))
  180. .add_auth(new DNSNsRR("example.com", 218, "ns2.example.com"))
  181. .add_auth(new DNSNsRR("example.com", 218, "ns3.example.com"))
  182. .add_auth(new DNSNsRR("example.com", 218, "ns4.example.com"))
  183. .add_additional(new DNSARR("aa.ns1.example.com", 218, {129,97,1,1}))
  184. .add_additional(new DNSARR("ns2.example.com", 218, {129,97,1,2}))
  185. .add_additional(new DNSARR("ns3.example.com", 218, {129,97,1,3}))
  186. .add_additional(new DNSARR("ns4.example.com", 218, {129,97,1,4}));
  187. struct hostent *host = nullptr;
  188. struct ares_addrttl info[2];
  189. int count = 2;
  190. std::vector<byte> data = pkt.data();
  191. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  192. &host, info, &count));
  193. EXPECT_EQ(1, count);
  194. EXPECT_EQ("129.97.123.22", AddressToString(&(info[0].ipaddr), 4));
  195. // TTL is reduced to match CNAME's.
  196. EXPECT_EQ(200, info[0].ttl);
  197. ares_free_hostent(host);
  198. // Repeat parsing without places to put the results.
  199. count = 0;
  200. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  201. nullptr, info, &count));
  202. }
  203. TEST_F(LibraryTest, ParseAReplyVariantCnameChain) {
  204. DNSPacket pkt;
  205. pkt.set_qid(6366).set_rd().set_ra()
  206. .add_question(new DNSQuestion("c1.localhost", ns_t_a))
  207. .add_answer(new DNSCnameRR("c1.localhost", 604800, "c2.localhost"))
  208. .add_answer(new DNSCnameRR("c2.localhost", 604800, "c3.localhost"))
  209. .add_answer(new DNSCnameRR("c3.localhost", 604800, "c4.localhost"))
  210. .add_answer(new DNSARR("c4.localhost", 604800, {8,8,8,8}))
  211. .add_auth(new DNSNsRR("localhost", 604800, "localhost"))
  212. .add_additional(new DNSARR("localhost", 604800, {127,0,0,1}))
  213. .add_additional(new DNSAaaaRR("localhost", 604800,
  214. {0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  215. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}));
  216. struct hostent *host = nullptr;
  217. struct ares_addrttl info[2];
  218. int count = 2;
  219. std::vector<byte> data = pkt.data();
  220. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  221. &host, info, &count));
  222. EXPECT_EQ(1, count);
  223. EXPECT_EQ("8.8.8.8", AddressToString(&(info[0].ipaddr), 4));
  224. EXPECT_EQ(604800, info[0].ttl);
  225. ares_free_hostent(host);
  226. }
  227. TEST_F(LibraryTest, DISABLED_ParseAReplyVariantCnameLast) {
  228. DNSPacket pkt;
  229. pkt.set_qid(6366).set_rd().set_ra()
  230. .add_question(new DNSQuestion("query.example.com", ns_t_a))
  231. .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,221}))
  232. .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,222}))
  233. .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,223}))
  234. .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,224}))
  235. .add_answer(new DNSCnameRR("query.example.com", 60, "redirect.query.example.com"))
  236. .add_additional(new DNSTxtRR("query.example.com", 60, {"text record"}));
  237. struct hostent *host = nullptr;
  238. struct ares_addrttl info[8];
  239. int count = 8;
  240. std::vector<byte> data = pkt.data();
  241. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  242. &host, info, &count));
  243. EXPECT_EQ(4, count);
  244. EXPECT_EQ("129.97.123.221", AddressToString(&(info[0].ipaddr), 4));
  245. EXPECT_EQ("129.97.123.222", AddressToString(&(info[1].ipaddr), 4));
  246. EXPECT_EQ("129.97.123.223", AddressToString(&(info[2].ipaddr), 4));
  247. EXPECT_EQ("129.97.123.224", AddressToString(&(info[3].ipaddr), 4));
  248. EXPECT_EQ(300, info[0].ttl);
  249. EXPECT_EQ(300, info[1].ttl);
  250. EXPECT_EQ(300, info[2].ttl);
  251. EXPECT_EQ(300, info[3].ttl);
  252. ares_free_hostent(host);
  253. }
  254. TEST_F(LibraryTest, ParseAReplyErrors) {
  255. DNSPacket pkt;
  256. pkt.set_qid(0x1234).set_response().set_aa()
  257. .add_question(new DNSQuestion("example.com", ns_t_a))
  258. .add_answer(new DNSARR("example.com", 100, {0x02, 0x03, 0x04, 0x05}));
  259. std::vector<byte> data;
  260. struct hostent *host = nullptr;
  261. struct ares_addrttl info[2];
  262. int count = 2;
  263. // No question.
  264. pkt.questions_.clear();
  265. data = pkt.data();
  266. EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
  267. &host, info, &count));
  268. EXPECT_EQ(nullptr, host);
  269. pkt.add_question(new DNSQuestion("example.com", ns_t_a));
  270. // Question != answer
  271. pkt.questions_.clear();
  272. pkt.add_question(new DNSQuestion("Axample.com", ns_t_a));
  273. data = pkt.data();
  274. EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
  275. &host, info, &count));
  276. EXPECT_EQ(nullptr, host);
  277. pkt.questions_.clear();
  278. pkt.add_question(new DNSQuestion("example.com", ns_t_a));
  279. #ifdef DISABLED
  280. // Not a response.
  281. pkt.set_response(false);
  282. data = pkt.data();
  283. EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
  284. &host, info, &count));
  285. EXPECT_EQ(nullptr, host);
  286. pkt.set_response(true);
  287. // Bad return code.
  288. pkt.set_rcode(ns_r_formerr);
  289. data = pkt.data();
  290. EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
  291. &host, info, &count));
  292. EXPECT_EQ(nullptr, host);
  293. pkt.set_rcode(ns_r_noerror);
  294. #endif
  295. // Two questions
  296. pkt.add_question(new DNSQuestion("example.com", ns_t_a));
  297. data = pkt.data();
  298. EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
  299. &host, info, &count));
  300. EXPECT_EQ(nullptr, host);
  301. pkt.questions_.clear();
  302. pkt.add_question(new DNSQuestion("example.com", ns_t_a));
  303. // Wrong sort of answer.
  304. pkt.answers_.clear();
  305. pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
  306. data = pkt.data();
  307. EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
  308. &host, info, &count));
  309. EXPECT_EQ(nullptr, host);
  310. pkt.answers_.clear();
  311. pkt.add_answer(new DNSARR("example.com", 100, {0x02, 0x03, 0x04, 0x05}));
  312. // No answer.
  313. pkt.answers_.clear();
  314. data = pkt.data();
  315. EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
  316. &host, info, &count));
  317. EXPECT_EQ(nullptr, host);
  318. pkt.add_answer(new DNSARR("example.com", 100, {0x02, 0x03, 0x04, 0x05}));
  319. // Truncated packets.
  320. data = pkt.data();
  321. for (size_t len = 1; len < data.size(); len++) {
  322. EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), len,
  323. &host, info, &count));
  324. EXPECT_EQ(nullptr, host);
  325. EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), len,
  326. nullptr, info, &count));
  327. }
  328. }
  329. TEST_F(LibraryTest, ParseAReplyAllocFail) {
  330. DNSPacket pkt;
  331. pkt.set_qid(0x1234).set_response().set_aa()
  332. .add_question(new DNSQuestion("example.com", ns_t_a))
  333. .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
  334. .add_answer(new DNSARR("c.example.com", 500, {0x02, 0x03, 0x04, 0x05}));
  335. std::vector<byte> data = pkt.data();
  336. struct hostent *host = nullptr;
  337. struct ares_addrttl info[2];
  338. int count = 2;
  339. for (int ii = 1; ii <= 8; ii++) {
  340. ClearFails();
  341. SetAllocFail(ii);
  342. EXPECT_EQ(ARES_ENOMEM, ares_parse_a_reply(data.data(), data.size(),
  343. &host, info, &count)) << ii;
  344. EXPECT_EQ(nullptr, host);
  345. }
  346. }
  347. } // namespace test
  348. } // namespace ares