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