• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) The c-ares project and its contributors
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * SPDX-License-Identifier: MIT
25  */
26 #include "ares-test-ai.h"
27 #include "dns-proto.h"
28 
29 #ifdef HAVE_NETINET_IN_H
30 #include <netinet/in.h>
31 #endif
32 
33 #include <sstream>
34 #include <vector>
35 
36 using testing::InvokeWithoutArgs;
37 using testing::DoAll;
38 
39 namespace ares {
40 namespace test {
41 
42 MATCHER_P(IncludesNumAddresses, n, "") {
43   (void)result_listener;
44   if(!arg)
45     return false;
46   int cnt = 0;
47   for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
48     cnt++;
49   return n == cnt;
50 }
51 
52 MATCHER_P(IncludesV4Address, address, "") {
53   (void)result_listener;
54   if(!arg)
55     return false;
56   in_addr addressnum = {};
57   if (!ares_inet_pton(AF_INET, address, &addressnum))
58     return false; // wrong number format?
59   for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
60     if (ai->ai_family != AF_INET)
61       continue;
62     if (ai->ai_addrlen != sizeof(struct sockaddr_in))
63       continue;
64     if (reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr.s_addr ==
65         addressnum.s_addr)
66       return true; // found
67   }
68   return false;
69 }
70 
71 MATCHER_P(IncludesV6Address, address, "") {
72   (void)result_listener;
73   if(!arg)
74     return false;
75   in6_addr addressnum = {};
76   if (!ares_inet_pton(AF_INET6, address, &addressnum)) {
77     return false; // wrong number format?
78   }
79   for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
80     if (ai->ai_family != AF_INET6)
81       continue;
82     if (ai->ai_addrlen != sizeof(struct sockaddr_in6))
83       continue;
84     if (!memcmp(
85         reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr.s6_addr,
86         addressnum.s6_addr, sizeof(addressnum.s6_addr)))
87       return true; // found
88   }
89   return false;
90 }
91 
92 // UDP only so mock server doesn't get confused by concatenated requests
TEST_P(MockUDPChannelTestAI,GetAddrInfoParallelLookups)93 TEST_P(MockUDPChannelTestAI, GetAddrInfoParallelLookups) {
94   DNSPacket rsp1;
95   rsp1.set_response().set_aa()
96     .add_question(new DNSQuestion("www.google.com", T_A))
97     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
98   ON_CALL(server_, OnRequest("www.google.com", T_A))
99     .WillByDefault(SetReply(&server_, &rsp1));
100   DNSPacket rsp2;
101   rsp2.set_response().set_aa()
102     .add_question(new DNSQuestion("www.example.com", T_A))
103     .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
104   ON_CALL(server_, OnRequest("www.example.com", T_A))
105     .WillByDefault(SetReply(&server_, &rsp2));
106 
107   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
108   hints.ai_family = AF_INET;
109   hints.ai_flags = ARES_AI_NOSORT;
110   AddrInfoResult result1;
111   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result1);
112   AddrInfoResult result2;
113   ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result2);
114   AddrInfoResult result3;
115   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result3);
116   Process();
117 
118   EXPECT_TRUE(result1.done_);
119   EXPECT_EQ(result1.status_, ARES_SUCCESS);
120   EXPECT_THAT(result1.ai_, IncludesNumAddresses(1));
121   EXPECT_THAT(result1.ai_, IncludesV4Address("2.3.4.5"));
122 
123   EXPECT_TRUE(result2.done_);
124   EXPECT_EQ(result2.status_, ARES_SUCCESS);
125   EXPECT_THAT(result2.ai_, IncludesNumAddresses(1));
126   EXPECT_THAT(result2.ai_, IncludesV4Address("1.2.3.4"));
127 
128   EXPECT_TRUE(result3.done_);
129   EXPECT_EQ(result3.status_, ARES_SUCCESS);
130   EXPECT_THAT(result3.ai_, IncludesNumAddresses(1));
131   EXPECT_THAT(result3.ai_, IncludesV4Address("2.3.4.5"));
132 }
133 
134 // UDP to TCP specific test
TEST_P(MockUDPChannelTestAI,TruncationRetry)135 TEST_P(MockUDPChannelTestAI, TruncationRetry) {
136   DNSPacket rsptruncated;
137   rsptruncated.set_response().set_aa().set_tc()
138     .add_question(new DNSQuestion("www.google.com", T_A));
139   DNSPacket rspok;
140   rspok.set_response()
141     .add_question(new DNSQuestion("www.google.com", T_A))
142     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
143   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
144     .WillOnce(SetReply(&server_, &rsptruncated))
145     .WillOnce(SetReply(&server_, &rspok));
146 
147   AddrInfoResult result;
148   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
149   hints.ai_family = AF_INET;
150   hints.ai_flags = ARES_AI_NOSORT;
151   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
152   Process();
153   EXPECT_TRUE(result.done_);
154   EXPECT_EQ(result.status_, ARES_SUCCESS);
155   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
156   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
157 }
158 
TEST_P(MockTCPChannelTestAI,MalformedResponse)159 TEST_P(MockTCPChannelTestAI, MalformedResponse) {
160   std::vector<byte> one = {0x01};
161   ON_CALL(server_, OnRequest("www.google.com", T_A))
162     .WillByDefault(SetReplyData(&server_, one));
163 
164   AddrInfoResult result;
165   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
166   hints.ai_family = AF_INET;
167   hints.ai_flags = ARES_AI_NOSORT;
168   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
169   Process();
170   EXPECT_TRUE(result.done_);
171   EXPECT_EQ(ARES_EBADRESP, result.status_);
172 }
173 
TEST_P(MockTCPChannelTestAI,FormErrResponse)174 TEST_P(MockTCPChannelTestAI, FormErrResponse) {
175   DNSPacket rsp;
176   rsp.set_response().set_aa()
177     .add_question(new DNSQuestion("www.google.com", T_A));
178   rsp.set_rcode(FORMERR);
179   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
180     .WillOnce(SetReply(&server_, &rsp));
181 
182   AddrInfoResult result;
183   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
184   hints.ai_family = AF_INET;
185   hints.ai_flags = ARES_AI_NOSORT;
186   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
187   Process();
188   EXPECT_TRUE(result.done_);
189   EXPECT_EQ(ARES_EFORMERR, result.status_);
190 }
191 
TEST_P(MockTCPChannelTestAI,ServFailResponse)192 TEST_P(MockTCPChannelTestAI, ServFailResponse) {
193   DNSPacket rsp;
194   rsp.set_response().set_aa()
195     .add_question(new DNSQuestion("www.google.com", T_A));
196   rsp.set_rcode(SERVFAIL);
197   ON_CALL(server_, OnRequest("www.google.com", T_A))
198     .WillByDefault(SetReply(&server_, &rsp));
199 
200   AddrInfoResult result;
201   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
202   hints.ai_family = AF_INET;
203   hints.ai_flags = ARES_AI_NOSORT;
204   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
205   Process();
206   EXPECT_TRUE(result.done_);
207   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
208 }
209 
TEST_P(MockTCPChannelTestAI,NotImplResponse)210 TEST_P(MockTCPChannelTestAI, NotImplResponse) {
211   DNSPacket rsp;
212   rsp.set_response().set_aa()
213     .add_question(new DNSQuestion("www.google.com", T_A));
214   rsp.set_rcode(NOTIMP);
215   ON_CALL(server_, OnRequest("www.google.com", T_A))
216     .WillByDefault(SetReply(&server_, &rsp));
217 
218   AddrInfoResult result;
219   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
220   hints.ai_family = AF_INET;
221   hints.ai_flags = ARES_AI_NOSORT;
222   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
223   Process();
224   EXPECT_TRUE(result.done_);
225   EXPECT_EQ(ARES_ENOTIMP, result.status_);
226 }
227 
TEST_P(MockTCPChannelTestAI,RefusedResponse)228 TEST_P(MockTCPChannelTestAI, RefusedResponse) {
229   DNSPacket rsp;
230   rsp.set_response().set_aa()
231     .add_question(new DNSQuestion("www.google.com", T_A));
232   rsp.set_rcode(REFUSED);
233   ON_CALL(server_, OnRequest("www.google.com", T_A))
234     .WillByDefault(SetReply(&server_, &rsp));
235 
236   AddrInfoResult result;
237   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
238   hints.ai_family = AF_INET;
239   hints.ai_flags = ARES_AI_NOSORT;
240   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
241   Process();
242   EXPECT_TRUE(result.done_);
243   EXPECT_EQ(ARES_EREFUSED, result.status_);
244 }
245 
TEST_P(MockTCPChannelTestAI,YXDomainResponse)246 TEST_P(MockTCPChannelTestAI, YXDomainResponse) {
247   DNSPacket rsp;
248   rsp.set_response().set_aa()
249     .add_question(new DNSQuestion("www.google.com", T_A));
250   rsp.set_rcode(YXDOMAIN);
251   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
252     .WillOnce(SetReply(&server_, &rsp));
253 
254   AddrInfoResult result;
255   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
256   hints.ai_family = AF_INET;
257   hints.ai_flags = ARES_AI_NOSORT;
258   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
259   Process();
260   EXPECT_TRUE(result.done_);
261   EXPECT_EQ(ARES_ENODATA, result.status_);
262 }
263 
264 class MockExtraOptsTestAI
265     : public MockChannelOptsTest,
266       public ::testing::WithParamInterface< std::pair<int, bool> > {
267  public:
MockExtraOptsTestAI()268   MockExtraOptsTestAI()
269     : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
270                           FillOptions(&opts_),
271                           ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
FillOptions(struct ares_options * opts)272   static struct ares_options* FillOptions(struct ares_options * opts) {
273     memset(opts, 0, sizeof(struct ares_options));
274     // Set a few options that affect socket communications
275     opts->socket_send_buffer_size = 514;
276     opts->socket_receive_buffer_size = 514;
277     return opts;
278   }
279  private:
280   struct ares_options opts_;
281 };
282 
TEST_P(MockExtraOptsTestAI,SimpleQuery)283 TEST_P(MockExtraOptsTestAI, SimpleQuery) {
284   ares_set_local_ip4(channel_, 0x7F000001);
285   byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
287   ares_set_local_ip6(channel_, addr6);
288   ares_set_local_dev(channel_, "dummy");
289 
290   DNSPacket rsp;
291   rsp.set_response().set_aa()
292     .add_question(new DNSQuestion("www.google.com", T_A))
293     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
294   ON_CALL(server_, OnRequest("www.google.com", T_A))
295     .WillByDefault(SetReply(&server_, &rsp));
296 
297   AddrInfoResult result;
298   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
299   hints.ai_family = AF_INET;
300   hints.ai_flags = ARES_AI_NOSORT;
301   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
302   Process();
303   EXPECT_TRUE(result.done_);
304   EXPECT_EQ(ARES_SUCCESS, result.status_);
305   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
306   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
307 }
308 
309 class MockExtraOptsNDotsTestAI
310     : public MockChannelOptsTest,
311       public ::testing::WithParamInterface< std::pair<int, bool> > {
312  public:
MockExtraOptsNDotsTestAI(int ndots)313   MockExtraOptsNDotsTestAI(int ndots)
314     : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
315                           FillOptions(&opts_, ndots),
316                           ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF|ARES_OPT_NDOTS) {}
FillOptions(struct ares_options * opts,int ndots)317   static struct ares_options* FillOptions(struct ares_options * opts, int ndots) {
318     memset(opts, 0, sizeof(struct ares_options));
319     // Set a few options that affect socket communications
320     opts->socket_send_buffer_size = 514;
321     opts->socket_receive_buffer_size = 514;
322     opts->ndots = ndots;
323     return opts;
324   }
325  private:
326   struct ares_options opts_;
327 };
328 
329 class MockExtraOptsNDots5TestAI : public MockExtraOptsNDotsTestAI {
330  public:
MockExtraOptsNDots5TestAI()331   MockExtraOptsNDots5TestAI() : MockExtraOptsNDotsTestAI(5) {}
332 };
333 
TEST_P(MockExtraOptsNDots5TestAI,SimpleQuery)334 TEST_P(MockExtraOptsNDots5TestAI, SimpleQuery) {
335   ares_set_local_ip4(channel_, 0x7F000001);
336   byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
338   ares_set_local_ip6(channel_, addr6);
339   ares_set_local_dev(channel_, "dummy");
340 
341   DNSPacket rsp;
342   rsp.set_response().set_aa()
343     .add_question(new DNSQuestion("dynamodb.us-east-1.amazonaws.com", T_A))
344     .add_answer(new DNSARR("dynamodb.us-east-1.amazonaws.com", 100, {123, 45, 67, 8}));
345   ON_CALL(server_, OnRequest("dynamodb.us-east-1.amazonaws.com", T_A))
346     .WillByDefault(SetReply(&server_, &rsp));
347 
348   AddrInfoResult result;
349   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
350   hints.ai_family = AF_INET;
351   hints.ai_flags = ARES_AI_NOSORT;
352   ares_getaddrinfo(channel_, "dynamodb.us-east-1.amazonaws.com.", NULL, &hints, AddrInfoCallback, &result);
353   Process();
354   EXPECT_TRUE(result.done_);
355   EXPECT_EQ(ARES_SUCCESS, result.status_);
356   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
357   EXPECT_THAT(result.ai_, IncludesV4Address("123.45.67.8"));
358 }
359 
360 class MockExtraOptsNDots0TestAI : public MockExtraOptsNDotsTestAI {
361  public:
MockExtraOptsNDots0TestAI()362   MockExtraOptsNDots0TestAI() : MockExtraOptsNDotsTestAI(0) {}
363 };
364 
TEST_P(MockExtraOptsNDots0TestAI,SimpleQuery)365 TEST_P(MockExtraOptsNDots0TestAI, SimpleQuery) {
366   DNSPacket rsp_ndots0;
367   rsp_ndots0.set_response().set_aa()
368     .add_question(new DNSQuestion("ndots0", T_A))
369     .add_answer(new DNSARR("ndots0", 100, {1, 2, 3, 4}));
370   ON_CALL(server_, OnRequest("ndots0", T_A))
371     .WillByDefault(SetReply(&server_, &rsp_ndots0));
372 
373   DNSPacket rsp_ndots0_first;
374   rsp_ndots0_first.set_response().set_aa()
375     .add_question(new DNSQuestion("ndots0.first.com", T_A))
376     .add_answer(new DNSARR("ndots0.first.com", 100, {99, 99, 99, 99}));
377   ON_CALL(server_, OnRequest("ndots0.first.com", T_A))
378     .WillByDefault(SetReply(&server_, &rsp_ndots0_first));
379 
380   DNSPacket rsp_ndots0_second;
381   rsp_ndots0_second.set_response().set_aa()
382     .add_question(new DNSQuestion("ndots0.second.org", T_A))
383     .add_answer(new DNSARR("ndots0.second.org", 100, {98, 98, 98, 98}));
384   ON_CALL(server_, OnRequest("ndots0.second.org", T_A))
385     .WillByDefault(SetReply(&server_, &rsp_ndots0_second));
386 
387   DNSPacket rsp_ndots0_third;
388   rsp_ndots0_third.set_response().set_aa()
389     .add_question(new DNSQuestion("ndots0.third.gov", T_A))
390     .add_answer(new DNSARR("ndots0.third.gov", 100, {97, 97, 97, 97}));
391   ON_CALL(server_, OnRequest("ndots0.third.gov", T_A))
392     .WillByDefault(SetReply(&server_, &rsp_ndots0_third));
393 
394   AddrInfoResult result;
395   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
396   hints.ai_family = AF_INET;
397   hints.ai_flags = ARES_AI_NOSORT;
398   ares_getaddrinfo(channel_, "ndots0", NULL, &hints, AddrInfoCallback, &result);
399   Process();
400   EXPECT_TRUE(result.done_);
401   EXPECT_EQ(ARES_SUCCESS, result.status_);
402   std::stringstream ss;
403   ss << result.ai_;
404   EXPECT_EQ("{addr=[1.2.3.4]}", ss.str());
405 }
406 
407 
408 // Issue #852, systemd-resolved returns SERVFAIL (and possibly REFUSED) on
409 // single label domains.  We need to work around this by continuing to go
410 // to the next in the search list. See also
411 // https://github.com/systemd/systemd/issues/34101
TEST_P(MockExtraOptsNDots0TestAI,SystemdServFail)412 TEST_P(MockExtraOptsNDots0TestAI, SystemdServFail) {
413   DNSPacket rsp_ndots0;
414   rsp_ndots0.set_response().set_rcode(SERVFAIL)
415     .add_question(new DNSQuestion("ndots0", T_A));
416   EXPECT_CALL(server_, OnRequest("ndots0", T_A))
417     // Will call until it hits max retries
418     .WillRepeatedly(SetReply(&server_, &rsp_ndots0));
419 
420   DNSPacket rsp_ndots0_first;
421   rsp_ndots0_first.set_response().set_aa()
422     .add_question(new DNSQuestion("ndots0.first.com", T_A))
423     .add_answer(new DNSARR("ndots0.first.com", 100, {1, 2, 3, 4}));
424   EXPECT_CALL(server_, OnRequest("ndots0.first.com", T_A))
425     .WillOnce(SetReply(&server_, &rsp_ndots0_first));
426 
427   AddrInfoResult result;
428   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
429   hints.ai_family = AF_INET;
430   hints.ai_flags = ARES_AI_NOSORT;
431   ares_getaddrinfo(channel_, "ndots0", NULL, &hints, AddrInfoCallback, &result);
432   Process();
433   EXPECT_TRUE(result.done_);
434   EXPECT_EQ(ARES_SUCCESS, result.status_);
435   std::stringstream ss;
436   ss << result.ai_;
437   EXPECT_EQ("{addr=[1.2.3.4]}", ss.str());
438 }
TEST_P(MockExtraOptsNDots0TestAI,SystemdServFailSearch)439 TEST_P(MockExtraOptsNDots0TestAI, SystemdServFailSearch) {
440   DNSPacket rsp_ndots0;
441   rsp_ndots0.set_response().set_rcode(SERVFAIL)
442     .add_question(new DNSQuestion("ndots0", T_A));
443   EXPECT_CALL(server_, OnRequest("ndots0", T_A))
444     // Will call until it hits max retries
445     .WillRepeatedly(SetReply(&server_, &rsp_ndots0));
446 
447   DNSPacket rsp_ndots0_first;
448   rsp_ndots0_first.set_response().set_aa()
449     .add_question(new DNSQuestion("ndots0.first.com", T_A))
450     .add_answer(new DNSARR("ndots0.first.com", 100, {1, 2, 3, 4}));
451   EXPECT_CALL(server_, OnRequest("ndots0.first.com", T_A))
452     .WillOnce(SetReply(&server_, &rsp_ndots0_first));
453 
454   QueryResult result;
455   ares_dns_record_t *dnsrec = NULL;
456   ares_dns_record_create(&dnsrec, 0, ARES_FLAG_RD, ARES_OPCODE_QUERY, ARES_RCODE_NOERROR);
457   ares_dns_record_query_add(dnsrec, "ndots0", ARES_REC_TYPE_A, ARES_CLASS_IN);
458   ares_search_dnsrec(channel_, dnsrec, QueryCallback, &result);
459   ares_dns_record_destroy(dnsrec);
460   Process();
461   EXPECT_TRUE(result.done_);
462   EXPECT_EQ(ARES_SUCCESS, result.status_);
463 
464   // QueryResult doesn't provide an easy way to retrieve the address, just ignore,
465   // success is probably good enough
466 }
TEST_P(MockExtraOptsNDots0TestAI,SystemdRefused)467 TEST_P(MockExtraOptsNDots0TestAI, SystemdRefused) {
468   DNSPacket rsp_ndots0;
469   rsp_ndots0.set_response().set_rcode(REFUSED)
470     .add_question(new DNSQuestion("ndots0", T_A));
471   EXPECT_CALL(server_, OnRequest("ndots0", T_A))
472     // Will call until it hits max retries
473     .WillRepeatedly(SetReply(&server_, &rsp_ndots0));
474 
475   DNSPacket rsp_ndots0_first;
476   rsp_ndots0_first.set_response().set_aa()
477     .add_question(new DNSQuestion("ndots0.first.com", T_A))
478     .add_answer(new DNSARR("ndots0.first.com", 100, {1, 2, 3, 4}));
479   EXPECT_CALL(server_, OnRequest("ndots0.first.com", T_A))
480     .WillOnce(SetReply(&server_, &rsp_ndots0_first));
481 
482   AddrInfoResult result;
483   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
484   hints.ai_family = AF_INET;
485   hints.ai_flags = ARES_AI_NOSORT;
486   ares_getaddrinfo(channel_, "ndots0", NULL, &hints, AddrInfoCallback, &result);
487   Process();
488   EXPECT_TRUE(result.done_);
489   EXPECT_EQ(ARES_SUCCESS, result.status_);
490   std::stringstream ss;
491   ss << result.ai_;
492   EXPECT_EQ("{addr=[1.2.3.4]}", ss.str());
493 }
TEST_P(MockExtraOptsNDots0TestAI,SystemdRefusedSearch)494 TEST_P(MockExtraOptsNDots0TestAI, SystemdRefusedSearch) {
495   DNSPacket rsp_ndots0;
496   rsp_ndots0.set_response().set_rcode(REFUSED)
497     .add_question(new DNSQuestion("ndots0", T_A));
498   EXPECT_CALL(server_, OnRequest("ndots0", T_A))
499     // Will call until it hits max retries
500     .WillRepeatedly(SetReply(&server_, &rsp_ndots0));
501 
502   DNSPacket rsp_ndots0_first;
503   rsp_ndots0_first.set_response().set_aa()
504     .add_question(new DNSQuestion("ndots0.first.com", T_A))
505     .add_answer(new DNSARR("ndots0.first.com", 100, {1, 2, 3, 4}));
506   EXPECT_CALL(server_, OnRequest("ndots0.first.com", T_A))
507     .WillOnce(SetReply(&server_, &rsp_ndots0_first));
508 
509   QueryResult result;
510   ares_dns_record_t *dnsrec = NULL;
511   ares_dns_record_create(&dnsrec, 0, ARES_FLAG_RD, ARES_OPCODE_QUERY, ARES_RCODE_NOERROR);
512   ares_dns_record_query_add(dnsrec, "ndots0", ARES_REC_TYPE_A, ARES_CLASS_IN);
513   ares_search_dnsrec(channel_, dnsrec, QueryCallback, &result);
514   ares_dns_record_destroy(dnsrec);
515   Process();
516   EXPECT_TRUE(result.done_);
517   EXPECT_EQ(ARES_SUCCESS, result.status_);
518 
519   // QueryResult doesn't provide an easy way to retrieve the address, just ignore,
520   // success is probably good enough
521 }
522 
523 
524 class MockFlagsChannelOptsTestAI
525     : public MockChannelOptsTest,
526       public ::testing::WithParamInterface< std::pair<int, bool> > {
527  public:
MockFlagsChannelOptsTestAI(int flags)528   MockFlagsChannelOptsTestAI(int flags)
529     : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
530                           FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
FillOptions(struct ares_options * opts,int flags)531   static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
532     memset(opts, 0, sizeof(struct ares_options));
533     opts->flags = flags;
534     return opts;
535   }
536  private:
537   struct ares_options opts_;
538 };
539 
540 class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI {
541  public:
MockNoCheckRespChannelTestAI()542   MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {}
543 };
544 
TEST_P(MockNoCheckRespChannelTestAI,ServFailResponse)545 TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) {
546   DNSPacket rsp;
547   rsp.set_response().set_aa()
548     .add_question(new DNSQuestion("www.google.com", T_A));
549   rsp.set_rcode(SERVFAIL);
550   ON_CALL(server_, OnRequest("www.google.com", T_A))
551     .WillByDefault(SetReply(&server_, &rsp));
552 
553   AddrInfoResult result;
554   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
555   hints.ai_family = AF_INET;
556   hints.ai_flags = ARES_AI_NOSORT;
557   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
558   Process();
559   EXPECT_TRUE(result.done_);
560   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
561 }
562 
TEST_P(MockNoCheckRespChannelTestAI,NotImplResponse)563 TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) {
564   DNSPacket rsp;
565   rsp.set_response().set_aa()
566     .add_question(new DNSQuestion("www.google.com", T_A));
567   rsp.set_rcode(NOTIMP);
568   ON_CALL(server_, OnRequest("www.google.com", T_A))
569     .WillByDefault(SetReply(&server_, &rsp));
570 
571   AddrInfoResult result;
572   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
573   hints.ai_family = AF_INET;
574   hints.ai_flags = ARES_AI_NOSORT;
575   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
576   Process();
577   EXPECT_TRUE(result.done_);
578   EXPECT_EQ(ARES_ENOTIMP, result.status_);
579 }
580 
TEST_P(MockNoCheckRespChannelTestAI,RefusedResponse)581 TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) {
582   DNSPacket rsp;
583   rsp.set_response().set_aa()
584     .add_question(new DNSQuestion("www.google.com", T_A));
585   rsp.set_rcode(REFUSED);
586   ON_CALL(server_, OnRequest("www.google.com", T_A))
587     .WillByDefault(SetReply(&server_, &rsp));
588 
589   AddrInfoResult result;
590   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
591   hints.ai_family = AF_INET;
592   hints.ai_flags = ARES_AI_NOSORT;
593   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
594   Process();
595   EXPECT_TRUE(result.done_);
596   EXPECT_EQ(ARES_EREFUSED, result.status_);
597 }
598 
TEST_P(MockChannelTestAI,FamilyV6)599 TEST_P(MockChannelTestAI, FamilyV6) {
600   DNSPacket rsp6;
601   rsp6.set_response().set_aa()
602     .add_question(new DNSQuestion("example.com", T_AAAA))
603     .add_answer(new DNSAaaaRR("example.com", 100,
604                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
606   ON_CALL(server_, OnRequest("example.com", T_AAAA))
607     .WillByDefault(SetReply(&server_, &rsp6));
608   AddrInfoResult result;
609   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
610   hints.ai_family = AF_INET6;
611   hints.ai_flags = ARES_AI_NOSORT;
612   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
613                    AddrInfoCallback, &result);
614   Process();
615   EXPECT_TRUE(result.done_);
616   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
617   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
618 }
619 
620 // Test case for Issue #662
TEST_P(MockChannelTestAI,PartialQueryCancel)621 TEST_P(MockChannelTestAI, PartialQueryCancel) {
622   std::vector<byte> nothing;
623   DNSPacket reply;
624   reply.set_response().set_aa()
625     .add_question(new DNSQuestion("example.com", T_A))
626     .add_answer(new DNSARR("example.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
627 
628   ON_CALL(server_, OnRequest("example.com", T_A))
629     .WillByDefault(SetReply(&server_, &reply));
630 
631   ON_CALL(server_, OnRequest("example.com", T_AAAA))
632     .WillByDefault(SetReplyData(&server_, nothing));
633 
634 
635   AddrInfoResult result;
636   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
637   hints.ai_family = AF_UNSPEC;
638   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
639                    AddrInfoCallback, &result);
640 
641   // After 100ms, issues ares_cancel(), this should be enough time for the A
642   // record reply, but before the timeout on the AAAA record.
643   Process(100);
644   EXPECT_TRUE(result.done_);
645   EXPECT_EQ(ARES_ECANCELLED, result.status_);
646 }
647 
TEST_P(MockChannelTestAI,FamilyV4)648 TEST_P(MockChannelTestAI, FamilyV4) {
649   DNSPacket rsp4;
650   rsp4.set_response().set_aa()
651     .add_question(new DNSQuestion("example.com", T_A))
652     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
653   ON_CALL(server_, OnRequest("example.com", T_A))
654     .WillByDefault(SetReply(&server_, &rsp4));
655   AddrInfoResult result = {};
656   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
657   hints.ai_family = AF_INET;
658   hints.ai_flags = ARES_AI_NOSORT;
659   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
660                    AddrInfoCallback, &result);
661   Process();
662   EXPECT_TRUE(result.done_);
663   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
664   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
665 }
666 
TEST_P(MockChannelTestAI,FamilyV4_MultipleAddresses)667 TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) {
668   DNSPacket rsp4;
669   rsp4.set_response().set_aa()
670     .add_question(new DNSQuestion("example.com", T_A))
671     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}))
672     .add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0}));
673   ON_CALL(server_, OnRequest("example.com", T_A))
674     .WillByDefault(SetReply(&server_, &rsp4));
675   AddrInfoResult result = {};
676   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
677   hints.ai_family = AF_INET;
678   hints.ai_flags = ARES_AI_NOSORT;
679   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
680                    AddrInfoCallback, &result);
681   Process();
682   EXPECT_TRUE(result.done_);
683   std::stringstream ss;
684   ss << result.ai_;
685   EXPECT_EQ("{addr=[2.3.4.5], addr=[7.8.9.0]}", ss.str());
686 }
687 
TEST_P(MockChannelTestAI,FamilyUnspecified)688 TEST_P(MockChannelTestAI, FamilyUnspecified) {
689   DNSPacket rsp6;
690   rsp6.set_response().set_aa()
691     .add_question(new DNSQuestion("example.com", T_AAAA))
692     .add_answer(new DNSAaaaRR("example.com", 100,
693                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
695   ON_CALL(server_, OnRequest("example.com", T_AAAA))
696     .WillByDefault(SetReply(&server_, &rsp6));
697   DNSPacket rsp4;
698   rsp4.set_response().set_aa()
699     .add_question(new DNSQuestion("example.com", T_A))
700     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
701   ON_CALL(server_, OnRequest("example.com", T_A))
702     .WillByDefault(SetReply(&server_, &rsp4));
703   AddrInfoResult result;
704   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
705   hints.ai_family = AF_UNSPEC;
706   hints.ai_flags = ARES_AI_NOSORT;
707   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
708                    AddrInfoCallback, &result);
709   Process();
710   EXPECT_TRUE(result.done_);
711   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
712   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
713   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
714 }
715 
716 
TEST_P(MockChannelTestAI,TriggerResendThenConnFailSERVFAIL)717 TEST_P(MockChannelTestAI, TriggerResendThenConnFailSERVFAIL) {
718   // Set up the server response. The server always returns SERVFAIL.
719   DNSPacket badrsp4;
720   badrsp4.set_response().set_aa().set_rcode(SERVFAIL)
721     .add_question(new DNSQuestion("www.google.com", T_A));
722   DNSPacket goodrsp4;
723   goodrsp4.set_response().set_aa()
724     .add_question(new DNSQuestion("www.google.com", T_A))
725     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
726 
727   DNSPacket goodrsp6;
728   goodrsp6.set_response().set_aa()
729     .add_question(new DNSQuestion("www.google.com", T_AAAA))
730     .add_answer(new DNSAaaaRR("www.google.com", 100,
731                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
733 
734   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
735     .WillOnce(SetReplyAndFailSend(&server_, &badrsp4))
736     .WillOnce(SetReply(&server_, &goodrsp4));
737 
738   EXPECT_CALL(server_, OnRequest("www.google.com", T_AAAA))
739     .WillRepeatedly(SetReply(&server_, &goodrsp6));
740 
741   ares_socket_functions sock_funcs;
742   memset(&sock_funcs, 0, sizeof(sock_funcs));
743 
744   sock_funcs.asendv = ares_sendv_fail;
745 
746   ares_set_socket_functions(channel_, &sock_funcs, NULL);
747 
748   AddrInfoResult result;
749   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
750   hints.ai_family = AF_UNSPEC;
751   hints.ai_flags = ARES_AI_NOSORT;
752   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints,
753                    AddrInfoCallback, &result);
754 
755   Process();
756   EXPECT_TRUE(result.done_);
757   EXPECT_TRUE(result.done_);
758   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
759   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
760   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
761 }
762 
TEST_P(MockUDPChannelTestAI,TriggerResendThenConnFailEDNS)763 TEST_P(MockUDPChannelTestAI, TriggerResendThenConnFailEDNS) {
764   // Set up the server response to simulate an EDNS failure
765  DNSPacket badrsp4;
766   badrsp4.set_response().set_aa().set_rcode(FORMERR)
767     .add_question(new DNSQuestion("www.google.com", T_A));
768   DNSPacket goodrsp4;
769   goodrsp4.set_response().set_aa()
770     .add_question(new DNSQuestion("www.google.com", T_A))
771     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
772   DNSPacket goodrsp6;
773   goodrsp6.set_response().set_aa()
774     .add_question(new DNSQuestion("www.google.com", T_AAAA))
775     .add_answer(new DNSAaaaRR("www.google.com", 100,
776                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
778 
779   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
780     .WillOnce(SetReplyAndFailSend(&server_, &badrsp4))
781     .WillOnce(SetReply(&server_, &goodrsp4));
782 
783   EXPECT_CALL(server_, OnRequest("www.google.com", T_AAAA))
784     .WillRepeatedly(SetReply(&server_, &goodrsp6));
785 
786   ares_socket_functions sock_funcs;
787   memset(&sock_funcs, 0, sizeof(sock_funcs));
788 
789   sock_funcs.asendv = ares_sendv_fail;
790 
791   ares_set_socket_functions(channel_, &sock_funcs, NULL);
792 
793   AddrInfoResult result;
794   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
795   hints.ai_family = AF_UNSPEC;
796   hints.ai_flags = ARES_AI_NOSORT;
797   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints,
798                    AddrInfoCallback, &result);
799 
800   Process();
801   EXPECT_TRUE(result.done_);
802   EXPECT_TRUE(result.done_);
803   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
804   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
805   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
806 }
807 
808 
809 
810 class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI {
811  public:
MockEDNSChannelTestAI()812   MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {}
813 };
814 
TEST_P(MockEDNSChannelTestAI,RetryWithoutEDNS)815 TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) {
816   DNSPacket rspfail;
817   rspfail.set_response().set_aa().set_rcode(FORMERR)
818     .add_question(new DNSQuestion("www.google.com", T_A));
819   DNSPacket rspok;
820   rspok.set_response()
821     .add_question(new DNSQuestion("www.google.com", T_A))
822     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
823   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
824     .WillOnce(SetReply(&server_, &rspfail))
825     .WillOnce(SetReply(&server_, &rspok));
826 
827   AddrInfoResult result;
828   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
829   hints.ai_family = AF_INET;
830   hints.ai_flags = ARES_AI_NOSORT;
831   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
832   Process();
833   EXPECT_TRUE(result.done_);
834   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
835   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
836 }
837 
TEST_P(MockChannelTestAI,SearchDomains)838 TEST_P(MockChannelTestAI, SearchDomains) {
839   DNSPacket nofirst;
840   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
841     .add_question(new DNSQuestion("www.first.com", T_A));
842   ON_CALL(server_, OnRequest("www.first.com", T_A))
843     .WillByDefault(SetReply(&server_, &nofirst));
844   DNSPacket nosecond;
845   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
846     .add_question(new DNSQuestion("www.second.org", T_A));
847   ON_CALL(server_, OnRequest("www.second.org", T_A))
848     .WillByDefault(SetReply(&server_, &nosecond));
849   DNSPacket yesthird;
850   yesthird.set_response().set_aa()
851     .add_question(new DNSQuestion("www.third.gov", T_A))
852     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
853   ON_CALL(server_, OnRequest("www.third.gov", T_A))
854     .WillByDefault(SetReply(&server_, &yesthird));
855 
856   AddrInfoResult result;
857   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
858   hints.ai_family = AF_INET;
859   hints.ai_flags = ARES_AI_NOSORT;
860   ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
861   Process();
862   EXPECT_TRUE(result.done_);
863   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
864   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
865 }
866 
TEST_P(MockChannelTestAI,SearchDomainsServFailOnAAAA)867 TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) {
868   DNSPacket nofirst;
869   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
870     .add_question(new DNSQuestion("www.first.com", T_AAAA));
871   ON_CALL(server_, OnRequest("www.first.com", T_AAAA))
872     .WillByDefault(SetReply(&server_, &nofirst));
873   DNSPacket nofirst4;
874   nofirst4.set_response().set_aa().set_rcode(NXDOMAIN)
875     .add_question(new DNSQuestion("www.first.com", T_A));
876   ON_CALL(server_, OnRequest("www.first.com", T_A))
877     .WillByDefault(SetReply(&server_, &nofirst4));
878 
879   DNSPacket nosecond;
880   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
881     .add_question(new DNSQuestion("www.second.org", T_AAAA));
882   ON_CALL(server_, OnRequest("www.second.org", T_AAAA))
883     .WillByDefault(SetReply(&server_, &nosecond));
884   DNSPacket yessecond4;
885   yessecond4.set_response().set_aa()
886     .add_question(new DNSQuestion("www.second.org", T_A))
887     .add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5}));
888   ON_CALL(server_, OnRequest("www.second.org", T_A))
889     .WillByDefault(SetReply(&server_, &yessecond4));
890 
891   DNSPacket failthird;
892   failthird.set_response().set_aa().set_rcode(SERVFAIL)
893     .add_question(new DNSQuestion("www.third.gov", T_AAAA));
894   ON_CALL(server_, OnRequest("www.third.gov", T_AAAA))
895     .WillByDefault(SetReply(&server_, &failthird));
896   DNSPacket failthird4;
897   failthird4.set_response().set_aa().set_rcode(SERVFAIL)
898     .add_question(new DNSQuestion("www.third.gov", T_A));
899   ON_CALL(server_, OnRequest("www.third.gov", T_A))
900     .WillByDefault(SetReply(&server_, &failthird4));
901 
902   AddrInfoResult result;
903   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
904   hints.ai_family = AF_UNSPEC;
905   hints.ai_flags = ARES_AI_NOSORT;
906   ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
907   Process();
908   EXPECT_TRUE(result.done_);
909   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
910   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
911 }
912 
913 class MockMultiServerChannelTestAI
914   : public MockChannelOptsTest,
915     public ::testing::WithParamInterface< std::pair<int, bool> > {
916  public:
MockMultiServerChannelTestAI(ares_options * opts,int optmask)917   MockMultiServerChannelTestAI(ares_options *opts, int optmask)
918     : MockChannelOptsTest(3, GetParam().first, GetParam().second, false, opts, optmask) {}
CheckExample()919   void CheckExample() {
920     AddrInfoResult result;
921     struct ares_addrinfo_hints hints = {0, 0, 0, 0};
922     hints.ai_family = AF_INET;
923     hints.ai_flags = ARES_AI_NOSORT;
924     ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
925     Process();
926     EXPECT_TRUE(result.done_);
927     EXPECT_EQ(result.status_, ARES_SUCCESS);
928     EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
929     EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
930   }
931 };
932 
933 class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI {
934  public:
NoRotateMultiMockTestAI()935   NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(nullptr, ARES_OPT_NOROTATE) {}
936 };
937 
938 /* We want to terminate retries of other address classes on getaddrinfo if one
939  * address class is returned already to return replies faster.
940  * UPDATE: actually we want to do this only if the address class we received
941  *         was ipv4.  We've seen issues if ipv6 was returned but the host was
942  *         really only capable of ipv4.
943  */
TEST_P(NoRotateMultiMockTestAI,v4Worksv6Timesout)944 TEST_P(NoRotateMultiMockTestAI, v4Worksv6Timesout) {
945   std::vector<byte> nothing;
946 
947   DNSPacket rsp4;
948   rsp4.set_response().set_aa()
949     .add_question(new DNSQuestion("www.example.com", T_A))
950     .add_answer(new DNSARR("www.example.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
951 
952   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
953     .WillOnce(SetReply(servers_[0].get(), &rsp4));
954   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_AAAA))
955     .WillOnce(SetReplyData(servers_[0].get(), nothing));
956 
957   AddrInfoResult result;
958   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
959   hints.ai_family = AF_UNSPEC;
960   hints.ai_flags = ARES_AI_NOSORT;
961   ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
962   Process();
963   EXPECT_TRUE(result.done_);
964   EXPECT_EQ(result.status_, ARES_SUCCESS);
965   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
966   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
967 }
968 
TEST_P(NoRotateMultiMockTestAI,v6Worksv4TimesoutFirst)969 TEST_P(NoRotateMultiMockTestAI, v6Worksv4TimesoutFirst) {
970   std::vector<byte> nothing;
971 
972   DNSPacket rsp4;
973   rsp4.set_response().set_aa()
974     .add_question(new DNSQuestion("www.example.com", T_A))
975     .add_answer(new DNSARR("www.example.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
976 
977   DNSPacket rsp6;
978   rsp6.set_response().set_aa()
979     .add_question(new DNSQuestion("www.example.com", T_AAAA))
980     .add_answer(new DNSAaaaRR("www.example.com", 100,
981                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
982                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
983 
984   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
985     .WillOnce(SetReplyData(servers_[0].get(), nothing));
986   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_AAAA))
987     .WillOnce(SetReply(servers_[0].get(), &rsp6));
988   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
989     .WillOnce(SetReply(servers_[1].get(), &rsp4));
990 
991   AddrInfoResult result;
992   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
993   hints.ai_family = AF_UNSPEC;
994   hints.ai_flags = ARES_AI_NOSORT;
995   ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
996   Process();
997   EXPECT_TRUE(result.done_);
998   EXPECT_EQ(result.status_, ARES_SUCCESS);
999   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
1000   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
1001   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
1002 
1003 }
1004 
TEST_P(NoRotateMultiMockTestAI,ThirdServer)1005 TEST_P(NoRotateMultiMockTestAI, ThirdServer) {
1006   struct ares_options opts;
1007   int optmask = 0;
1008   memset(&opts, 0, sizeof(opts));
1009   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
1010   EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
1011   ares_destroy_options(&opts);
1012 
1013   DNSPacket servfailrsp;
1014   servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
1015     .add_question(new DNSQuestion("www.example.com", T_A));
1016   DNSPacket notimplrsp;
1017   notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
1018     .add_question(new DNSQuestion("www.example.com", T_A));
1019   DNSPacket okrsp;
1020   okrsp.set_response().set_aa()
1021     .add_question(new DNSQuestion("www.example.com", T_A))
1022     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
1023 
1024    EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
1025     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1026   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
1027     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1028   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
1029     .WillOnce(SetReply(servers_[2].get(), &okrsp));
1030   CheckExample();
1031 
1032   // Second time around, still starts from server [2], as [0] and [1] both
1033   // recorded failures
1034   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
1035     .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
1036   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
1037     .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
1038   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
1039     .WillOnce(SetReply(servers_[1].get(), &okrsp));
1040   CheckExample();
1041 
1042   // Third time around, server order is [1] (f0), [2] (f1), [0] (f2), which
1043   // means [1] will get called twice in a row as after the first call
1044   // order will be  [1] (f1), [2] (f1), [0] (f2) since sort order is
1045   // (failure count, index)
1046   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
1047     .WillOnce(SetReply(servers_[1].get(), &servfailrsp))
1048     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1049   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
1050     .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
1051   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
1052     .WillOnce(SetReply(servers_[0].get(), &okrsp));
1053   CheckExample();
1054 }
1055 
TEST_P(MockChannelTestAI,FamilyV4ServiceName)1056 TEST_P(MockChannelTestAI, FamilyV4ServiceName) {
1057   DNSPacket rsp4;
1058   rsp4.set_response().set_aa()
1059     .add_question(new DNSQuestion("example.com", T_A))
1060     .add_answer(new DNSARR("example.com", 100, {1, 1, 1, 1}))
1061     .add_answer(new DNSARR("example.com", 100, {2, 2, 2, 2}));
1062   ON_CALL(server_, OnRequest("example.com", T_A))
1063     .WillByDefault(SetReply(&server_, &rsp4));
1064   AddrInfoResult result = {};
1065   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1066   hints.ai_family = AF_INET;
1067   hints.ai_flags = ARES_AI_NOSORT;
1068   ares_getaddrinfo(channel_, "example.com", "http", &hints, AddrInfoCallback, &result);
1069   Process();
1070   EXPECT_TRUE(result.done_);
1071   std::stringstream ss;
1072   ss << result.ai_;
1073   EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str());
1074 }
1075 
1076 #ifdef HAVE_CONTAINER
1077 
1078 class ContainedMockChannelAISysConfig
1079     : public MockChannelOptsTest,
1080       public ::testing::WithParamInterface<std::pair<int, bool>> {
1081  public:
ContainedMockChannelAISysConfig()1082   ContainedMockChannelAISysConfig()
1083     : MockChannelOptsTest(1, GetParam().first, GetParam().second, true, nullptr, 0) {}
1084 };
1085 
1086 static NameContentList files_no_ndots = {
1087   {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
1088                        "search example.com example.org\n"
1089                        "options edns0 trust-ad\n"}, // ndots:1 is default
1090   {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
1091   {"/etc/nsswitch.conf", "hosts: files dns\n"}};
1092 
1093 /* These tests should still work even with /etc/hosts not having any localhost
1094  * entries */
1095 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, NoHostsLocalHostv4,
1096                  "myhostname", "mydomainname.org", files_no_ndots) {
1097   AddrInfoResult result = {};
1098   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1099   hints.ai_family = AF_INET;
1100   hints.ai_flags = ARES_AI_NOSORT;
1101   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1102   Process();
1103   EXPECT_TRUE(result.done_);
1104   EXPECT_EQ(result.status_, ARES_SUCCESS);
1105   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
1106   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
1107   return HasFailure();
1108 }
1109 
1110 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, NoHostsLocalHostv6,
1111                  "myhostname", "mydomainname.org", files_no_ndots) {
1112   AddrInfoResult result = {};
1113   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1114   hints.ai_family = AF_INET6;
1115   hints.ai_flags = ARES_AI_NOSORT;
1116   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1117   Process();
1118   EXPECT_TRUE(result.done_);
1119   EXPECT_EQ(result.status_, ARES_SUCCESS);
1120   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
1121   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
1122   return HasFailure();
1123 }
1124 
1125 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, NoHostsLocalHostUnspec,
1126                  "myhostname", "mydomainname.org", files_no_ndots) {
1127   AddrInfoResult result = {};
1128   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1129   hints.ai_family = AF_UNSPEC;
1130   hints.ai_flags = ARES_AI_NOSORT;
1131   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1132   Process();
1133   EXPECT_TRUE(result.done_);
1134   EXPECT_EQ(result.status_, ARES_SUCCESS);
1135   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
1136   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
1137   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
1138   return HasFailure();
1139 }
1140 
1141 
1142 /* Issue #946 says if a v4 localhost entry exists, but not a v6 entry, v6
1143  * isn't output correctly. */
1144 static NameContentList files_localhost_v4localhostonly = {
1145   {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
1146                        "search example.com example.org\n"
1147                        "options edns0 trust-ad\n"}, // ndots:1 is default
1148   {"/etc/hosts", "127.0.0.1 localhost\n"},
1149   {"/etc/nsswitch.conf", "hosts: files dns\n"}};
1150 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v4OnlyLocalHostv4,
1151                  "myhostname", "mydomainname.org", files_localhost_v4localhostonly) {
1152   AddrInfoResult result = {};
1153   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1154   hints.ai_family = AF_INET;
1155   hints.ai_flags = ARES_AI_NOSORT;
1156   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1157   Process();
1158   EXPECT_TRUE(result.done_);
1159   EXPECT_EQ(result.status_, ARES_SUCCESS);
1160   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
1161   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
1162   return HasFailure();
1163 }
1164 
1165 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v4OnlyLocalHostv6,
1166                  "myhostname", "mydomainname.org", files_localhost_v4localhostonly) {
1167   AddrInfoResult result = {};
1168   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1169   hints.ai_family = AF_INET6;
1170   hints.ai_flags = ARES_AI_NOSORT;
1171   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1172   Process();
1173   EXPECT_TRUE(result.done_);
1174   EXPECT_EQ(result.status_, ARES_SUCCESS);
1175   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
1176   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
1177   return HasFailure();
1178 }
1179 
1180 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v4OnlyLocalHostUnspec,
1181                  "myhostname", "mydomainname.org", files_localhost_v4localhostonly) {
1182   AddrInfoResult result = {};
1183   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1184   hints.ai_family = AF_UNSPEC;
1185   hints.ai_flags = ARES_AI_NOSORT;
1186   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1187   Process();
1188   EXPECT_TRUE(result.done_);
1189   EXPECT_EQ(result.status_, ARES_SUCCESS);
1190   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
1191   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
1192   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
1193   return HasFailure();
1194 }
1195 
1196 
1197 static NameContentList files_localhost_v6localhostonly = {
1198   {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
1199                        "search example.com example.org\n"
1200                        "options edns0 trust-ad\n"}, // ndots:1 is default
1201   {"/etc/hosts", "::1 localhost\n"},
1202   {"/etc/nsswitch.conf", "hosts: files dns\n"}};
1203 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v6OnlyLocalHostv4,
1204                  "myhostname", "mydomainname.org", files_localhost_v6localhostonly) {
1205   AddrInfoResult result = {};
1206   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1207   hints.ai_family = AF_INET;
1208   hints.ai_flags = ARES_AI_NOSORT;
1209   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1210   Process();
1211   EXPECT_TRUE(result.done_);
1212   EXPECT_EQ(result.status_, ARES_SUCCESS);
1213   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
1214   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
1215   return HasFailure();
1216 }
1217 
1218 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v6OnlyLocalHostv6,
1219                  "myhostname", "mydomainname.org", files_localhost_v6localhostonly) {
1220   AddrInfoResult result = {};
1221   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1222   hints.ai_family = AF_INET6;
1223   hints.ai_flags = ARES_AI_NOSORT;
1224   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1225   Process();
1226   EXPECT_TRUE(result.done_);
1227   EXPECT_EQ(result.status_, ARES_SUCCESS);
1228   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
1229   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
1230   return HasFailure();
1231 }
1232 
1233 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v6OnlyLocalHostUnspec,
1234                  "myhostname", "mydomainname.org", files_localhost_v6localhostonly) {
1235   AddrInfoResult result = {};
1236   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
1237   hints.ai_family = AF_UNSPEC;
1238   hints.ai_flags = ARES_AI_NOSORT;
1239   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
1240   Process();
1241   EXPECT_TRUE(result.done_);
1242   EXPECT_EQ(result.status_, ARES_SUCCESS);
1243   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
1244   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
1245   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
1246   return HasFailure();
1247 }
1248 
1249 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, ContainedMockChannelAISysConfig, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1250 #endif
1251 
1252 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockChannelTestAI,
1253                        ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1254 
1255 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockUDPChannelTestAI,
1256                         ::testing::ValuesIn(ares::test::families), PrintFamily);
1257 
1258 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockTCPChannelTestAI,
1259                         ::testing::ValuesIn(ares::test::families), PrintFamily);
1260 
1261 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockExtraOptsTestAI,
1262 			::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1263 
1264 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockExtraOptsNDots5TestAI,
1265       ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1266 
1267 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockExtraOptsNDots0TestAI,
1268       ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1269 
1270 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI,
1271 			::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1272 
1273 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockEDNSChannelTestAI,
1274 			::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1275 
1276 INSTANTIATE_TEST_SUITE_P(TransportModesAI, NoRotateMultiMockTestAI,
1277 			::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1278 
1279 }  // namespace test
1280 }  // namespace ares
1281