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,ParseUriReplyOK)10 TEST_F(LibraryTest, ParseUriReplyOK) {
11   DNSPacket pkt;
12   pkt.set_qid(0x1234).set_response().set_aa()
13     .add_question(new DNSQuestion("example.com", T_URI))
14     .add_answer(new DNSUriRR("example.com", 100, 10, 20, "uri.example.com"))
15     .add_answer(new DNSUriRR("example.com", 200, 11, 21, "uri2.example.com"));
16   std::vector<byte> data = pkt.data();
17 
18   struct ares_uri_reply* uri = nullptr;
19   EXPECT_EQ(ARES_SUCCESS, ares_parse_uri_reply(data.data(), data.size(), &uri));
20   ASSERT_NE(nullptr, uri);
21 
22   EXPECT_EQ("uri.example.com", std::string(uri->uri));
23   EXPECT_EQ(10, uri->priority);
24   EXPECT_EQ(20, uri->weight);
25   EXPECT_EQ(100, uri->ttl);
26 
27   struct ares_uri_reply* uri2 = uri->next;
28   ASSERT_NE(nullptr, uri2);
29   EXPECT_EQ("uri2.example.com", std::string(uri2->uri));
30   EXPECT_EQ(11, uri2->priority);
31   EXPECT_EQ(21, uri2->weight);
32   EXPECT_EQ(200, uri2->ttl);
33   EXPECT_EQ(nullptr, uri2->next);
34 
35   ares_free_data(uri);
36 }
37 
TEST_F(LibraryTest,ParseUriReplySingle)38 TEST_F(LibraryTest, ParseUriReplySingle) {
39   DNSPacket pkt;
40   pkt.set_qid(0x1234).set_response().set_aa()
41     .add_question(new DNSQuestion("example.abc.def.com", T_URI))
42     .add_answer(new DNSUriRR("example.abc.def.com", 180, 0, 10, "example.abc.def.com"))
43     .add_auth(new DNSNsRR("abc.def.com", 44, "else1.where.com"))
44     .add_auth(new DNSNsRR("abc.def.com", 44, "else2.where.com"))
45     .add_auth(new DNSNsRR("abc.def.com", 44, "else3.where.com"))
46     .add_auth(new DNSNsRR("abc.def.com", 44, "else4.where.com"))
47     .add_auth(new DNSNsRR("abc.def.com", 44, "else5.where.com"))
48     .add_additional(new DNSARR("else2.where.com", 42, {172,19,0,1}))
49     .add_additional(new DNSARR("else5.where.com", 42, {172,19,0,2}));
50   std::vector<byte> data = pkt.data();
51 
52   struct ares_uri_reply* uri = nullptr;
53   EXPECT_EQ(ARES_SUCCESS, ares_parse_uri_reply(data.data(), data.size(), &uri));
54   ASSERT_NE(nullptr, uri);
55 
56   EXPECT_EQ("example.abc.def.com", std::string(uri->uri));
57   EXPECT_EQ(0, uri->priority);
58   EXPECT_EQ(10, uri->weight);
59   EXPECT_EQ(180, uri->ttl);
60   EXPECT_EQ(nullptr, uri->next);
61 
62   ares_free_data(uri);
63 }
64 
TEST_F(LibraryTest,ParseUriReplyMalformed)65 TEST_F(LibraryTest, ParseUriReplyMalformed) {
66   std::vector<byte> data = {
67     0x12, 0x34,  // qid
68     0x84, // response + query + AA + not-TC + not-RD
69     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
70     0x00, 0x01,  // num questions
71     0x00, 0x01,  // num answer RRs
72     0x00, 0x00,  // num authority RRs
73     0x00, 0x00,  // num additional RRs
74     // Question
75     0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
76     0x03, 'c', 'o', 'm',
77     0x00,
78     0x01, 0x00,  // type URI
79     0x00, 0x01,  // class IN
80     // Answer 1
81     0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
82     0x03, 'c', 'o', 'm',
83     0x00,
84     0x01, 0x00,  // RR type
85     0x00, 0x01,  // class IN
86     0x01, 0x02, 0x03, 0x04, // TTL
87     0x00, 0x04,  // rdata length -- too short
88     0x02, 0x03, 0x04, 0x05,
89   };
90 
91   struct ares_uri_reply* uri = nullptr;
92   EXPECT_EQ(ARES_EBADRESP, ares_parse_uri_reply(data.data(), data.size(), &uri));
93   ASSERT_EQ(nullptr, uri);
94 }
95 
TEST_F(LibraryTest,ParseUriReplyMultiple)96 TEST_F(LibraryTest, ParseUriReplyMultiple) {
97   DNSPacket pkt;
98   pkt.set_qid(0x1234).set_response().set_ra().set_rd()
99     .add_question(new DNSQuestion("uri.example.com", T_URI))
100     .add_answer(new DNSUriRR("uri.example.com", 600, 0, 5, "a1.uri.example.com"))
101     .add_answer(new DNSUriRR("uri.example.com", 660, 0, 5, "a2.uri.example.com"))
102     .add_answer(new DNSUriRR("uri.example.com", 720, 0, 5, "a3.uri.example.com"))
103     .add_auth(new DNSNsRR("example.com", 300, "ns1.example.com"))
104     .add_auth(new DNSNsRR("example.com", 300, "ns2.example.com"))
105     .add_auth(new DNSNsRR("example.com", 300, "ns3.example.com"))
106     .add_additional(new DNSARR("a1.uri.example.com", 300, {172,19,1,1}))
107     .add_additional(new DNSARR("a2.uri.example.com", 300, {172,19,1,2}))
108     .add_additional(new DNSARR("a3.uri.example.com", 300, {172,19,1,3}))
109     .add_additional(new DNSARR("n1.example.com", 300, {172,19,0,1}))
110     .add_additional(new DNSARR("n2.example.com", 300, {172,19,0,2}))
111     .add_additional(new DNSARR("n3.example.com", 300, {172,19,0,3}));
112   std::vector<byte> data = pkt.data();
113 
114   struct ares_uri_reply* uri0 = nullptr;
115   EXPECT_EQ(ARES_SUCCESS, ares_parse_uri_reply(data.data(), data.size(), &uri0));
116   ASSERT_NE(nullptr, uri0);
117   struct ares_uri_reply* uri = uri0;
118 
119   EXPECT_EQ("a1.uri.example.com", std::string(uri->uri));
120   EXPECT_EQ(0, uri->priority);
121   EXPECT_EQ(5, uri->weight);
122   EXPECT_EQ(600, uri->ttl);
123   EXPECT_NE(nullptr, uri->next);
124   uri = uri->next;
125 
126   EXPECT_EQ("a2.uri.example.com", std::string(uri->uri));
127   EXPECT_EQ(0, uri->priority);
128   EXPECT_EQ(5, uri->weight);
129   EXPECT_EQ(660, uri->ttl);
130   EXPECT_NE(nullptr, uri->next);
131   uri = uri->next;
132 
133   EXPECT_EQ("a3.uri.example.com", std::string(uri->uri));
134   EXPECT_EQ(0, uri->priority);
135   EXPECT_EQ(5, uri->weight);
136   EXPECT_EQ(720, uri->ttl);
137   EXPECT_EQ(nullptr, uri->next);
138 
139   ares_free_data(uri0);
140 }
141 
TEST_F(LibraryTest,ParseUriReplyCname)142 TEST_F(LibraryTest, ParseUriReplyCname) {
143   DNSPacket pkt;
144   pkt.set_qid(0x1234).set_response().set_aa()
145     .add_question(new DNSQuestion("example.abc.def.com", T_URI))
146     .add_answer(new DNSCnameRR("example.abc.def.com", 300, "cname.abc.def.com"))
147     .add_answer(new DNSUriRR("cname.abc.def.com", 600, 0, 10, "uri.abc.def.com"))
148     .add_auth(new DNSNsRR("abc.def.com", 44, "else1.where.com"))
149     .add_auth(new DNSNsRR("abc.def.com", 44, "else2.where.com"))
150     .add_auth(new DNSNsRR("abc.def.com", 44, "else3.where.com"))
151     .add_additional(new DNSARR("example.abc.def.com", 300, {172,19,0,1}))
152     .add_additional(new DNSARR("else1.where.com", 42, {172,19,0,1}))
153     .add_additional(new DNSARR("else2.where.com", 42, {172,19,0,2}))
154     .add_additional(new DNSARR("else3.where.com", 42, {172,19,0,3}));
155   std::vector<byte> data = pkt.data();
156 
157   struct ares_uri_reply* uri = nullptr;
158   EXPECT_EQ(ARES_SUCCESS, ares_parse_uri_reply(data.data(), data.size(), &uri));
159   ASSERT_NE(nullptr, uri);
160 
161   EXPECT_EQ("uri.abc.def.com", std::string(uri->uri));
162   EXPECT_EQ(0, uri->priority);
163   EXPECT_EQ(10, uri->weight);
164   EXPECT_EQ(600, uri->ttl);
165   EXPECT_EQ(nullptr, uri->next);
166 
167   ares_free_data(uri);
168 }
169 
TEST_F(LibraryTest,ParseUriReplyCnameMultiple)170 TEST_F(LibraryTest, ParseUriReplyCnameMultiple) {
171   DNSPacket pkt;
172   pkt.set_qid(0x1234).set_response().set_ra().set_rd()
173     .add_question(new DNSQuestion("query.example.com", T_URI))
174     .add_answer(new DNSCnameRR("query.example.com", 300, "uri.example.com"))
175     .add_answer(new DNSUriRR("uri.example.com", 600, 0, 5, "a1.uri.example.com"))
176     .add_answer(new DNSUriRR("uri.example.com", 660, 0, 5, "a2.uri.example.com"))
177     .add_answer(new DNSUriRR("uri.example.com", 720, 0, 5, "a3.uri.example.com"))
178     .add_auth(new DNSNsRR("example.com", 300, "ns1.example.com"))
179     .add_auth(new DNSNsRR("example.com", 300, "ns2.example.com"))
180     .add_auth(new DNSNsRR("example.com", 300, "ns3.example.com"))
181     .add_additional(new DNSARR("a1.uri.example.com", 300, {172,19,1,1}))
182     .add_additional(new DNSARR("a2.uri.example.com", 300, {172,19,1,2}))
183     .add_additional(new DNSARR("a3.uri.example.com", 300, {172,19,1,3}))
184     .add_additional(new DNSARR("n1.example.com", 300, {172,19,0,1}))
185     .add_additional(new DNSARR("n2.example.com", 300, {172,19,0,2}))
186     .add_additional(new DNSARR("n3.example.com", 300, {172,19,0,3}));
187   std::vector<byte> data = pkt.data();
188 
189   struct ares_uri_reply* uri0 = nullptr;
190   EXPECT_EQ(ARES_SUCCESS, ares_parse_uri_reply(data.data(), data.size(), &uri0));
191   ASSERT_NE(nullptr, uri0);
192   struct ares_uri_reply* uri = uri0;
193 
194   EXPECT_EQ("a1.uri.example.com", std::string(uri->uri));
195   EXPECT_EQ(0, uri->priority);
196   EXPECT_EQ(5, uri->weight);
197   EXPECT_EQ(600, uri->ttl);
198   EXPECT_NE(nullptr, uri->next);
199   uri = uri->next;
200 
201   EXPECT_EQ("a2.uri.example.com", std::string(uri->uri));
202   EXPECT_EQ(0, uri->priority);
203   EXPECT_EQ(5, uri->weight);
204   EXPECT_EQ(660, uri->ttl);
205   EXPECT_NE(nullptr, uri->next);
206   uri = uri->next;
207 
208   EXPECT_EQ("a3.uri.example.com", std::string(uri->uri));
209   EXPECT_EQ(0, uri->priority);
210   EXPECT_EQ(5, uri->weight);
211   EXPECT_EQ(720, uri->ttl);
212   EXPECT_EQ(nullptr, uri->next);
213 
214   ares_free_data(uri0);
215 }
216 
TEST_F(LibraryTest,ParseUriReplyErrors)217 TEST_F(LibraryTest, ParseUriReplyErrors) {
218   DNSPacket pkt;
219   pkt.set_qid(0x1234).set_response().set_aa()
220     .add_question(new DNSQuestion("example.abc.def.com", T_URI))
221     .add_answer(new DNSUriRR("example.abc.def.com", 180, 0, 10, "example.abc.def.com"));
222   std::vector<byte> data;
223   struct ares_uri_reply* uri = nullptr;
224 
225   // No question.
226   pkt.questions_.clear();
227   data = pkt.data();
228   EXPECT_EQ(ARES_EBADRESP, ares_parse_uri_reply(data.data(), data.size(), &uri));
229   pkt.add_question(new DNSQuestion("example.abc.def.com", T_URI));
230 
231 #ifdef DISABLED
232   // Question != answer
233   pkt.questions_.clear();
234   pkt.add_question(new DNSQuestion("Axample.com", T_URI));
235   data = pkt.data();
236   EXPECT_EQ(ARES_ENODATA, ares_parse_uri_reply(data.data(), data.size(), &uri));
237   pkt.questions_.clear();
238   pkt.add_question(new DNSQuestion("example.com", T_URI));
239 #endif
240 
241   // Two questions.
242   pkt.add_question(new DNSQuestion("example.abc.def.com", T_URI));
243   data = pkt.data();
244   EXPECT_EQ(ARES_EBADRESP, ares_parse_uri_reply(data.data(), data.size(), &uri));
245   pkt.questions_.clear();
246   pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", T_PTR));
247 
248   // Wrong sort of answer.
249   pkt.answers_.clear();
250   pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
251   data = pkt.data();
252   EXPECT_EQ(ARES_SUCCESS, ares_parse_uri_reply(data.data(), data.size(), &uri));
253   EXPECT_EQ(nullptr, uri);
254   pkt.answers_.clear();
255   pkt.add_answer(new DNSUriRR("example.abc.def.com", 180, 0, 10, "example.abc.def.com"));
256 
257   // No answer.
258   pkt.answers_.clear();
259   data = pkt.data();
260   EXPECT_EQ(ARES_ENODATA, ares_parse_uri_reply(data.data(), data.size(), &uri));
261   pkt.add_answer(new DNSUriRR("example.abc.def.com", 180, 0, 10, "example.abc.def.com"));
262 
263   // Truncated packets.
264   data = pkt.data();
265   for (size_t len = 1; len < data.size(); len++) {
266     int rc = ares_parse_uri_reply(data.data(), len, &uri);
267     EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
268   }
269 }
270 
TEST_F(LibraryTest,ParseUriReplyAllocFail)271 TEST_F(LibraryTest, ParseUriReplyAllocFail) {
272   DNSPacket pkt;
273   pkt.set_qid(0x1234).set_response().set_aa()
274     .add_question(new DNSQuestion("example.abc.def.com", T_URI))
275     .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
276     .add_answer(new DNSUriRR("example.abc.def.com", 180, 0, 10, "example.abc.def.com"));
277   std::vector<byte> data = pkt.data();
278   struct ares_uri_reply* uri = nullptr;
279 
280   for (int ii = 1; ii <= 5; ii++) {
281     ClearFails();
282     SetAllocFail(ii);
283     EXPECT_EQ(ARES_ENOMEM, ares_parse_uri_reply(data.data(), data.size(), &uri)) << ii;
284   }
285 }
286 
287 }  // namespace test
288 }  // namespace ares
289