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