ares-test-parse-ptr.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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, ParsePtrReplyOK) {
  8. byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
  9. DNSPacket pkt;
  10. pkt.set_qid(0x1234).set_response().set_aa()
  11. .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR))
  12. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
  13. std::vector<byte> data = pkt.data();
  14. struct hostent *host = nullptr;
  15. EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
  16. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  17. ASSERT_NE(nullptr, host);
  18. std::stringstream ss;
  19. ss << HostEnt(host);
  20. EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
  21. ares_free_hostent(host);
  22. }
  23. TEST_F(LibraryTest, ParsePtrReplyCname) {
  24. byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
  25. DNSPacket pkt;
  26. pkt.set_qid(0x1234).set_response().set_aa()
  27. .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR))
  28. .add_answer(new DNSCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"))
  29. .add_answer(new DNSPtrRR("64.48.32.8.in-addr.arpa", 100, "other.com"));
  30. std::vector<byte> data = pkt.data();
  31. struct hostent *host = nullptr;
  32. EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
  33. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  34. ASSERT_NE(nullptr, host);
  35. std::stringstream ss;
  36. ss << HostEnt(host);
  37. EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
  38. ares_free_hostent(host);
  39. }
  40. struct DNSMalformedCnameRR : public DNSCnameRR {
  41. DNSMalformedCnameRR(const std::string& name, int ttl, const std::string& other)
  42. : DNSCnameRR(name, ttl, other) {}
  43. std::vector<byte> data() const {
  44. std::vector<byte> data = DNSRR::data();
  45. std::vector<byte> encname = EncodeString(other_);
  46. encname[0] = encname[0] + 63; // invalid label length
  47. int len = encname.size();
  48. PushInt16(&data, len);
  49. data.insert(data.end(), encname.begin(), encname.end());
  50. return data;
  51. }
  52. };
  53. TEST_F(LibraryTest, ParsePtrReplyMalformedCname) {
  54. byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
  55. DNSPacket pkt;
  56. pkt.set_qid(0x1234).set_response().set_aa()
  57. .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR))
  58. .add_answer(new DNSMalformedCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"))
  59. .add_answer(new DNSPtrRR("64.48.32.8.in-addr.arpa", 100, "other.com"));
  60. std::vector<byte> data = pkt.data();
  61. struct hostent *host = nullptr;
  62. EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
  63. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  64. ASSERT_EQ(nullptr, host);
  65. }
  66. TEST_F(LibraryTest, ParseManyPtrReply) {
  67. byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
  68. DNSPacket pkt;
  69. pkt.set_qid(0x1234).set_response().set_aa()
  70. .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR))
  71. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
  72. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
  73. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
  74. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"))
  75. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other4.com"))
  76. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other5.com"))
  77. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other6.com"))
  78. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other7.com"))
  79. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other8.com"))
  80. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other9.com"));
  81. std::vector<byte> data = pkt.data();
  82. struct hostent *host = nullptr;
  83. EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
  84. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  85. ASSERT_NE(nullptr, host);
  86. ares_free_hostent(host);
  87. }
  88. TEST_F(LibraryTest, ParsePtrReplyAdditional) {
  89. byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
  90. DNSPacket pkt;
  91. pkt.set_qid(0x1234).set_response().set_aa()
  92. .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR))
  93. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 55, "other.com"))
  94. .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "ns1.other.com"))
  95. .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "bb.ns2.other.com"))
  96. .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "ns3.other.com"))
  97. .add_additional(new DNSARR("ns1.other.com", 229, {10,20,30,41}))
  98. .add_additional(new DNSARR("bb.ns2.other.com", 229, {10,20,30,42}))
  99. .add_additional(new DNSARR("ns3.other.com", 229, {10,20,30,43}));
  100. std::vector<byte> data = pkt.data();
  101. struct hostent *host = nullptr;
  102. EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
  103. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  104. ASSERT_NE(nullptr, host);
  105. std::stringstream ss;
  106. ss << HostEnt(host);
  107. EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
  108. ares_free_hostent(host);
  109. }
  110. TEST_F(LibraryTest, ParsePtrReplyErrors) {
  111. byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
  112. DNSPacket pkt;
  113. pkt.set_qid(0x1234).set_response().set_aa()
  114. .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR))
  115. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
  116. std::vector<byte> data;
  117. struct hostent *host = nullptr;
  118. // No question.
  119. pkt.questions_.clear();
  120. data = pkt.data();
  121. EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
  122. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  123. pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR));
  124. // Question != answer
  125. pkt.questions_.clear();
  126. pkt.add_question(new DNSQuestion("99.48.32.16.in-addr.arpa", T_PTR));
  127. data = pkt.data();
  128. EXPECT_EQ(ARES_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
  129. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  130. EXPECT_EQ(nullptr, host);
  131. pkt.questions_.clear();
  132. pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR));
  133. // Two questions.
  134. pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR));
  135. data = pkt.data();
  136. EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
  137. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  138. EXPECT_EQ(nullptr, host);
  139. pkt.questions_.clear();
  140. pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR));
  141. // Wrong sort of answer.
  142. pkt.answers_.clear();
  143. pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
  144. data = pkt.data();
  145. EXPECT_EQ(ARES_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
  146. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  147. EXPECT_EQ(nullptr, host);
  148. pkt.answers_.clear();
  149. pkt.add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
  150. // No answer.
  151. pkt.answers_.clear();
  152. data = pkt.data();
  153. EXPECT_EQ(ARES_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
  154. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  155. EXPECT_EQ(nullptr, host);
  156. pkt.add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
  157. // Truncated packets.
  158. data = pkt.data();
  159. for (size_t len = 1; len < data.size(); len++) {
  160. EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), len,
  161. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  162. EXPECT_EQ(nullptr, host);
  163. }
  164. // Truncated packets with CNAME.
  165. pkt.add_answer(new DNSCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"));
  166. data = pkt.data();
  167. for (size_t len = 1; len < data.size(); len++) {
  168. EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), len,
  169. addrv4, sizeof(addrv4), AF_INET, &host, NULL));
  170. EXPECT_EQ(nullptr, host);
  171. }
  172. }
  173. TEST_F(LibraryTest, ParsePtrReplyAllocFailSome) {
  174. byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
  175. DNSPacket pkt;
  176. pkt.set_qid(0x1234).set_response().set_aa()
  177. .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR))
  178. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
  179. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
  180. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
  181. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"));
  182. std::vector<byte> data = pkt.data();
  183. struct hostent *host = nullptr;
  184. for (int ii = 1; ii <= 18; ii++) {
  185. ClearFails();
  186. SetAllocFail(ii);
  187. EXPECT_EQ(ARES_ENOMEM, ares_parse_ptr_reply(data.data(), data.size(),
  188. addrv4, sizeof(addrv4), AF_INET, &host, NULL)) << ii;
  189. }
  190. }
  191. TEST_F(LibraryTest, ParsePtrReplyAllocFailMany) {
  192. byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
  193. DNSPacket pkt;
  194. pkt.set_qid(0x1234).set_response().set_aa()
  195. .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR))
  196. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
  197. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
  198. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
  199. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"))
  200. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other4.com"))
  201. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other5.com"))
  202. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other6.com"))
  203. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other7.com"))
  204. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other8.com"))
  205. .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other9.com"));
  206. std::vector<byte> data = pkt.data();
  207. struct hostent *host = nullptr;
  208. for (int ii = 1; ii <= 63; ii++) {
  209. ClearFails();
  210. SetAllocFail(ii);
  211. int rc = ares_parse_ptr_reply(data.data(), data.size(),
  212. addrv4, sizeof(addrv4), AF_INET, &host, NULL);
  213. if (rc != ARES_ENOMEM) {
  214. EXPECT_EQ(ARES_SUCCESS, rc);
  215. ares_free_hostent(host);
  216. host = nullptr;
  217. }
  218. }
  219. }
  220. } // namespace test
  221. } // namespace ares