ares-test-parse-txt.cc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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, ParseTxtReplyOK) {
  8. DNSPacket pkt;
  9. std::string expected1 = "txt1.example.com";
  10. std::string expected2a = "txt2a";
  11. std::string expected2b("ABC\0ABC", 7);
  12. pkt.set_qid(0x1234).set_response().set_aa()
  13. .add_question(new DNSQuestion("example.com", T_MX))
  14. .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
  15. .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
  16. std::vector<byte> data = pkt.data();
  17. struct ares_txt_reply* txt = nullptr;
  18. EXPECT_EQ(ARES_SUCCESS, ares_parse_txt_reply(data.data(), data.size(), &txt));
  19. ASSERT_NE(nullptr, txt);
  20. EXPECT_EQ(std::vector<byte>(expected1.data(), expected1.data() + expected1.size()),
  21. std::vector<byte>(txt->txt, txt->txt + txt->length));
  22. struct ares_txt_reply* txt2 = txt->next;
  23. ASSERT_NE(nullptr, txt2);
  24. EXPECT_EQ(std::vector<byte>(expected2a.data(), expected2a.data() + expected2a.size()),
  25. std::vector<byte>(txt2->txt, txt2->txt + txt2->length));
  26. struct ares_txt_reply* txt3 = txt2->next;
  27. ASSERT_NE(nullptr, txt3);
  28. EXPECT_EQ(std::vector<byte>(expected2b.data(), expected2b.data() + expected2b.size()),
  29. std::vector<byte>(txt3->txt, txt3->txt + txt3->length));
  30. EXPECT_EQ(nullptr, txt3->next);
  31. ares_free_data(txt);
  32. }
  33. TEST_F(LibraryTest, ParseTxtExtReplyOK) {
  34. DNSPacket pkt;
  35. std::string expected1 = "txt1.example.com";
  36. std::string expected2a = "txt2a";
  37. std::string expected2b("ABC\0ABC", 7);
  38. pkt.set_qid(0x1234).set_response().set_aa()
  39. .add_question(new DNSQuestion("example.com", T_MX))
  40. .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
  41. .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
  42. std::vector<byte> data = pkt.data();
  43. struct ares_txt_ext* txt = nullptr;
  44. EXPECT_EQ(ARES_SUCCESS, ares_parse_txt_reply_ext(data.data(), data.size(), &txt));
  45. ASSERT_NE(nullptr, txt);
  46. EXPECT_EQ(std::vector<byte>(expected1.data(), expected1.data() + expected1.size()),
  47. std::vector<byte>(txt->txt, txt->txt + txt->length));
  48. EXPECT_EQ(1, txt->record_start);
  49. struct ares_txt_ext* txt2 = txt->next;
  50. ASSERT_NE(nullptr, txt2);
  51. EXPECT_EQ(std::vector<byte>(expected2a.data(), expected2a.data() + expected2a.size()),
  52. std::vector<byte>(txt2->txt, txt2->txt + txt2->length));
  53. EXPECT_EQ(1, txt2->record_start);
  54. struct ares_txt_ext* txt3 = txt2->next;
  55. ASSERT_NE(nullptr, txt3);
  56. EXPECT_EQ(std::vector<byte>(expected2b.data(), expected2b.data() + expected2b.size()),
  57. std::vector<byte>(txt3->txt, txt3->txt + txt3->length));
  58. EXPECT_EQ(nullptr, txt3->next);
  59. EXPECT_EQ(0, txt3->record_start);
  60. ares_free_data(txt);
  61. }
  62. TEST_F(LibraryTest, ParseTxtMalformedReply1) {
  63. std::vector<byte> data = {
  64. 0x12, 0x34, // qid
  65. 0x84, // response + query + AA + not-TC + not-RD
  66. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  67. 0x00, 0x01, // num questions
  68. 0x00, 0x01, // num answer RRs
  69. 0x00, 0x00, // num authority RRs
  70. 0x00, 0x00, // num additional RRs
  71. // Question
  72. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  73. 0x03, 'c', 'o', 'm',
  74. 0x00,
  75. 0x00, 0x10, // type TXT
  76. 0x00, 0x01, // class IN
  77. // Answer 1
  78. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  79. 0x03, 'c', 'o', 'm',
  80. 0x00,
  81. 0x00, 0x10, // RR type
  82. 0x00, 0x01, // class IN
  83. 0x01, 0x02, 0x03, 0x04, // TTL
  84. 0x00, 0x03, // rdata length
  85. 0x12, 'a', 'b', // invalid length
  86. };
  87. struct ares_txt_reply* txt = nullptr;
  88. EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
  89. ASSERT_EQ(nullptr, txt);
  90. }
  91. TEST_F(LibraryTest, ParseTxtMalformedReply2) {
  92. std::vector<byte> data = {
  93. 0x12, 0x34, // qid
  94. 0x84, // response + query + AA + not-TC + not-RD
  95. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  96. 0x00, 0x01, // num questions
  97. 0x00, 0x01, // num answer RRs
  98. 0x00, 0x00, // num authority RRs
  99. 0x00, 0x00, // num additional RRs
  100. // Question
  101. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  102. 0x03, 'c', 'o', 'm',
  103. 0x00,
  104. 0x00, 0x10, // type TXT
  105. 0x00, 0x01, // class IN
  106. // Answer 1
  107. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  108. 0x03, 'c', 'o', 'm',
  109. 0x00,
  110. 0x00, 0x10, // RR type
  111. // truncated
  112. };
  113. struct ares_txt_reply* txt = nullptr;
  114. EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
  115. ASSERT_EQ(nullptr, txt);
  116. }
  117. TEST_F(LibraryTest, ParseTxtMalformedReply3) {
  118. std::vector<byte> data = {
  119. 0x12, 0x34, // qid
  120. 0x84, // response + query + AA + not-TC + not-RD
  121. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  122. 0x00, 0x01, // num questions
  123. 0x00, 0x01, // num answer RRs
  124. 0x00, 0x00, // num authority RRs
  125. 0x00, 0x00, // num additional RRs
  126. // Question
  127. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  128. 0x03, 'c', 'o', 'm',
  129. 0x00,
  130. 0x00, 0x10, // type TXT
  131. 0x00, 0x01, // class IN
  132. // Answer 1
  133. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  134. 0x03, 'c', 'o', 'm',
  135. 0x00,
  136. 0x00, 0x10, // RR type
  137. 0x00, 0x01, // class IN
  138. 0x01, 0x02, 0x03, 0x04, // TTL
  139. 0x00, 0x13, // rdata length INVALID
  140. 0x02, 'a', 'b',
  141. };
  142. struct ares_txt_reply* txt = nullptr;
  143. EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
  144. ASSERT_EQ(nullptr, txt);
  145. }
  146. TEST_F(LibraryTest, ParseTxtMalformedReply4) {
  147. std::vector<byte> data = {
  148. 0x12, 0x34, // qid
  149. 0x84, // response + query + AA + not-TC + not-RD
  150. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  151. 0x00, 0x01, // num questions
  152. 0x00, 0x01, // num answer RRs
  153. 0x00, 0x00, // num authority RRs
  154. 0x00, 0x00, // num additional RRs
  155. // Question
  156. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  157. 0x03, 'c', 'o', 'm',
  158. 0x00,
  159. 0x00, 0x10, // type TXT
  160. 0x00, // TRUNCATED
  161. };
  162. struct ares_txt_reply* txt = nullptr;
  163. EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
  164. ASSERT_EQ(nullptr, txt);
  165. }
  166. TEST_F(LibraryTest, ParseTxtReplyErrors) {
  167. DNSPacket pkt;
  168. std::string expected1 = "txt1.example.com";
  169. std::string expected2a = "txt2a";
  170. std::string expected2b = "txt2b";
  171. pkt.set_qid(0x1234).set_response().set_aa()
  172. .add_question(new DNSQuestion("example.com", T_MX))
  173. .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
  174. .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
  175. .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
  176. std::vector<byte> data = pkt.data();
  177. struct ares_txt_reply* txt = nullptr;
  178. // No question.
  179. pkt.questions_.clear();
  180. data = pkt.data();
  181. txt = nullptr;
  182. EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
  183. EXPECT_EQ(nullptr, txt);
  184. pkt.add_question(new DNSQuestion("example.com", T_MX));
  185. #ifdef DISABLED
  186. // Question != answer
  187. pkt.questions_.clear();
  188. pkt.add_question(new DNSQuestion("Axample.com", T_TXT));
  189. data = pkt.data();
  190. EXPECT_EQ(ARES_ENODATA, ares_parse_txt_reply(data.data(), data.size(), &txt));
  191. pkt.questions_.clear();
  192. pkt.add_question(new DNSQuestion("example.com", T_TXT));
  193. #endif
  194. // Two questions.
  195. pkt.add_question(new DNSQuestion("example.com", T_MX));
  196. data = pkt.data();
  197. txt = nullptr;
  198. EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
  199. EXPECT_EQ(nullptr, txt);
  200. pkt.questions_.clear();
  201. pkt.add_question(new DNSQuestion("example.com", T_MX));
  202. // No answer.
  203. pkt.answers_.clear();
  204. data = pkt.data();
  205. txt = nullptr;
  206. EXPECT_EQ(ARES_ENODATA, ares_parse_txt_reply(data.data(), data.size(), &txt));
  207. EXPECT_EQ(nullptr, txt);
  208. pkt.add_answer(new DNSTxtRR("example.com", 100, {expected1}));
  209. // Truncated packets.
  210. for (size_t len = 1; len < data.size(); len++) {
  211. txt = nullptr;
  212. EXPECT_NE(ARES_SUCCESS, ares_parse_txt_reply(data.data(), len, &txt));
  213. EXPECT_EQ(nullptr, txt);
  214. }
  215. }
  216. TEST_F(LibraryTest, ParseTxtReplyAllocFail) {
  217. DNSPacket pkt;
  218. std::string expected1 = "txt1.example.com";
  219. std::string expected2a = "txt2a";
  220. std::string expected2b = "txt2b";
  221. pkt.set_qid(0x1234).set_response().set_aa()
  222. .add_question(new DNSQuestion("example.com", T_MX))
  223. .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
  224. .add_answer(new DNSTxtRR("c.example.com", 100, {expected1}))
  225. .add_answer(new DNSTxtRR("c.example.com", 100, {expected1}))
  226. .add_answer(new DNSTxtRR("c.example.com", 100, {expected2a, expected2b}));
  227. std::vector<byte> data = pkt.data();
  228. struct ares_txt_reply* txt = nullptr;
  229. for (int ii = 1; ii <= 13; ii++) {
  230. ClearFails();
  231. SetAllocFail(ii);
  232. EXPECT_EQ(ARES_ENOMEM, ares_parse_txt_reply(data.data(), data.size(), &txt)) << ii;
  233. }
  234. }
  235. } // namespace test
  236. } // namespace ares