ares-test-parse.cc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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, ParseRootName) {
  8. DNSPacket pkt;
  9. pkt.set_qid(0x1234).set_response().set_aa()
  10. .add_question(new DNSQuestion(".", T_A))
  11. .add_answer(new DNSARR(".", 100, {0x02, 0x03, 0x04, 0x05}));
  12. std::vector<byte> data = pkt.data();
  13. struct hostent *host = nullptr;
  14. struct ares_addrttl info[2];
  15. int count = 2;
  16. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  17. &host, info, &count));
  18. EXPECT_EQ(1, count);
  19. std::stringstream ss;
  20. ss << HostEnt(host);
  21. EXPECT_EQ("{'' aliases=[] addrs=[2.3.4.5]}", ss.str());
  22. ares_free_hostent(host);
  23. }
  24. TEST_F(LibraryTest, ParseIndirectRootName) {
  25. std::vector<byte> data = {
  26. 0x12, 0x34, // qid
  27. 0x84, // response + query + AA + not-TC + not-RD
  28. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  29. 0x00, 0x01, // num questions
  30. 0x00, 0x01, // num answer RRs
  31. 0x00, 0x00, // num authority RRs
  32. 0x00, 0x00, // num additional RRs
  33. // Question
  34. 0xC0, 0x04, // weird: pointer to a random zero earlier in the message
  35. 0x00, 0x01, // type A
  36. 0x00, 0x01, // class IN
  37. // Answer 1
  38. 0xC0, 0x04,
  39. 0x00, 0x01, // RR type
  40. 0x00, 0x01, // class IN
  41. 0x01, 0x02, 0x03, 0x04, // TTL
  42. 0x00, 0x04, // rdata length
  43. 0x02, 0x03, 0x04, 0x05,
  44. };
  45. struct hostent *host = nullptr;
  46. struct ares_addrttl info[2];
  47. int count = 2;
  48. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  49. &host, info, &count));
  50. EXPECT_EQ(1, count);
  51. std::stringstream ss;
  52. ss << HostEnt(host);
  53. EXPECT_EQ("{'' aliases=[] addrs=[2.3.4.5]}", ss.str());
  54. ares_free_hostent(host);
  55. }
  56. #if 0 /* We are validating hostnames now, its not clear how this would ever be valid */
  57. TEST_F(LibraryTest, ParseEscapedName) {
  58. std::vector<byte> data = {
  59. 0x12, 0x34, // qid
  60. 0x84, // response + query + AA + not-TC + not-RD
  61. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  62. 0x00, 0x01, // num questions
  63. 0x00, 0x01, // num answer RRs
  64. 0x00, 0x00, // num authority RRs
  65. 0x00, 0x00, // num additional RRs
  66. // Question
  67. 0x05, 'a', '\\', 'b', '.', 'c',
  68. 0x03, 'c', 'o', 'm',
  69. 0x00,
  70. 0x00, 0x01, // type A
  71. 0x00, 0x01, // class IN
  72. // Answer 1
  73. 0x05, 'a', '\\', 'b', '.', 'c',
  74. 0x03, 'c', 'o', 'm',
  75. 0x00,
  76. 0x00, 0x01, // RR type
  77. 0x00, 0x01, // class IN
  78. 0x01, 0x02, 0x03, 0x04, // TTL
  79. 0x00, 0x04, // rdata length
  80. 0x02, 0x03, 0x04, 0x05,
  81. };
  82. struct hostent *host = nullptr;
  83. struct ares_addrttl info[2];
  84. int count = 2;
  85. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  86. &host, info, &count));
  87. EXPECT_EQ(1, count);
  88. HostEnt hent(host);
  89. std::stringstream ss;
  90. ss << hent;
  91. // The printable name is expanded with escapes.
  92. EXPECT_EQ(11, hent.name_.size());
  93. EXPECT_EQ('a', hent.name_[0]);
  94. EXPECT_EQ('\\', hent.name_[1]);
  95. EXPECT_EQ('\\', hent.name_[2]);
  96. EXPECT_EQ('b', hent.name_[3]);
  97. EXPECT_EQ('\\', hent.name_[4]);
  98. EXPECT_EQ('.', hent.name_[5]);
  99. EXPECT_EQ('c', hent.name_[6]);
  100. ares_free_hostent(host);
  101. }
  102. #endif
  103. TEST_F(LibraryTest, ParsePartialCompressedName) {
  104. std::vector<byte> data = {
  105. 0x12, 0x34, // qid
  106. 0x84, // response + query + AA + not-TC + not-RD
  107. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  108. 0x00, 0x01, // num questions
  109. 0x00, 0x01, // num answer RRs
  110. 0x00, 0x00, // num authority RRs
  111. 0x00, 0x00, // num additional RRs
  112. // Question
  113. 0x03, 'w', 'w', 'w',
  114. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  115. 0x03, 'c', 'o', 'm',
  116. 0x00,
  117. 0x00, 0x01, // type A
  118. 0x00, 0x01, // class IN
  119. // Answer 1
  120. 0x03, 'w', 'w', 'w',
  121. 0xc0, 0x10, // offset 16
  122. 0x00, 0x01, // RR type
  123. 0x00, 0x01, // class IN
  124. 0x01, 0x02, 0x03, 0x04, // TTL
  125. 0x00, 0x04, // rdata length
  126. 0x02, 0x03, 0x04, 0x05,
  127. };
  128. struct hostent *host = nullptr;
  129. struct ares_addrttl info[2];
  130. int count = 2;
  131. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  132. &host, info, &count));
  133. ASSERT_NE(nullptr, host);
  134. std::stringstream ss;
  135. ss << HostEnt(host);
  136. EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
  137. ares_free_hostent(host);
  138. }
  139. TEST_F(LibraryTest, ParseFullyCompressedName) {
  140. std::vector<byte> data = {
  141. 0x12, 0x34, // qid
  142. 0x84, // response + query + AA + not-TC + not-RD
  143. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  144. 0x00, 0x01, // num questions
  145. 0x00, 0x01, // num answer RRs
  146. 0x00, 0x00, // num authority RRs
  147. 0x00, 0x00, // num additional RRs
  148. // Question
  149. 0x03, 'w', 'w', 'w',
  150. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  151. 0x03, 'c', 'o', 'm',
  152. 0x00,
  153. 0x00, 0x01, // type A
  154. 0x00, 0x01, // class IN
  155. // Answer 1
  156. 0xc0, 0x0c, // offset 12
  157. 0x00, 0x01, // RR type
  158. 0x00, 0x01, // class IN
  159. 0x01, 0x02, 0x03, 0x04, // TTL
  160. 0x00, 0x04, // rdata length
  161. 0x02, 0x03, 0x04, 0x05,
  162. };
  163. struct hostent *host = nullptr;
  164. struct ares_addrttl info[2];
  165. int count = 2;
  166. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  167. &host, info, &count));
  168. ASSERT_NE(nullptr, host);
  169. std::stringstream ss;
  170. ss << HostEnt(host);
  171. EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
  172. ares_free_hostent(host);
  173. }
  174. TEST_F(LibraryTest, ParseFullyCompressedName2) {
  175. std::vector<byte> data = {
  176. 0x12, 0x34, // qid
  177. 0x84, // response + query + AA + not-TC + not-RD
  178. 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
  179. 0x00, 0x01, // num questions
  180. 0x00, 0x01, // num answer RRs
  181. 0x00, 0x00, // num authority RRs
  182. 0x00, 0x00, // num additional RRs
  183. // Question
  184. 0xC0, 0x12, // pointer to later in message
  185. 0x00, 0x01, // type A
  186. 0x00, 0x01, // class IN
  187. // Answer 1
  188. 0x03, 'w', 'w', 'w',
  189. 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
  190. 0x03, 'c', 'o', 'm',
  191. 0x00,
  192. 0x00, 0x01, // RR type
  193. 0x00, 0x01, // class IN
  194. 0x01, 0x02, 0x03, 0x04, // TTL
  195. 0x00, 0x04, // rdata length
  196. 0x02, 0x03, 0x04, 0x05,
  197. };
  198. struct hostent *host = nullptr;
  199. struct ares_addrttl info[2];
  200. int count = 2;
  201. EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
  202. &host, info, &count));
  203. ASSERT_NE(nullptr, host);
  204. std::stringstream ss;
  205. ss << HostEnt(host);
  206. EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
  207. ares_free_hostent(host);
  208. }
  209. } // namespace test
  210. } // namespace ares