• 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.h"
27 #include "dns-proto.h"
28 
29 #ifndef WIN32
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #endif
33 
34 #include <sstream>
35 #include <vector>
36 
37 using testing::InvokeWithoutArgs;
38 using testing::DoAll;
39 
40 namespace ares {
41 namespace test {
42 
43 class NoDNS0x20MockTest
44     : public MockChannelOptsTest,
45       public ::testing::WithParamInterface<int> {
46  public:
NoDNS0x20MockTest()47   NoDNS0x20MockTest()
48     : MockChannelOptsTest(1, GetParam(), false, false,
49                           FillOptions(&opts_),
50                           ARES_OPT_FLAGS) {}
FillOptions(struct ares_options * opts)51   static struct ares_options* FillOptions(struct ares_options * opts) {
52     memset(opts, 0, sizeof(struct ares_options));
53     opts->flags = ARES_FLAG_EDNS;
54     return opts;
55   }
56  private:
57   struct ares_options opts_;
58 };
59 
60 
TEST_P(NoDNS0x20MockTest,Basic)61 TEST_P(NoDNS0x20MockTest, Basic) {
62   std::vector<byte> reply = {
63     0x00, 0x00,  // qid
64     0x84, // response + query + AA + not-TC + not-RD
65     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
66     0x00, 0x01,  // 1 question
67     0x00, 0x01,  // 1 answer RRs
68     0x00, 0x00,  // 0 authority RRs
69     0x00, 0x00,  // 0 additional RRs
70     // Question
71     0x03, 'w', 'w', 'w',
72     0x06, 'g', 'o', 'o', 'g', 'l', 'e',
73     0x03, 'c', 'o', 'm',
74     0x00,
75     0x00, 0x01,  // type A
76     0x00, 0x01,  // class IN
77     // Answer
78     0x03, 'w', 'w', 'w',
79     0x06, 'g', 'o', 'o', 'g', 'l', 'e',
80     0x03, 'c', 'o', 'm',
81     0x00,
82     0x00, 0x01,  // type A
83     0x00, 0x01,  // class IN
84     0x00, 0x00, 0x01, 0x00,  // TTL
85     0x00, 0x04,  // rdata length
86     0x01, 0x02, 0x03, 0x04
87   };
88 
89   ON_CALL(server_, OnRequest("www.google.com", T_A))
90     .WillByDefault(SetReplyData(&server_, reply));
91 
92   HostResult result;
93   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
94   Process();
95   EXPECT_TRUE(result.done_);
96   std::stringstream ss;
97   ss << result.host_;
98   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
99 }
100 
TEST_P(MockUDPChannelTest,DNS0x20BadReply)101 TEST_P(MockUDPChannelTest, DNS0x20BadReply) {
102   std::vector<byte> reply = {
103     0x00, 0x00,  // qid
104     0x84, // response + query + AA + not-TC + not-RD
105     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
106     0x00, 0x01,  // 1 question
107     0x00, 0x01,  // 1 answer RRs
108     0x00, 0x00,  // 0 authority RRs
109     0x00, 0x00,  // 0 additional RRs
110     // Question
111     0x03, 'w', 'w', 'w',
112     0x1D, 's', 'o', 'm', 'e', 'l', 'o', 'n', 'g', 'd', 'o', 'm', 'a', 'i', 'n', 'n', 'a', 'm', 'e', 'b', 'e', 'c', 'a', 'u', 's', 'e', 'p', 'r', 'n', 'g',
113     0x03, 'c', 'o', 'm',
114     0x00,
115     0x00, 0x01,  // type A
116     0x00, 0x01,  // class IN
117     // Answer
118     0x03, 'w', 'w', 'w',
119     0x1D, 's', 'o', 'm', 'e', 'l', 'o', 'n', 'g', 'd', 'o', 'm', 'a', 'i', 'n', 'n', 'a', 'm', 'e', 'b', 'e', 'c', 'a', 'u', 's', 'e', 'p', 'r', 'n', 'g',
120     0x03, 'c', 'o', 'm',
121     0x00,
122     0x00, 0x01,  // type A
123     0x00, 0x01,  // class IN
124     0x00, 0x00, 0x01, 0x00,  // TTL
125     0x00, 0x04,  // rdata length
126     0x01, 0x02, 0x03, 0x04
127   };
128 
129   ON_CALL(server_, OnRequest("www.somelongdomainnamebecauseprng.com", T_A))
130     .WillByDefault(SetReplyData(&server_, reply));
131 
132   /* Reply will be thrown out due to mismatched case for DNS 0x20 in response,
133    * its technically possible this test case may not fail if somehow the
134    * PRNG returns all lowercase domain name so we need to make this domain
135    * fairly long to make sure those odds are very very very low */
136   HostResult result;
137   ares_gethostbyname(channel_, "www.somelongdomainnamebecauseprng.com.", AF_INET, HostCallback, &result);
138   Process();
139   EXPECT_TRUE(result.done_);
140   EXPECT_EQ(ARES_ETIMEOUT, result.status_);
141 }
142 
143 // UDP only so mock server doesn't get confused by concatenated requests
TEST_P(MockUDPChannelTest,GetHostByNameParallelLookups)144 TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) {
145   DNSPacket rsp1;
146   rsp1.set_response().set_aa()
147     .add_question(new DNSQuestion("www.google.com", T_A))
148     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
149   ON_CALL(server_, OnRequest("www.google.com", T_A))
150     .WillByDefault(SetReply(&server_, &rsp1));
151   DNSPacket rsp2;
152   rsp2.set_response().set_aa()
153     .add_question(new DNSQuestion("www.example.com", T_A))
154     .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
155   ON_CALL(server_, OnRequest("www.example.com", T_A))
156     .WillByDefault(SetReply(&server_, &rsp2));
157 
158   HostResult result1;
159   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
160   HostResult result2;
161   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result2);
162   HostResult result3;
163   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result3);
164   Process();
165   EXPECT_TRUE(result1.done_);
166   EXPECT_TRUE(result2.done_);
167   EXPECT_TRUE(result3.done_);
168   std::stringstream ss1;
169   ss1 << result1.host_;
170   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
171   std::stringstream ss2;
172   ss2 << result2.host_;
173   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[1.2.3.4]}", ss2.str());
174   std::stringstream ss3;
175   ss3 << result3.host_;
176   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
177 }
178 
179 // UDP to TCP specific test
TEST_P(MockUDPChannelTest,TruncationRetry)180 TEST_P(MockUDPChannelTest, TruncationRetry) {
181   DNSPacket rsptruncated;
182   rsptruncated.set_response().set_aa().set_tc()
183     .add_question(new DNSQuestion("www.google.com", T_A));
184   DNSPacket rspok;
185   rspok.set_response()
186     .add_question(new DNSQuestion("www.google.com", T_A))
187     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
188   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
189     .WillOnce(SetReply(&server_, &rsptruncated))
190     .WillOnce(SetReply(&server_, &rspok));
191   HostResult result;
192   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
193   Process();
194   EXPECT_TRUE(result.done_);
195   std::stringstream ss;
196   ss << result.host_;
197   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
198 }
199 
TEST_P(MockUDPChannelTest,UTF8BadName)200 TEST_P(MockUDPChannelTest, UTF8BadName) {
201   DNSPacket reply;
202   reply.set_response().set_aa()
203     .add_question(new DNSQuestion("españa.icom.museum", T_A))
204     .add_answer(new DNSARR("españa.icom.museum", 100, {2, 3, 4, 5}));
205   ON_CALL(server_, OnRequest("españa.icom.museum", T_A))
206     .WillByDefault(SetReply(&server_, &reply));
207 
208   HostResult result;
209   ares_gethostbyname(channel_, "españa.icom.museum", AF_INET, HostCallback, &result);
210   Process();
211   EXPECT_TRUE(result.done_);
212   EXPECT_EQ(ARES_EBADNAME, result.status_);
213 }
214 
215 static int sock_cb_count = 0;
SocketConnectCallback(ares_socket_t fd,int type,void * data)216 static int SocketConnectCallback(ares_socket_t fd, int type, void *data) {
217   int rc = *(int*)data;
218   (void)type;
219   if (verbose) std::cerr << "SocketConnectCallback(" << fd << ") invoked" << std::endl;
220   sock_cb_count++;
221   return rc;
222 }
223 
TEST_P(MockChannelTest,SockCallback)224 TEST_P(MockChannelTest, SockCallback) {
225   DNSPacket rsp;
226   rsp.set_response().set_aa()
227     .add_question(new DNSQuestion("www.google.com", T_A))
228     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
229   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
230     .WillOnce(SetReply(&server_, &rsp));
231 
232   // Get notified of new sockets
233   int rc = ARES_SUCCESS;
234   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
235 
236   HostResult result;
237   sock_cb_count = 0;
238   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
239   Process();
240   EXPECT_EQ(1, sock_cb_count);
241   EXPECT_TRUE(result.done_);
242   std::stringstream ss;
243   ss << result.host_;
244   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
245 }
246 
TEST_P(MockChannelTest,SockFailCallback)247 TEST_P(MockChannelTest, SockFailCallback) {
248   // Notification of new sockets gives an error.
249   int rc = -1;
250   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
251 
252   HostResult result;
253   sock_cb_count = 0;
254   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
255   Process();
256   EXPECT_LT(1, sock_cb_count);
257   EXPECT_TRUE(result.done_);
258   EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
259 }
260 
261 static int sock_config_cb_count = 0;
SocketConfigureCallback(ares_socket_t fd,int type,void * data)262 static int SocketConfigureCallback(ares_socket_t fd, int type, void *data) {
263   int rc = *(int*)data;
264   (void)type;
265   if (verbose) std::cerr << "SocketConfigureCallback(" << fd << ") invoked" << std::endl;
266   sock_config_cb_count++;
267   return rc;
268 }
269 
TEST_P(MockChannelTest,SockConfigureCallback)270 TEST_P(MockChannelTest, SockConfigureCallback) {
271   DNSPacket rsp;
272   rsp.set_response().set_aa()
273     .add_question(new DNSQuestion("www.google.com", T_A))
274     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
275   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
276     .WillOnce(SetReply(&server_, &rsp));
277 
278   // Get notified of new sockets
279   int rc = ARES_SUCCESS;
280   ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
281 
282   HostResult result;
283   sock_config_cb_count = 0;
284   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
285   Process();
286   EXPECT_EQ(1, sock_config_cb_count);
287   EXPECT_TRUE(result.done_);
288   std::stringstream ss;
289   ss << result.host_;
290   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
291 }
292 
TEST_P(MockChannelTest,SockConfigureFailCallback)293 TEST_P(MockChannelTest, SockConfigureFailCallback) {
294   // Notification of new sockets gives an error.
295   int rc = -1;
296   ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
297 
298   HostResult result;
299   sock_config_cb_count = 0;
300   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
301   Process();
302   EXPECT_LT(1, sock_config_cb_count);
303   EXPECT_TRUE(result.done_);
304   EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
305 }
306 
307 // Define a server state callback for testing. The custom userdata should be
308 // the expected server string that the callback is invoked with.
309 static int server_state_cb_success_count = 0;
310 static int server_state_cb_failure_count = 0;
ServerStateCallback(const char * server_string,ares_bool_t success,int flags,void * data)311 static void ServerStateCallback(const char *server_string,
312                                 ares_bool_t success, int flags, void *data) {
313   // Increment overall success/failure counts appropriately.
314   if (verbose) std::cerr << "ServerStateCallback("
315                          << server_string << ", "
316                          << success       << ", "
317                          << flags         << ") invoked" << std::endl;
318   if (success == ARES_TRUE) server_state_cb_success_count++;
319   else server_state_cb_failure_count++;
320 
321   // Check that the server string is as expected.
322   char *exp_server_string = *(char **)(data);
323   EXPECT_STREQ(exp_server_string, server_string);
324 
325   // The callback should be invoked with either the UDP flag or the TCP flag,
326   // but not both.
327   ares_bool_t udp = (flags & ARES_SERV_STATE_UDP) ? ARES_TRUE: ARES_FALSE;
328   ares_bool_t tcp = (flags & ARES_SERV_STATE_TCP) ? ARES_TRUE: ARES_FALSE;
329   EXPECT_NE(udp, tcp);
330 }
331 
TEST_P(MockChannelTest,ServStateCallbackSuccess)332 TEST_P(MockChannelTest, ServStateCallbackSuccess) {
333   // Set up the server response. The server returns successfully with an answer
334   // to the query.
335   DNSPacket rsp;
336   rsp.set_response().set_aa()
337     .add_question(new DNSQuestion("www.google.com", T_A))
338     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
339   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
340     .WillOnce(SetReply(&server_, &rsp));
341 
342   // Set up the server state callback. The channel used for this test has a
343   // single server configured.
344   char *exp_server_string = ares_get_servers_csv(channel_);
345   ares_set_server_state_callback(channel_, ServerStateCallback,
346                                  &exp_server_string);
347 
348   // Perform the hostname lookup. Expect 1 successful query to the server.
349   HostResult result;
350   server_state_cb_success_count = 0;
351   server_state_cb_failure_count = 0;
352   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback,
353                      &result);
354   Process();
355   EXPECT_EQ(1, server_state_cb_success_count);
356   EXPECT_EQ(0, server_state_cb_failure_count);
357   EXPECT_TRUE(result.done_);
358   std::stringstream ss;
359   ss << result.host_;
360   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
361 
362   ares_free_string(exp_server_string);
363 }
364 
TEST_P(MockChannelTest,ServStateCallbackFailure)365 TEST_P(MockChannelTest, ServStateCallbackFailure) {
366   // Set up the server response. The server always returns SERVFAIL.
367   DNSPacket rsp;
368   rsp.set_response().set_aa()
369     .add_question(new DNSQuestion("www.google.com", T_A));
370   rsp.set_rcode(SERVFAIL);
371   ON_CALL(server_, OnRequest("www.google.com", T_A))
372     .WillByDefault(SetReply(&server_, &rsp));
373 
374   // Set up the server state callback. The channel used for this test has a
375   // single server configured.
376   char *exp_server_string = ares_get_servers_csv(channel_);
377   ares_set_server_state_callback(channel_, ServerStateCallback,
378                                  &exp_server_string);
379 
380   // Perform the hostname lookup. Expect 3 failed queries to the server (due to
381   // retries).
382   HostResult result;
383   server_state_cb_success_count = 0;
384   server_state_cb_failure_count = 0;
385   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback,
386                      &result);
387   Process();
388   EXPECT_EQ(0, server_state_cb_success_count);
389   EXPECT_EQ(3, server_state_cb_failure_count);
390   EXPECT_TRUE(result.done_);
391   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
392 
393   ares_free_string(exp_server_string);
394 }
395 
TEST_P(MockChannelTest,ServStateCallbackRecover)396 TEST_P(MockChannelTest, ServStateCallbackRecover) {
397   // Set up the server response. The server initially times out, but then
398   // returns successfully (with NXDOMAIN) on the first retry.
399   std::vector<byte> nothing;
400   DNSPacket rsp;
401   rsp.set_response().set_aa()
402     .add_question(new DNSQuestion("www.google.com", T_A));
403   rsp.set_rcode(NXDOMAIN);
404   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
405     .WillOnce(SetReplyData(&server_, nothing))
406     .WillOnce(SetReply(&server_, &rsp));
407 
408   // Set up the server state callback. The channel used for this test has a
409   // single server configured.
410   char *exp_server_string = ares_get_servers_csv(channel_);
411   ares_set_server_state_callback(channel_, ServerStateCallback,
412                                  &exp_server_string);
413 
414   // Perform the hostname lookup. Expect 1 failed query and 1 successful query
415   // to the server.
416   HostResult result;
417   server_state_cb_success_count = 0;
418   server_state_cb_failure_count = 0;
419   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback,
420                      &result);
421   Process();
422   EXPECT_EQ(1, server_state_cb_success_count);
423   EXPECT_EQ(1, server_state_cb_failure_count);
424   EXPECT_TRUE(result.done_);
425   EXPECT_EQ(ARES_ENOTFOUND, result.status_);
426 
427   ares_free_string(exp_server_string);
428 }
429 
TEST_P(MockChannelTest,ReInit)430 TEST_P(MockChannelTest, ReInit) {
431   DNSPacket rsp;
432   rsp.set_response().set_aa()
433     .add_question(new DNSQuestion("www.google.com", T_A))
434     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
435   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
436     .WillOnce(SetReply(&server_, &rsp));
437 
438   HostResult result;
439   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
440   EXPECT_EQ(ARES_SUCCESS, ares_reinit(channel_));
441   Process();
442   EXPECT_TRUE(result.done_);
443   std::stringstream ss;
444   ss << result.host_;
445   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
446 }
447 
448 #define MAXUDPQUERIES_TOTAL 32
449 #define MAXUDPQUERIES_LIMIT 8
450 
451 class MockUDPMaxQueriesTest
452     : public MockChannelOptsTest,
453       public ::testing::WithParamInterface<int> {
454  public:
MockUDPMaxQueriesTest()455   MockUDPMaxQueriesTest()
456     : MockChannelOptsTest(1, GetParam(), false, false,
457                           FillOptions(&opts_),
458                           ARES_OPT_UDP_MAX_QUERIES) {}
FillOptions(struct ares_options * opts)459   static struct ares_options* FillOptions(struct ares_options * opts) {
460     memset(opts, 0, sizeof(struct ares_options));
461     opts->udp_max_queries = MAXUDPQUERIES_LIMIT;
462     return opts;
463   }
464  private:
465   struct ares_options opts_;
466 };
467 
TEST_P(MockUDPMaxQueriesTest,GetHostByNameParallelLookups)468 TEST_P(MockUDPMaxQueriesTest, GetHostByNameParallelLookups) {
469   DNSPacket rsp;
470   rsp.set_response().set_aa()
471     .add_question(new DNSQuestion("www.google.com", T_A))
472     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
473   ON_CALL(server_, OnRequest("www.google.com", T_A))
474     .WillByDefault(SetReply(&server_, &rsp));
475 
476   // Get notified of new sockets so we can validate how many are created
477   int rc = ARES_SUCCESS;
478   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
479   sock_cb_count = 0;
480 
481   HostResult result[MAXUDPQUERIES_TOTAL];
482   for (size_t i=0; i<MAXUDPQUERIES_TOTAL; i++) {
483     ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result[i]);
484   }
485 
486   Process();
487 
488   EXPECT_EQ(MAXUDPQUERIES_TOTAL / MAXUDPQUERIES_LIMIT, sock_cb_count);
489 
490   for (size_t i=0; i<MAXUDPQUERIES_TOTAL; i++) {
491     std::stringstream ss;
492     EXPECT_TRUE(result[i].done_);
493     ss << result[i].host_;
494     EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
495   }
496 }
497 
498 class CacheQueriesTest
499     : public MockChannelOptsTest,
500       public ::testing::WithParamInterface<int> {
501  public:
CacheQueriesTest()502   CacheQueriesTest()
503     : MockChannelOptsTest(1, GetParam(), false, false,
504                           FillOptions(&opts_),
505                           ARES_OPT_QUERY_CACHE) {}
FillOptions(struct ares_options * opts)506   static struct ares_options* FillOptions(struct ares_options * opts) {
507     memset(opts, 0, sizeof(struct ares_options));
508     opts->qcache_max_ttl = 3600;
509     return opts;
510   }
511  private:
512   struct ares_options opts_;
513 };
514 
TEST_P(CacheQueriesTest,GetHostByNameCache)515 TEST_P(CacheQueriesTest, GetHostByNameCache) {
516   DNSPacket rsp;
517   rsp.set_response().set_aa()
518     .add_question(new DNSQuestion("www.google.com", T_A))
519     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
520   ON_CALL(server_, OnRequest("www.google.com", T_A))
521     .WillByDefault(SetReply(&server_, &rsp));
522 
523   // Get notified of new sockets so we can validate how many are created
524   int rc = ARES_SUCCESS;
525   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
526   sock_cb_count = 0;
527 
528   HostResult result1;
529   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
530   Process();
531 
532   std::stringstream ss1;
533   EXPECT_TRUE(result1.done_);
534   ss1 << result1.host_;
535   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
536 
537   /* Run again, should return cached result */
538   HostResult result2;
539   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result2);
540   Process();
541 
542   std::stringstream ss2;
543   EXPECT_TRUE(result2.done_);
544   ss2 << result2.host_;
545   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss2.str());
546 
547   EXPECT_EQ(1, sock_cb_count);
548 }
549 
550 #define TCPPARALLELLOOKUPS 32
TEST_P(MockTCPChannelTest,GetHostByNameParallelLookups)551 TEST_P(MockTCPChannelTest, GetHostByNameParallelLookups) {
552   DNSPacket rsp;
553   rsp.set_response().set_aa()
554     .add_question(new DNSQuestion("www.google.com", T_A))
555     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
556   ON_CALL(server_, OnRequest("www.google.com", T_A))
557     .WillByDefault(SetReply(&server_, &rsp));
558 
559   // Get notified of new sockets so we can validate how many are created
560   int rc = ARES_SUCCESS;
561   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
562   sock_cb_count = 0;
563 
564   HostResult result[TCPPARALLELLOOKUPS];
565   for (size_t i=0; i<TCPPARALLELLOOKUPS; i++) {
566     ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result[i]);
567   }
568 
569   Process();
570 
571   EXPECT_EQ(1, sock_cb_count);
572 
573   for (size_t i=0; i<TCPPARALLELLOOKUPS; i++) {
574     std::stringstream ss;
575     EXPECT_TRUE(result[i].done_);
576     ss << result[i].host_;
577     EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
578   }
579 }
580 
TEST_P(MockTCPChannelTest,MalformedResponse)581 TEST_P(MockTCPChannelTest, MalformedResponse) {
582   std::vector<byte> one = {0x00};
583   ON_CALL(server_, OnRequest("www.google.com", T_A))
584     .WillByDefault(SetReplyData(&server_, one));
585 
586   HostResult result;
587   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
588   Process();
589   EXPECT_TRUE(result.done_);
590   EXPECT_EQ(ARES_EBADRESP, result.status_);
591 }
592 
TEST_P(MockTCPChannelTest,FormErrResponse)593 TEST_P(MockTCPChannelTest, FormErrResponse) {
594   DNSPacket rsp;
595   rsp.set_response().set_aa()
596     .add_question(new DNSQuestion("www.google.com", T_A));
597   rsp.set_rcode(FORMERR);
598   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
599     .WillOnce(SetReply(&server_, &rsp));
600   HostResult result;
601   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
602   Process();
603   EXPECT_TRUE(result.done_);
604   EXPECT_EQ(ARES_EFORMERR, result.status_);
605 }
606 
TEST_P(MockTCPChannelTest,ServFailResponse)607 TEST_P(MockTCPChannelTest, ServFailResponse) {
608   DNSPacket rsp;
609   rsp.set_response().set_aa()
610     .add_question(new DNSQuestion("www.google.com", T_A));
611   rsp.set_rcode(SERVFAIL);
612   ON_CALL(server_, OnRequest("www.google.com", T_A))
613     .WillByDefault(SetReply(&server_, &rsp));
614   HostResult result;
615   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
616   Process();
617   EXPECT_TRUE(result.done_);
618   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
619 }
620 
TEST_P(MockTCPChannelTest,NotImplResponse)621 TEST_P(MockTCPChannelTest, NotImplResponse) {
622   DNSPacket rsp;
623   rsp.set_response().set_aa()
624     .add_question(new DNSQuestion("www.google.com", T_A));
625   rsp.set_rcode(NOTIMP);
626   ON_CALL(server_, OnRequest("www.google.com", T_A))
627     .WillByDefault(SetReply(&server_, &rsp));
628   HostResult result;
629   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
630   Process();
631   EXPECT_TRUE(result.done_);
632   EXPECT_EQ(ARES_ENOTIMP, result.status_);
633 }
634 
TEST_P(MockTCPChannelTest,RefusedResponse)635 TEST_P(MockTCPChannelTest, RefusedResponse) {
636   DNSPacket rsp;
637   rsp.set_response().set_aa()
638     .add_question(new DNSQuestion("www.google.com", T_A));
639   rsp.set_rcode(REFUSED);
640   ON_CALL(server_, OnRequest("www.google.com", T_A))
641     .WillByDefault(SetReply(&server_, &rsp));
642   HostResult result;
643   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
644   Process();
645   EXPECT_TRUE(result.done_);
646   EXPECT_EQ(ARES_EREFUSED, result.status_);
647 }
648 
TEST_P(MockTCPChannelTest,YXDomainResponse)649 TEST_P(MockTCPChannelTest, YXDomainResponse) {
650   DNSPacket rsp;
651   rsp.set_response().set_aa()
652     .add_question(new DNSQuestion("www.google.com", T_A));
653   rsp.set_rcode(YXDOMAIN);
654   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
655     .WillOnce(SetReply(&server_, &rsp));
656   HostResult result;
657   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
658   Process();
659   EXPECT_TRUE(result.done_);
660   EXPECT_EQ(ARES_ENODATA, result.status_);
661 }
662 
663 class MockExtraOptsTest
664     : public MockChannelOptsTest,
665       public ::testing::WithParamInterface< std::pair<int, bool> > {
666  public:
MockExtraOptsTest()667   MockExtraOptsTest()
668     : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
669                           FillOptions(&opts_),
670                           ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
FillOptions(struct ares_options * opts)671   static struct ares_options* FillOptions(struct ares_options * opts) {
672     memset(opts, 0, sizeof(struct ares_options));
673     // Set a few options that affect socket communications
674     opts->socket_send_buffer_size = 514;
675     opts->socket_receive_buffer_size = 514;
676     return opts;
677   }
678  private:
679   struct ares_options opts_;
680 };
681 
TEST_P(MockExtraOptsTest,SimpleQuery)682 TEST_P(MockExtraOptsTest, SimpleQuery) {
683   ares_set_local_ip4(channel_, 0x7F000001);
684   byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
686   ares_set_local_ip6(channel_, addr6);
687   ares_set_local_dev(channel_, "dummy");
688 
689   DNSPacket rsp;
690   rsp.set_response().set_aa()
691     .add_question(new DNSQuestion("www.google.com", T_A))
692     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
693   ON_CALL(server_, OnRequest("www.google.com", T_A))
694     .WillByDefault(SetReply(&server_, &rsp));
695 
696   HostResult result;
697   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
698   Process();
699   EXPECT_TRUE(result.done_);
700   std::stringstream ss;
701   ss << result.host_;
702   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
703 }
704 
705 class MockFlagsChannelOptsTest
706     : public MockChannelOptsTest,
707       public ::testing::WithParamInterface< std::pair<int, bool> > {
708  public:
MockFlagsChannelOptsTest(int flags)709   MockFlagsChannelOptsTest(int flags)
710     : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
711                           FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
FillOptions(struct ares_options * opts,int flags)712   static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
713     memset(opts, 0, sizeof(struct ares_options));
714     opts->flags = flags;
715     return opts;
716   }
717  private:
718   struct ares_options opts_;
719 };
720 
721 class MockNoCheckRespChannelTest : public MockFlagsChannelOptsTest {
722  public:
MockNoCheckRespChannelTest()723   MockNoCheckRespChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_NOCHECKRESP) {}
724 };
725 
TEST_P(MockNoCheckRespChannelTest,ServFailResponse)726 TEST_P(MockNoCheckRespChannelTest, ServFailResponse) {
727   DNSPacket rsp;
728   rsp.set_response().set_aa()
729     .add_question(new DNSQuestion("www.google.com", T_A));
730   rsp.set_rcode(SERVFAIL);
731   ON_CALL(server_, OnRequest("www.google.com", T_A))
732     .WillByDefault(SetReply(&server_, &rsp));
733   HostResult result;
734   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
735   Process();
736   EXPECT_TRUE(result.done_);
737   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
738 }
739 
TEST_P(MockNoCheckRespChannelTest,NotImplResponse)740 TEST_P(MockNoCheckRespChannelTest, NotImplResponse) {
741   DNSPacket rsp;
742   rsp.set_response().set_aa()
743     .add_question(new DNSQuestion("www.google.com", T_A));
744   rsp.set_rcode(NOTIMP);
745   ON_CALL(server_, OnRequest("www.google.com", T_A))
746     .WillByDefault(SetReply(&server_, &rsp));
747   HostResult result;
748   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
749   Process();
750   EXPECT_TRUE(result.done_);
751   EXPECT_EQ(ARES_ENOTIMP, result.status_);
752 }
753 
TEST_P(MockNoCheckRespChannelTest,RefusedResponse)754 TEST_P(MockNoCheckRespChannelTest, RefusedResponse) {
755   DNSPacket rsp;
756   rsp.set_response().set_aa()
757     .add_question(new DNSQuestion("www.google.com", T_A));
758   rsp.set_rcode(REFUSED);
759   ON_CALL(server_, OnRequest("www.google.com", T_A))
760     .WillByDefault(SetReply(&server_, &rsp));
761   HostResult result;
762   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
763   Process();
764   EXPECT_TRUE(result.done_);
765   EXPECT_EQ(ARES_EREFUSED, result.status_);
766 }
767 
768 class MockEDNSChannelTest : public MockFlagsChannelOptsTest {
769  public:
MockEDNSChannelTest()770   MockEDNSChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_EDNS) {}
771 };
772 
TEST_P(MockEDNSChannelTest,RetryWithoutEDNS)773 TEST_P(MockEDNSChannelTest, RetryWithoutEDNS) {
774   DNSPacket rspfail;
775   rspfail.set_response().set_aa().set_rcode(FORMERR)
776     .add_question(new DNSQuestion("www.google.com", T_A));
777   DNSPacket rspok;
778   rspok.set_response()
779     .add_question(new DNSQuestion("www.google.com", T_A))
780     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
781   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
782     .WillOnce(SetReply(&server_, &rspfail))
783     .WillOnce(SetReply(&server_, &rspok));
784   HostResult result;
785   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
786   Process();
787   EXPECT_TRUE(result.done_);
788   std::stringstream ss;
789   ss << result.host_;
790   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
791 }
792 
793 
794 // Issue #911
TEST_P(MockUDPChannelTest,RetryWithoutEDNSNonCompliant)795 TEST_P(MockUDPChannelTest, RetryWithoutEDNSNonCompliant) {
796   DNSPacket rspfail;
797   rspfail.set_response().set_aa().set_rcode(FORMERR)
798     .add_question(new DNSQuestion("www.google.com", T_A))
799     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, { }, false));
800   DNSPacket rspok;
801   rspok.set_response()
802     .add_question(new DNSQuestion("www.google.com", T_A))
803     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
804   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
805     .WillOnce(SetReply(&server_, &rspfail))
806     .WillOnce(SetReply(&server_, &rspok));
807   HostResult result;
808   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
809   Process();
810   EXPECT_TRUE(result.done_);
811   std::stringstream ss;
812   ss << result.host_;
813   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
814 }
815 
TEST_P(MockChannelTest,SearchDomains)816 TEST_P(MockChannelTest, SearchDomains) {
817   DNSPacket nofirst;
818   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
819     .add_question(new DNSQuestion("www.first.com", T_A));
820   ON_CALL(server_, OnRequest("www.first.com", T_A))
821     .WillByDefault(SetReply(&server_, &nofirst));
822   DNSPacket nosecond;
823   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
824     .add_question(new DNSQuestion("www.second.org", T_A));
825   ON_CALL(server_, OnRequest("www.second.org", T_A))
826     .WillByDefault(SetReply(&server_, &nosecond));
827   DNSPacket yesthird;
828   yesthird.set_response().set_aa()
829     .add_question(new DNSQuestion("www.third.gov", T_A))
830     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
831   ON_CALL(server_, OnRequest("www.third.gov", T_A))
832     .WillByDefault(SetReply(&server_, &yesthird));
833 
834   HostResult result;
835   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
836   Process();
837   EXPECT_TRUE(result.done_);
838   std::stringstream ss;
839   ss << result.host_;
840   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
841 }
842 
843 #ifdef HAVE_CONTAINER
844 // Issue #852
845 class ContainedMockChannelSysConfig
846     : public MockChannelOptsTest,
847       public ::testing::WithParamInterface<std::pair<int, bool>> {
848  public:
ContainedMockChannelSysConfig()849   ContainedMockChannelSysConfig()
850     : MockChannelOptsTest(1, GetParam().first, GetParam().second, true, nullptr, 0) {}
851 };
852 
853 static NameContentList files_no_ndots = {
854   {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
855                        "search example.com example.org\n"
856                        "options edns0 trust-ad\n"}, // ndots:1 is default
857   {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
858   {"/etc/nsswitch.conf", "hosts: files dns\n"}};
859 CONTAINED_TEST_P(ContainedMockChannelSysConfig, SysConfigNdotsDefault,
860                  "myhostname", "mydomainname.org", files_no_ndots) {
861   DNSPacket rsp;
862   rsp.set_response().set_aa()
863     .add_question(new DNSQuestion("www.example.com", T_A))
864     .add_answer(new DNSARR("www.example.com", 0x0200, {2, 3, 4, 5}));
865   EXPECT_CALL(server_, OnRequest("www.example.com", T_A))
866     .WillOnce(SetReply(&server_, &rsp));
867 
868   HostResult result;
869   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
870   Process();
871   EXPECT_TRUE(result.done_);
872   std::stringstream ss;
873   ss << result.host_;
874   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
875   return HasFailure();
876 }
877 
878 
879 static NameContentList files_ndots0 = {
880   {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
881                        "search example.com example.org\n"
882                        "options edns0 trust-ad ndots:0\n"}, // ndots:1 is default
883   {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
884   {"/etc/nsswitch.conf", "hosts: files dns\n"}};
885 CONTAINED_TEST_P(ContainedMockChannelSysConfig, SysConfigNdots0,
886                  "myhostname", "mydomainname.org", files_ndots0) {
887   DNSPacket rsp;
888   rsp.set_response().set_aa()
889     .add_question(new DNSQuestion("www", T_A))
890     .add_answer(new DNSARR("www", 0x0200, {1, 2, 3, 4}));
891   EXPECT_CALL(server_, OnRequest("www", T_A))
892     .WillOnce(SetReply(&server_, &rsp));
893 
894   HostResult result;
895   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
896   Process();
897   EXPECT_TRUE(result.done_);
898   std::stringstream ss;
899   ss << result.host_;
900   EXPECT_EQ("{'www' aliases=[] addrs=[1.2.3.4]}", ss.str());
901   return HasFailure();
902 }
903 #endif
904 
905 // Issue #858
TEST_P(CacheQueriesTest,BlankName)906 TEST_P(CacheQueriesTest, BlankName) {
907   DNSPacket rsp;
908   rsp.set_response().set_aa()
909     .add_question(new DNSQuestion(".", T_SOA))
910     .add_answer(new DNSSoaRR(".", 600, "a.root-servers.net", "nstld.verisign-grs.com", 123456, 3600, 3600, 3600, 3600));
911   EXPECT_CALL(server_, OnRequest("", T_SOA))
912     .WillOnce(SetReply(&server_, &rsp));
913 
914   QueryResult result;
915   ares_query_dnsrec(channel_, ".", ARES_CLASS_IN, ARES_REC_TYPE_SOA, QueryCallback, &result, NULL);
916   Process();
917   EXPECT_TRUE(result.done_);
918   EXPECT_EQ(0, result.timeouts_);
919 
920   QueryResult cacheresult;
921   ares_query_dnsrec(channel_, ".", ARES_CLASS_IN, ARES_REC_TYPE_SOA, QueryCallback, &cacheresult, NULL);
922   Process();
923   EXPECT_TRUE(cacheresult.done_);
924   EXPECT_EQ(0, cacheresult.timeouts_);
925 }
926 
TEST_P(CacheQueriesTest,SearchDomainsCache)927 TEST_P(CacheQueriesTest, SearchDomainsCache) {
928   DNSPacket nofirst;
929   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
930     .add_question(new DNSQuestion("www.first.com", T_A))
931     .add_auth(new DNSSoaRR("first.com", 600, "ns1.first.com", "admin.first.com", 123456, 3600, 3600, 3600, 3600));
932   EXPECT_CALL(server_, OnRequest("www.first.com", T_A))
933     .WillOnce(SetReply(&server_, &nofirst));
934   DNSPacket nosecond;
935   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
936     .add_question(new DNSQuestion("www.second.org", T_A))
937     .add_auth(new DNSSoaRR("second.org", 600, "ns1.second.org", "admin.second.org", 123456, 3600, 3600, 3600, 3600));
938   EXPECT_CALL(server_, OnRequest("www.second.org", T_A))
939     .WillOnce(SetReply(&server_, &nosecond));
940   DNSPacket yesthird;
941   yesthird.set_response().set_aa()
942     .add_question(new DNSQuestion("www.third.gov", T_A))
943     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
944   EXPECT_CALL(server_, OnRequest("www.third.gov", T_A))
945     .WillOnce(SetReply(&server_, &yesthird));
946 
947   // First pass through should send the queries.  The EXPECT_CALL .WillOnce
948   // will make sure this only happens once (vs ON_CALL .WillByDefault)
949   HostResult result;
950   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
951   Process();
952   EXPECT_TRUE(result.done_);
953   std::stringstream ss;
954   ss << result.host_;
955   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
956 
957   // This pass should be fully served by cache and yield the same result
958   HostResult cacheresult;
959   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &cacheresult);
960   Process();
961   EXPECT_TRUE(cacheresult.done_);
962   std::stringstream sscache;
963   sscache << cacheresult.host_;
964   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", sscache.str());
965 }
966 
967 // Relies on retries so is UDP-only
TEST_P(MockUDPChannelTest,SearchDomainsWithResentReply)968 TEST_P(MockUDPChannelTest, SearchDomainsWithResentReply) {
969   DNSPacket nofirst;
970   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
971     .add_question(new DNSQuestion("www.first.com", T_A));
972   EXPECT_CALL(server_, OnRequest("www.first.com", T_A))
973     .WillOnce(SetReply(&server_, &nofirst));
974   DNSPacket nosecond;
975   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
976     .add_question(new DNSQuestion("www.second.org", T_A));
977   EXPECT_CALL(server_, OnRequest("www.second.org", T_A))
978     .WillOnce(SetReply(&server_, &nosecond));
979   DNSPacket yesthird;
980   yesthird.set_response().set_aa()
981     .add_question(new DNSQuestion("www.third.gov", T_A))
982     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
983   // Before sending the real answer, resend an earlier reply
984   EXPECT_CALL(server_, OnRequest("www.third.gov", T_A))
985     .WillOnce(DoAll(SetReply(&server_, &nofirst),
986                     SetReplyQID(&server_, 123)))
987     .WillOnce(DoAll(SetReply(&server_, &yesthird),
988                     SetReplyQID(&server_, -1)));
989 
990   HostResult result;
991   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
992   Process();
993   EXPECT_TRUE(result.done_);
994   std::stringstream ss;
995   ss << result.host_;
996   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
997 }
998 
TEST_P(MockChannelTest,SearchDomainsBare)999 TEST_P(MockChannelTest, SearchDomainsBare) {
1000   DNSPacket nofirst;
1001   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
1002     .add_question(new DNSQuestion("www.first.com", T_A));
1003   ON_CALL(server_, OnRequest("www.first.com", T_A))
1004     .WillByDefault(SetReply(&server_, &nofirst));
1005   DNSPacket nosecond;
1006   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
1007     .add_question(new DNSQuestion("www.second.org", T_A));
1008   ON_CALL(server_, OnRequest("www.second.org", T_A))
1009     .WillByDefault(SetReply(&server_, &nosecond));
1010   DNSPacket nothird;
1011   nothird.set_response().set_aa().set_rcode(NXDOMAIN)
1012     .add_question(new DNSQuestion("www.third.gov", T_A));
1013   ON_CALL(server_, OnRequest("www.third.gov", T_A))
1014     .WillByDefault(SetReply(&server_, &nothird));
1015   DNSPacket yesbare;
1016   yesbare.set_response().set_aa()
1017     .add_question(new DNSQuestion("www", T_A))
1018     .add_answer(new DNSARR("www", 0x0200, {2, 3, 4, 5}));
1019   ON_CALL(server_, OnRequest("www", T_A))
1020     .WillByDefault(SetReply(&server_, &yesbare));
1021 
1022   HostResult result;
1023   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1024   Process();
1025   EXPECT_TRUE(result.done_);
1026   EXPECT_EQ(0, result.timeouts_);
1027 
1028   std::stringstream ss;
1029   ss << result.host_;
1030   EXPECT_EQ("{'www' aliases=[] addrs=[2.3.4.5]}", ss.str());
1031 }
1032 
TEST_P(MockChannelTest,SearchNoDataThenSuccess)1033 TEST_P(MockChannelTest, SearchNoDataThenSuccess) {
1034   // First two search domains recognize the name but have no A records.
1035   DNSPacket nofirst;
1036   nofirst.set_response().set_aa()
1037     .add_question(new DNSQuestion("www.first.com", T_A));
1038   ON_CALL(server_, OnRequest("www.first.com", T_A))
1039     .WillByDefault(SetReply(&server_, &nofirst));
1040   DNSPacket nosecond;
1041   nosecond.set_response().set_aa()
1042     .add_question(new DNSQuestion("www.second.org", T_A));
1043   ON_CALL(server_, OnRequest("www.second.org", T_A))
1044     .WillByDefault(SetReply(&server_, &nosecond));
1045   DNSPacket yesthird;
1046   yesthird.set_response().set_aa()
1047     .add_question(new DNSQuestion("www.third.gov", T_A))
1048     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
1049   ON_CALL(server_, OnRequest("www.third.gov", T_A))
1050     .WillByDefault(SetReply(&server_, &yesthird));
1051 
1052   HostResult result;
1053   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1054   Process();
1055   EXPECT_TRUE(result.done_);
1056   std::stringstream ss;
1057   ss << result.host_;
1058   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
1059 }
1060 
TEST_P(MockChannelTest,SearchNoDataThenNoDataBare)1061 TEST_P(MockChannelTest, SearchNoDataThenNoDataBare) {
1062   // First two search domains recognize the name but have no A records.
1063   DNSPacket nofirst;
1064   nofirst.set_response().set_aa()
1065     .add_question(new DNSQuestion("www.first.com", T_A));
1066   ON_CALL(server_, OnRequest("www.first.com", T_A))
1067     .WillByDefault(SetReply(&server_, &nofirst));
1068   DNSPacket nosecond;
1069   nosecond.set_response().set_aa()
1070     .add_question(new DNSQuestion("www.second.org", T_A));
1071   ON_CALL(server_, OnRequest("www.second.org", T_A))
1072     .WillByDefault(SetReply(&server_, &nosecond));
1073   DNSPacket nothird;
1074   nothird.set_response().set_aa()
1075     .add_question(new DNSQuestion("www.third.gov", T_A));
1076   ON_CALL(server_, OnRequest("www.third.gov", T_A))
1077     .WillByDefault(SetReply(&server_, &nothird));
1078   DNSPacket nobare;
1079   nobare.set_response().set_aa()
1080     .add_question(new DNSQuestion("www", T_A));
1081   ON_CALL(server_, OnRequest("www", T_A))
1082     .WillByDefault(SetReply(&server_, &nobare));
1083 
1084   HostResult result;
1085   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1086   Process();
1087   EXPECT_TRUE(result.done_);
1088   EXPECT_EQ(ARES_ENODATA, result.status_);
1089 }
1090 
TEST_P(MockChannelTest,SearchNoDataThenFail)1091 TEST_P(MockChannelTest, SearchNoDataThenFail) {
1092   // First two search domains recognize the name but have no A records.
1093   DNSPacket nofirst;
1094   nofirst.set_response().set_aa()
1095     .add_question(new DNSQuestion("www.first.com", T_A));
1096   ON_CALL(server_, OnRequest("www.first.com", T_A))
1097     .WillByDefault(SetReply(&server_, &nofirst));
1098   DNSPacket nosecond;
1099   nosecond.set_response().set_aa()
1100     .add_question(new DNSQuestion("www.second.org", T_A));
1101   ON_CALL(server_, OnRequest("www.second.org", T_A))
1102     .WillByDefault(SetReply(&server_, &nosecond));
1103   DNSPacket nothird;
1104   nothird.set_response().set_aa()
1105     .add_question(new DNSQuestion("www.third.gov", T_A));
1106   ON_CALL(server_, OnRequest("www.third.gov", T_A))
1107     .WillByDefault(SetReply(&server_, &nothird));
1108   DNSPacket nobare;
1109   nobare.set_response().set_aa().set_rcode(NXDOMAIN)
1110     .add_question(new DNSQuestion("www", T_A));
1111   ON_CALL(server_, OnRequest("www", T_A))
1112     .WillByDefault(SetReply(&server_, &nobare));
1113 
1114   HostResult result;
1115   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1116   Process();
1117   EXPECT_TRUE(result.done_);
1118   EXPECT_EQ(ARES_ENODATA, result.status_);
1119 }
1120 
TEST_P(MockChannelTest,SearchAllocFailure)1121 TEST_P(MockChannelTest, SearchAllocFailure) {
1122   SearchResult result;
1123   SetAllocFail(1);
1124   ares_search(channel_, "fully.qualified.", C_IN, T_A, SearchCallback, &result);
1125   /* Already done */
1126   EXPECT_TRUE(result.done_);
1127   EXPECT_EQ(ARES_ENOMEM, result.status_);
1128 }
1129 
TEST_P(MockChannelTest,SearchHighNdots)1130 TEST_P(MockChannelTest, SearchHighNdots) {
1131   DNSPacket nobare;
1132   nobare.set_response().set_aa().set_rcode(NXDOMAIN)
1133     .add_question(new DNSQuestion("a.b.c.w.w.w", T_A));
1134   ON_CALL(server_, OnRequest("a.b.c.w.w.w", T_A))
1135     .WillByDefault(SetReply(&server_, &nobare));
1136   DNSPacket yesfirst;
1137   yesfirst.set_response().set_aa()
1138     .add_question(new DNSQuestion("a.b.c.w.w.w.first.com", T_A))
1139     .add_answer(new DNSARR("a.b.c.w.w.w.first.com", 0x0200, {2, 3, 4, 5}));
1140   ON_CALL(server_, OnRequest("a.b.c.w.w.w.first.com", T_A))
1141     .WillByDefault(SetReply(&server_, &yesfirst));
1142 
1143   SearchResult result;
1144   ares_search(channel_, "a.b.c.w.w.w", C_IN, T_A, SearchCallback, &result);
1145   Process();
1146   EXPECT_TRUE(result.done_);
1147   EXPECT_EQ(ARES_SUCCESS, result.status_);
1148   std::stringstream ss;
1149   ss << PacketToString(result.data_);
1150   EXPECT_EQ("RSP QRY AA NOERROR Q:{'a.b.c.w.w.w.first.com' IN A} "
1151             "A:{'a.b.c.w.w.w.first.com' IN A TTL=512 2.3.4.5}",
1152             ss.str());
1153 }
1154 
1155 // Test that performing an EDNS search with an OPT RR options value works. The
1156 // options value should be included on the requests to the mock server.
1157 // We are going to do this only via TCP since this won't include the dynamically
1158 // generated DNS cookie that would otherwise mess with this result.
TEST_P(MockTCPChannelTest,SearchOptVal)1159 TEST_P(MockTCPChannelTest, SearchOptVal) {
1160   /* Define the OPT RR options code and value to use. */
1161   unsigned short opt_opt = 3;
1162   unsigned char opt_val[] = { 'c', '-', 'a', 'r', 'e', 's' };
1163 
1164   /* Set up the expected request and reply on the mock server for the first,
1165    * second and third domains. The expected requests contain the OPT RR options
1166    * value defined above.
1167    */
1168   std::string nofirst_req = "REQ QRY RD  Q:{'example.first.com' IN A} "
1169     "ADD:{'' MAXUDP=1232 OPT RCODE2=0 "
1170     "0003"  // opt_opt
1171     "0006"  // length of opt_val
1172     "632d61726573"  // opt_val in hex
1173     "}";
1174   DNSPacket nofirst_rep;
1175   nofirst_rep.set_response().set_aa().set_rcode(NXDOMAIN)
1176     .add_question(new DNSQuestion("example.first.com", T_A));
1177   ON_CALL(server_, OnRequest("example.first.com", T_A))
1178     .WillByDefault(SetReplyExpRequest(&server_, &nofirst_rep, nofirst_req));
1179 
1180   std::string nosecond_req = "REQ QRY RD  Q:{'example.second.org' IN A} "
1181     "ADD:{'' MAXUDP=1232 OPT RCODE2=0 "
1182     "0003"  // opt_opt
1183     "0006"  // length of opt_val
1184     "632d61726573"  // opt_val in hex
1185     "}";
1186   DNSPacket nosecond_rep;
1187   nosecond_rep.set_response().set_aa().set_rcode(NXDOMAIN)
1188     .add_question(new DNSQuestion("example.second.org", T_A));
1189   ON_CALL(server_, OnRequest("example.second.org", T_A))
1190     .WillByDefault(SetReplyExpRequest(&server_, &nosecond_rep, nosecond_req));
1191 
1192   std::string nothird_req = "REQ QRY RD  Q:{'example.third.gov' IN A} "
1193     "ADD:{'' MAXUDP=1232 OPT RCODE2=0 "
1194     "0003"  // opt_opt
1195     "0006"  // length of opt_val
1196     "632d61726573"  // opt_val in hex
1197     "}";
1198   DNSPacket nothird_rep;
1199   nothird_rep.set_response().set_aa().set_rcode(NXDOMAIN)
1200     .add_question(new DNSQuestion("example.third.gov", T_A));
1201   ON_CALL(server_, OnRequest("example.third.gov", T_A))
1202     .WillByDefault(SetReplyExpRequest(&server_, &nothird_rep, nothird_req));
1203 
1204   /* Set up the expected request and reply on the mock server for the bare
1205    * domain. The expected request contains the OPT RR options value defined
1206    * above.
1207    */
1208   std::string yesbare_req = "REQ QRY RD  Q:{'example' IN A} "
1209     "ADD:{'' MAXUDP=1232 OPT RCODE2=0 "
1210     "0003"  // opt_opt
1211     "0006"  // length of opt_val
1212     "632d61726573"  // opt_val in hex
1213     "}";
1214   DNSPacket yesbare_rep;
1215   yesbare_rep.set_response().set_aa()
1216     .add_question(new DNSQuestion("example", T_A))
1217     .add_answer(new DNSARR("example", 0x0200, {2, 3, 4, 5}));
1218   ON_CALL(server_, OnRequest("example", T_A))
1219     .WillByDefault(SetReplyExpRequest(&server_, &yesbare_rep, yesbare_req));
1220 
1221   /* Construct the DNS record to search. */
1222   ares_dns_record_t *dnsrec = NULL;
1223   ares_dns_rr_t *rr = NULL;
1224   EXPECT_EQ(ARES_SUCCESS,
1225     ares_dns_record_create(&dnsrec, 0, ARES_FLAG_RD, ARES_OPCODE_QUERY,
1226       ARES_RCODE_NOERROR));
1227   EXPECT_EQ(ARES_SUCCESS,
1228     ares_dns_record_query_add(dnsrec, "example", (ares_dns_rec_type_t)T_A,
1229       (ares_dns_class_t)C_IN));
1230   EXPECT_EQ(ARES_SUCCESS,
1231     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL, "",
1232       ARES_REC_TYPE_OPT, ARES_CLASS_IN, 0));
1233   EXPECT_EQ(ARES_SUCCESS,
1234     ares_dns_rr_set_u16(rr, ARES_RR_OPT_UDP_SIZE, 1232));
1235   EXPECT_EQ(ARES_SUCCESS, ares_dns_rr_set_u8(rr, ARES_RR_OPT_VERSION, 0));
1236   EXPECT_EQ(ARES_SUCCESS, ares_dns_rr_set_u16(rr, ARES_RR_OPT_FLAGS, 0));
1237   EXPECT_EQ(ARES_SUCCESS,
1238     ares_dns_rr_set_opt(rr, ARES_RR_OPT_OPTIONS, opt_opt, opt_val,
1239       sizeof(opt_val)));
1240 
1241   /* Perform the search. Check that it succeeds with the expected response. */
1242   SearchResult result;
1243   ares_search_dnsrec(channel_, dnsrec, SearchCallbackDnsRec, &result);
1244   ares_dns_record_destroy(dnsrec);
1245   Process();
1246   EXPECT_TRUE(result.done_);
1247   EXPECT_EQ(ARES_SUCCESS, result.status_);
1248   std::stringstream ss;
1249   ss << PacketToString(result.data_);
1250   EXPECT_EQ("RSP QRY AA NOERROR Q:{'example' IN A} "
1251             "A:{'example' IN A TTL=512 2.3.4.5}",
1252             ss.str());
1253 }
1254 
TEST_P(MockChannelTest,V4WorksV6Timeout)1255 TEST_P(MockChannelTest, V4WorksV6Timeout) {
1256   std::vector<byte> nothing;
1257   DNSPacket reply;
1258   reply.set_response().set_aa()
1259     .add_question(new DNSQuestion("www.google.com", T_A))
1260     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1261 
1262   ON_CALL(server_, OnRequest("www.google.com", T_A))
1263     .WillByDefault(SetReply(&server_, &reply));
1264 
1265   ON_CALL(server_, OnRequest("www.google.com", T_AAAA))
1266     .WillByDefault(SetReplyData(&server_, nothing));
1267 
1268   HostResult result;
1269   ares_gethostbyname(channel_, "www.google.com.", AF_UNSPEC, HostCallback, &result);
1270   Process();
1271   EXPECT_TRUE(result.done_);
1272   EXPECT_EQ(1, result.timeouts_);
1273   std::stringstream ss;
1274   ss << result.host_;
1275   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
1276 }
1277 
1278 // Test case for Issue #662
TEST_P(MockChannelTest,PartialQueryCancel)1279 TEST_P(MockChannelTest, PartialQueryCancel) {
1280   std::vector<byte> nothing;
1281   DNSPacket reply;
1282   reply.set_response().set_aa()
1283     .add_question(new DNSQuestion("www.google.com", T_A))
1284     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1285 
1286   ON_CALL(server_, OnRequest("www.google.com", T_A))
1287     .WillByDefault(SetReply(&server_, &reply));
1288 
1289   ON_CALL(server_, OnRequest("www.google.com", T_AAAA))
1290     .WillByDefault(SetReplyData(&server_, nothing));
1291 
1292   HostResult result;
1293   ares_gethostbyname(channel_, "www.google.com.", AF_UNSPEC, HostCallback, &result);
1294   // After 100ms, issues ares_cancel(), this should be enough time for the A
1295   // record reply, but before the timeout on the AAAA record.
1296   Process(100);
1297   EXPECT_TRUE(result.done_);
1298   EXPECT_EQ(ARES_ECANCELLED, result.status_);
1299 }
1300 
TEST_P(MockChannelTest,UnspecifiedFamilyV6)1301 TEST_P(MockChannelTest, UnspecifiedFamilyV6) {
1302   DNSPacket rsp6;
1303   rsp6.set_response().set_aa()
1304     .add_question(new DNSQuestion("example.com", T_AAAA))
1305     .add_answer(new DNSAaaaRR("example.com", 100,
1306                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
1308   ON_CALL(server_, OnRequest("example.com", T_AAAA))
1309     .WillByDefault(SetReply(&server_, &rsp6));
1310 
1311   DNSPacket rsp4;
1312   rsp4.set_response().set_aa()
1313     .add_question(new DNSQuestion("example.com", T_A));
1314   ON_CALL(server_, OnRequest("example.com", T_A))
1315     .WillByDefault(SetReply(&server_, &rsp4));
1316 
1317   HostResult result;
1318   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
1319   Process();
1320   EXPECT_TRUE(result.done_);
1321   std::stringstream ss;
1322   ss << result.host_;
1323   // Default to IPv6 when both are available.
1324   EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
1325 }
1326 
TEST_P(MockChannelTest,UnspecifiedFamilyV4)1327 TEST_P(MockChannelTest, UnspecifiedFamilyV4) {
1328   DNSPacket rsp6;
1329   rsp6.set_response().set_aa()
1330     .add_question(new DNSQuestion("example.com", T_AAAA));
1331   ON_CALL(server_, OnRequest("example.com", T_AAAA))
1332     .WillByDefault(SetReply(&server_, &rsp6));
1333   DNSPacket rsp4;
1334   rsp4.set_response().set_aa()
1335     .add_question(new DNSQuestion("example.com", T_A))
1336     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
1337   ON_CALL(server_, OnRequest("example.com", T_A))
1338     .WillByDefault(SetReply(&server_, &rsp4));
1339 
1340   HostResult result;
1341   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
1342   Process();
1343   EXPECT_TRUE(result.done_);
1344   std::stringstream ss;
1345   ss << result.host_;
1346   EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
1347 }
1348 
TEST_P(MockChannelTest,UnspecifiedFamilyNoData)1349 TEST_P(MockChannelTest, UnspecifiedFamilyNoData) {
1350   DNSPacket rsp6;
1351   rsp6.set_response().set_aa()
1352     .add_question(new DNSQuestion("example.com", T_AAAA))
1353     .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
1354   ON_CALL(server_, OnRequest("example.com", T_AAAA))
1355     .WillByDefault(SetReply(&server_, &rsp6));
1356   DNSPacket rsp4;
1357   rsp4.set_response().set_aa()
1358     .add_question(new DNSQuestion("example.com", T_A));
1359   ON_CALL(server_, OnRequest("example.com", T_A))
1360     .WillByDefault(SetReply(&server_, &rsp4));
1361 
1362   HostResult result;
1363   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
1364   Process();
1365   EXPECT_TRUE(result.done_);
1366   std::stringstream ss;
1367   ss << result.host_;
1368   EXPECT_EQ("{'' aliases=[] addrs=[]}", ss.str());
1369 }
1370 
TEST_P(MockChannelTest,UnspecifiedFamilyCname6A4)1371 TEST_P(MockChannelTest, UnspecifiedFamilyCname6A4) {
1372   DNSPacket rsp6;
1373   rsp6.set_response().set_aa()
1374     .add_question(new DNSQuestion("example.com", T_AAAA))
1375     .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
1376   ON_CALL(server_, OnRequest("example.com", T_AAAA))
1377     .WillByDefault(SetReply(&server_, &rsp6));
1378   DNSPacket rsp4;
1379   rsp4.set_response().set_aa()
1380     .add_question(new DNSQuestion("example.com", T_A))
1381     .add_answer(new DNSARR("example.com", 100, {1, 2, 3, 4}));
1382   ON_CALL(server_, OnRequest("example.com", T_A))
1383     .WillByDefault(SetReply(&server_, &rsp4));
1384 
1385   HostResult result;
1386   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
1387   Process();
1388   EXPECT_TRUE(result.done_);
1389   std::stringstream ss;
1390   ss << result.host_;
1391   EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
1392 }
1393 
TEST_P(MockChannelTest,ExplicitIP)1394 TEST_P(MockChannelTest, ExplicitIP) {
1395   HostResult result;
1396   ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
1397   EXPECT_TRUE(result.done_);  // Immediate return
1398   EXPECT_EQ(ARES_SUCCESS, result.status_);
1399   std::stringstream ss;
1400   ss << result.host_;
1401   EXPECT_EQ("{'1.2.3.4' aliases=[] addrs=[1.2.3.4]}", ss.str());
1402 }
1403 
TEST_P(MockChannelTest,ExplicitIPAllocFail)1404 TEST_P(MockChannelTest, ExplicitIPAllocFail) {
1405   HostResult result;
1406   SetAllocSizeFail(strlen("1.2.3.4") + 1);
1407   ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
1408   EXPECT_TRUE(result.done_);  // Immediate return
1409   EXPECT_EQ(ARES_ENOMEM, result.status_);
1410 }
1411 
TEST_P(MockChannelTest,SortListV4)1412 TEST_P(MockChannelTest, SortListV4) {
1413   DNSPacket rsp;
1414   rsp.set_response().set_aa()
1415     .add_question(new DNSQuestion("example.com", T_A))
1416     .add_answer(new DNSARR("example.com", 100, {22, 23, 24, 25}))
1417     .add_answer(new DNSARR("example.com", 100, {12, 13, 14, 15}))
1418     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
1419   ON_CALL(server_, OnRequest("example.com", T_A))
1420     .WillByDefault(SetReply(&server_, &rsp));
1421 
1422   {
1423     EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "12.13.0.0/255.255.0.0 1234::5678"));
1424     HostResult result;
1425     ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
1426     Process();
1427     EXPECT_TRUE(result.done_);
1428     std::stringstream ss;
1429     ss << result.host_;
1430     EXPECT_EQ("{'example.com' aliases=[] addrs=[12.13.14.15, 22.23.24.25, 2.3.4.5]}", ss.str());
1431   }
1432   {
1433     EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "2.3.0.0/16 130.140.150.160/26"));
1434     HostResult result;
1435     ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
1436     Process();
1437     EXPECT_TRUE(result.done_);
1438     std::stringstream ss;
1439     ss << result.host_;
1440     EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5, 22.23.24.25, 12.13.14.15]}", ss.str());
1441   }
1442   struct ares_options options;
1443   memset(&options, 0, sizeof(options));
1444   int optmask = 0;
1445   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &options, &optmask));
1446   EXPECT_TRUE((optmask & ARES_OPT_SORTLIST) == ARES_OPT_SORTLIST);
1447   ares_destroy_options(&options);
1448 }
1449 
TEST_P(MockChannelTest,SortListV6)1450 TEST_P(MockChannelTest, SortListV6) {
1451   DNSPacket rsp;
1452   rsp.set_response().set_aa()
1453     .add_question(new DNSQuestion("example.com", T_AAAA))
1454     .add_answer(new DNSAaaaRR("example.com", 100,
1455                               {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1456                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02}))
1457     .add_answer(new DNSAaaaRR("example.com", 100,
1458                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1459                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
1460   ON_CALL(server_, OnRequest("example.com", T_AAAA))
1461     .WillByDefault(SetReply(&server_, &rsp));
1462 
1463   {
1464     ares_set_sortlist(channel_, "1111::/16 2.3.0.0/255.255.0.0");
1465     HostResult result;
1466     ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
1467     Process();
1468     EXPECT_TRUE(result.done_);
1469     std::stringstream ss;
1470     ss << result.host_;
1471     EXPECT_EQ("{'example.com' aliases=[] addrs=[1111:0000:0000:0000:0000:0000:0000:0202, "
1472               "2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
1473   }
1474   {
1475     ares_set_sortlist(channel_, "2121::/8");
1476     HostResult result;
1477     ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
1478     Process();
1479     EXPECT_TRUE(result.done_);
1480     std::stringstream ss;
1481     ss << result.host_;
1482     EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303, "
1483               "1111:0000:0000:0000:0000:0000:0000:0202]}", ss.str());
1484   }
1485 }
1486 
1487 // Relies on retries so is UDP-only
TEST_P(MockUDPChannelTest,SearchDomainsAllocFail)1488 TEST_P(MockUDPChannelTest, SearchDomainsAllocFail) {
1489   DNSPacket nofirst;
1490   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
1491     .add_question(new DNSQuestion("www.first.com", T_A));
1492   ON_CALL(server_, OnRequest("www.first.com", T_A))
1493     .WillByDefault(SetReply(&server_, &nofirst));
1494   DNSPacket nosecond;
1495   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
1496     .add_question(new DNSQuestion("www.second.org", T_A));
1497   ON_CALL(server_, OnRequest("www.second.org", T_A))
1498     .WillByDefault(SetReply(&server_, &nosecond));
1499   DNSPacket yesthird;
1500   yesthird.set_response().set_aa()
1501     .add_question(new DNSQuestion("www.third.gov", T_A))
1502     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
1503   ON_CALL(server_, OnRequest("www.third.gov", T_A))
1504     .WillByDefault(SetReply(&server_, &yesthird));
1505 
1506   // Fail a variety of different memory allocations, and confirm
1507   // that the operation either fails with ENOMEM or succeeds
1508   // with the expected result.
1509   const int kCount = 34;
1510   HostResult results[kCount];
1511   for (int ii = 1; ii <= kCount; ii++) {
1512     HostResult* result = &(results[ii - 1]);
1513     ClearFails();
1514     SetAllocFail(ii);
1515     ares_gethostbyname(channel_, "www", AF_INET, HostCallback, result);
1516     Process();
1517     EXPECT_TRUE(result->done_);
1518     if (result->status_ == ARES_SUCCESS) {
1519       std::stringstream ss;
1520       ss << result->host_;
1521       EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str()) << " failed alloc #" << ii;
1522       if (verbose) std::cerr << "Succeeded despite failure of alloc #" << ii << std::endl;
1523     }
1524   }
1525 
1526   // Explicitly destroy the channel now, so that the HostResult objects
1527   // are still valid (in case any pending work refers to them).
1528   ares_destroy(channel_);
1529   channel_ = nullptr;
1530 }
1531 
1532 // Relies on retries so is UDP-only
TEST_P(MockUDPChannelTest,Resend)1533 TEST_P(MockUDPChannelTest, Resend) {
1534   std::vector<byte> nothing;
1535   DNSPacket reply;
1536   reply.set_response().set_aa()
1537     .add_question(new DNSQuestion("www.google.com", T_A))
1538     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1539 
1540   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
1541     .WillOnce(SetReplyData(&server_, nothing))
1542     .WillOnce(SetReplyData(&server_, nothing))
1543     .WillOnce(SetReply(&server_, &reply));
1544 
1545   HostResult result;
1546   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
1547   Process();
1548   EXPECT_TRUE(result.done_);
1549   EXPECT_EQ(2, result.timeouts_);
1550   std::stringstream ss;
1551   ss << result.host_;
1552   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
1553 }
1554 
TEST_P(MockChannelTest,CancelImmediate)1555 TEST_P(MockChannelTest, CancelImmediate) {
1556   HostResult result;
1557   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
1558   ares_cancel(channel_);
1559   EXPECT_TRUE(result.done_);
1560   EXPECT_EQ(ARES_ECANCELLED, result.status_);
1561   EXPECT_EQ(0, result.timeouts_);
1562 }
1563 
TEST_P(MockChannelTest,CancelImmediateGetHostByAddr)1564 TEST_P(MockChannelTest, CancelImmediateGetHostByAddr) {
1565   HostResult result;
1566   struct in_addr addr;
1567   addr.s_addr = htonl(0x08080808);
1568 
1569   ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
1570   ares_cancel(channel_);
1571   EXPECT_TRUE(result.done_);
1572   EXPECT_EQ(ARES_ECANCELLED, result.status_);
1573   EXPECT_EQ(0, result.timeouts_);
1574 }
1575 
1576 // Relies on retries so is UDP-only
TEST_P(MockUDPChannelTest,CancelLater)1577 TEST_P(MockUDPChannelTest, CancelLater) {
1578   std::vector<byte> nothing;
1579 
1580   // On second request, cancel the channel.
1581   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
1582     .WillOnce(SetReplyData(&server_, nothing))
1583     .WillOnce(CancelChannel(&server_, channel_));
1584 
1585   HostResult result;
1586   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
1587   Process();
1588   EXPECT_TRUE(result.done_);
1589   EXPECT_EQ(ARES_ECANCELLED, result.status_);
1590   EXPECT_EQ(0, result.timeouts_);
1591 }
1592 
TEST_P(MockChannelTest,DisconnectFirstAttempt)1593 TEST_P(MockChannelTest, DisconnectFirstAttempt) {
1594   DNSPacket reply;
1595   reply.set_response().set_aa()
1596     .add_question(new DNSQuestion("www.google.com", T_A))
1597     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1598 
1599   // On second request, cancel the channel.
1600   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
1601     .WillOnce(Disconnect(&server_))
1602     .WillOnce(SetReply(&server_, &reply));
1603 
1604   HostResult result;
1605   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
1606   Process();
1607   EXPECT_TRUE(result.done_);
1608   std::stringstream ss;
1609   ss << result.host_;
1610   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
1611 }
1612 
TEST_P(MockChannelTest,GetHostByNameDestroyAbsolute)1613 TEST_P(MockChannelTest, GetHostByNameDestroyAbsolute) {
1614   HostResult result;
1615   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
1616 
1617   ares_destroy(channel_);
1618   channel_ = nullptr;
1619 
1620   EXPECT_TRUE(result.done_);  // Synchronous
1621   EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
1622   EXPECT_EQ(0, result.timeouts_);
1623 }
1624 
TEST_P(MockChannelTest,GetHostByNameDestroyRelative)1625 TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
1626   HostResult result;
1627   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1628 
1629   ares_destroy(channel_);
1630   channel_ = nullptr;
1631 
1632   EXPECT_TRUE(result.done_);  // Synchronous
1633   EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
1634   EXPECT_EQ(0, result.timeouts_);
1635 }
1636 
TEST_P(MockChannelTest,GetHostByNameCNAMENoData)1637 TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
1638   DNSPacket response;
1639   response.set_response().set_aa()
1640     .add_question(new DNSQuestion("cname.first.com", T_A))
1641     .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com"));
1642   ON_CALL(server_, OnRequest("cname.first.com", T_A))
1643     .WillByDefault(SetReply(&server_, &response));
1644 
1645   HostResult result;
1646   ares_gethostbyname(channel_, "cname.first.com.", AF_INET, HostCallback, &result);
1647   Process();
1648   EXPECT_TRUE(result.done_);
1649   EXPECT_EQ(ARES_ENODATA, result.status_);
1650 }
1651 
TEST_P(MockChannelTest,GetHostByAddrDestroy)1652 TEST_P(MockChannelTest, GetHostByAddrDestroy) {
1653   unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
1654   HostResult result;
1655   ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
1656 
1657   ares_destroy(channel_);
1658   channel_ = nullptr;
1659 
1660   EXPECT_TRUE(result.done_);  // Synchronous
1661   EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
1662   EXPECT_EQ(0, result.timeouts_);
1663 }
1664 
TEST_P(MockChannelTest,TriggerResendThenConnFailSERVFAIL)1665 TEST_P(MockChannelTest, TriggerResendThenConnFailSERVFAIL) {
1666   // Set up the server response. The server always returns SERVFAIL.
1667   DNSPacket badrsp;
1668   badrsp.set_response().set_aa().set_rcode(SERVFAIL)
1669     .add_question(new DNSQuestion("www.google.com", T_A));
1670   DNSPacket goodrsp;
1671   goodrsp.set_response().set_aa()
1672     .add_question(new DNSQuestion("www.google.com", T_A))
1673     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1674   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
1675     .WillOnce(SetReplyAndFailSend(&server_, &badrsp))
1676     .WillOnce(SetReply(&server_, &goodrsp));
1677 
1678   ares_socket_functions sock_funcs;
1679   memset(&sock_funcs, 0, sizeof(sock_funcs));
1680 
1681   sock_funcs.asendv = ares_sendv_fail;
1682 
1683   ares_set_socket_functions(channel_, &sock_funcs, NULL);
1684 
1685   HostResult result;
1686   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback,
1687                      &result);
1688   Process();
1689   EXPECT_TRUE(result.done_);
1690   std::stringstream ss;
1691   ss << result.host_;
1692   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
1693 }
1694 
TEST_P(MockUDPChannelTest,TriggerResendThenConnFailEDNS)1695 TEST_P(MockUDPChannelTest, TriggerResendThenConnFailEDNS) {
1696   // Set up the server response to simulate an EDNS failure
1697   DNSPacket badrsp;
1698   badrsp.set_response().set_aa().set_rcode(FORMERR)
1699     .add_question(new DNSQuestion("www.google.com", T_A));
1700   DNSPacket goodrsp;
1701   goodrsp.set_response().set_aa()
1702     .add_question(new DNSQuestion("www.google.com", T_A))
1703     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1704   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
1705     .WillOnce(SetReplyAndFailSend(&server_, &badrsp))
1706     .WillOnce(SetReply(&server_, &goodrsp));
1707 
1708   ares_socket_functions sock_funcs;
1709   memset(&sock_funcs, 0, sizeof(sock_funcs));
1710 
1711   sock_funcs.asendv = ares_sendv_fail;
1712 
1713   ares_set_socket_functions(channel_, &sock_funcs, NULL);
1714 
1715   HostResult result;
1716   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback,
1717                      &result);
1718   Process();
1719   EXPECT_TRUE(result.done_);
1720   std::stringstream ss;
1721   ss << result.host_;
1722   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
1723 }
1724 
TEST_P(MockUDPChannelTest,GetSock)1725 TEST_P(MockUDPChannelTest, GetSock) {
1726   DNSPacket reply;
1727   reply.set_response().set_aa()
1728     .add_question(new DNSQuestion("www.google.com", T_A))
1729     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1730   ON_CALL(server_, OnRequest("www.google.com", T_A))
1731     .WillByDefault(SetReply(&server_, &reply));
1732 
1733   ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD};
1734   int bitmask;
1735 
1736   bitmask = ares_getsock(channel_, socks, 3);
1737   EXPECT_EQ(0, bitmask);
1738   bitmask = ares_getsock(channel_, nullptr, 0);
1739   EXPECT_EQ(0, bitmask);
1740 
1741   // Ask again with a pending query.
1742   HostResult result;
1743   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
1744   bitmask = ares_getsock(channel_, socks, 3);
1745   EXPECT_NE(0, bitmask);
1746 
1747   size_t sock_cnt = 0;
1748   for (size_t i=0; i<3; i++) {
1749     if (ARES_GETSOCK_READABLE(bitmask, i) || ARES_GETSOCK_WRITABLE(bitmask, i)) {
1750       EXPECT_NE(ARES_SOCKET_BAD, socks[i]);
1751       if (socks[i] != ARES_SOCKET_BAD)
1752         sock_cnt++;
1753     }
1754   }
1755   EXPECT_NE((size_t)0, sock_cnt);
1756 
1757   Process();
1758 
1759   bitmask = ares_getsock(channel_, nullptr, 0);
1760   EXPECT_EQ(0, bitmask);
1761 }
1762 
TEST_P(MockTCPChannelTest,GetSock)1763 TEST_P(MockTCPChannelTest, GetSock) {
1764   DNSPacket reply;
1765   reply.set_response().set_aa()
1766     .add_question(new DNSQuestion("www.google.com", T_A))
1767     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1768   ON_CALL(server_, OnRequest("www.google.com", T_A))
1769     .WillByDefault(SetReply(&server_, &reply));
1770 
1771   ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD};
1772   int bitmask;
1773 
1774   bitmask = ares_getsock(channel_, socks, 3);
1775   EXPECT_EQ(0, bitmask);
1776   bitmask = ares_getsock(channel_, nullptr, 0);
1777   EXPECT_EQ(0, bitmask);
1778 
1779   // Ask again with a pending query.
1780   HostResult result;
1781   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
1782   bitmask = ares_getsock(channel_, socks, 3);
1783   EXPECT_NE(0, bitmask);
1784 
1785   size_t sock_cnt = 0;
1786   for (size_t i=0; i<3; i++) {
1787     if (ARES_GETSOCK_READABLE(bitmask, i) || ARES_GETSOCK_WRITABLE(bitmask, i)) {
1788       EXPECT_NE(ARES_SOCKET_BAD, socks[i]);
1789       if (socks[i] != ARES_SOCKET_BAD)
1790         sock_cnt++;
1791     }
1792   }
1793   EXPECT_NE((size_t)0, sock_cnt);
1794 
1795   Process();
1796 
1797   bitmask = ares_getsock(channel_, nullptr, 0);
1798   EXPECT_EQ(0, bitmask);
1799 }
1800 
1801 
TEST_P(MockChannelTest,VerifySocketFunctionCallback)1802 TEST_P(MockChannelTest, VerifySocketFunctionCallback) {
1803   ares_socket_functions sock_funcs;
1804   memset(&sock_funcs, 0, sizeof(sock_funcs));
1805 
1806   DNSPacket reply;
1807   reply.set_response().set_aa()
1808     .add_question(new DNSQuestion("www.google.com", T_A))
1809     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
1810   ON_CALL(server_, OnRequest("www.google.com", T_A))
1811     .WillByDefault(SetReply(&server_, &reply));
1812 
1813   size_t count = 0;
1814 
1815   sock_funcs.asocket = [](int af, int type, int protocol, void * p) -> ares_socket_t {
1816     EXPECT_NE(nullptr, p);
1817     (*reinterpret_cast<size_t *>(p))++;
1818     return ::socket(af, type, protocol);
1819   };
1820 
1821   ares_set_socket_functions(channel_, &sock_funcs, &count);
1822 
1823   {
1824     count = 0;
1825     HostResult result;
1826     ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
1827     Process();
1828 
1829     EXPECT_TRUE(result.done_);
1830     EXPECT_EQ(ARES_SUCCESS, result.status_);
1831     EXPECT_EQ(0, result.timeouts_);
1832     EXPECT_NE((size_t)0, count);
1833   }
1834 
1835   {
1836     count = 0;
1837     ares_channel_t *copy;
1838     EXPECT_EQ(ARES_SUCCESS, ares_dup(&copy, channel_));
1839 
1840     HostResult result;
1841     ares_gethostbyname(copy, "www.google.com.", AF_INET, HostCallback, &result);
1842 
1843     ProcessAltChannel(copy);
1844 
1845     EXPECT_TRUE(result.done_);
1846     ares_destroy(copy);
1847     EXPECT_NE((size_t)0, count);
1848     EXPECT_EQ(ARES_SUCCESS, result.status_);
1849     EXPECT_EQ(0, result.timeouts_);
1850   }
1851 
1852 }
1853 
1854 static const unsigned char *
fetch_server_cookie(const ares_dns_record_t * dnsrec,size_t * len)1855   fetch_server_cookie(const ares_dns_record_t *dnsrec, size_t *len)
1856 {
1857   const ares_dns_rr_t *rr  = fetch_rr_opt(dnsrec);
1858   const unsigned char *val = NULL;
1859   *len                     = 0;
1860 
1861   if (rr == NULL) {
1862     return NULL;
1863   }
1864 
1865   if (!ares_dns_rr_get_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE,
1866                                 &val, len)) {
1867     return NULL;
1868   }
1869 
1870   if (*len <= 8) {
1871     *len = 0;
1872     return NULL;
1873   }
1874 
1875   *len -= 8;
1876   val  += 8;
1877   return val;
1878 }
1879 
1880 static const unsigned char *
fetch_client_cookie(const ares_dns_record_t * dnsrec,size_t * len)1881   fetch_client_cookie(const ares_dns_record_t *dnsrec, size_t *len)
1882 {
1883   const ares_dns_rr_t *rr  = fetch_rr_opt(dnsrec);
1884   const unsigned char *val = NULL;
1885   *len                     = 0;
1886 
1887   if (rr == NULL) {
1888     return NULL;
1889   }
1890 
1891   if (!ares_dns_rr_get_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE,
1892                                 &val, len)) {
1893     return NULL;
1894   }
1895 
1896   if (*len < 8) {
1897     *len = 0;
1898     return NULL;
1899   }
1900 
1901   *len = 8;
1902   return val;
1903 }
1904 
TEST_P(MockUDPChannelTest,DNSCookieSingle)1905 TEST_P(MockUDPChannelTest, DNSCookieSingle) {
1906   DNSPacket reply;
1907   std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
1908   reply.set_response().set_aa()
1909     .add_question(new DNSQuestion("www.google.com", T_A))
1910     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
1911     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, false));
1912   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
1913     .WillOnce(SetReply(&server_, &reply));
1914 
1915   QueryResult result;
1916   ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result, NULL);
1917   Process();
1918   EXPECT_TRUE(result.done_);
1919   EXPECT_EQ(0, result.timeouts_);
1920 
1921   size_t len;
1922   const unsigned char *returned_cookie = fetch_server_cookie(result.dnsrec_.dnsrec_, &len);
1923   EXPECT_EQ(len, server_cookie.size());
1924   EXPECT_TRUE(memcmp(server_cookie.data(), returned_cookie, len) == 0);
1925 }
1926 
TEST_P(MockUDPChannelTest,DNSCookieMissingAfterGood)1927 TEST_P(MockUDPChannelTest, DNSCookieMissingAfterGood) {
1928   std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
1929   DNSPacket reply;
1930   reply.set_response().set_aa()
1931     .add_question(new DNSQuestion("www.google.com", T_A))
1932     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
1933     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, false));
1934   DNSPacket reply_nocookie;
1935   reply_nocookie.set_response().set_aa()
1936     .add_question(new DNSQuestion("www.google.com", T_A))
1937     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
1938     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, { }, false));
1939   DNSPacket reply_ensurecookie;
1940   reply_ensurecookie.set_response().set_aa()
1941     .add_question(new DNSQuestion("www.google.com", T_A))
1942     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
1943     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, true));
1944 
1945   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
1946     .WillOnce(SetReply(&server_, &reply))
1947     .WillOnce(SetReply(&server_, &reply_nocookie))
1948     .WillOnce(SetReply(&server_, &reply_ensurecookie));
1949 
1950   /* This test will establish the server supports cookies, then the next reply
1951    * will be missing the server cookie and therefore be rejected and timeout, then
1952    * an internal retry will occur and the cookie will be present again and it
1953    * will be verified a server cookie was actually present that matches the
1954    * server cookie. */
1955   QueryResult result1;
1956   ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result1, NULL);
1957   Process();
1958   EXPECT_TRUE(result1.done_);
1959   EXPECT_EQ(0, result1.timeouts_);
1960 
1961   QueryResult result2;
1962   ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result2, NULL);
1963   Process();
1964   EXPECT_TRUE(result2.done_);
1965   EXPECT_EQ(1, result2.timeouts_);
1966 
1967   /* Client cookie should NOT have rotated */
1968   size_t len1;
1969   const unsigned char *client_cookie_1 = fetch_client_cookie(result1.dnsrec_.dnsrec_, &len1);
1970   size_t len2;
1971   const unsigned char *client_cookie_2 = fetch_client_cookie(result2.dnsrec_.dnsrec_, &len2);
1972   EXPECT_EQ(len1, 8);
1973   EXPECT_EQ(len1, len2);
1974   EXPECT_TRUE(memcmp(client_cookie_1, client_cookie_2, len1) == 0);
1975 }
1976 
1977 
TEST_P(MockUDPChannelTest,DNSCookieBadLen)1978 TEST_P(MockUDPChannelTest, DNSCookieBadLen) {
1979   std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
1980   std::vector<byte> server_cookie_bad = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0 };
1981   DNSPacket reply;
1982   reply.set_response().set_aa()
1983     .add_question(new DNSQuestion("www.google.com", T_A))
1984     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
1985     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, false));
1986   DNSPacket reply_badcookielen;
1987   reply_badcookielen.set_response().set_aa()
1988     .add_question(new DNSQuestion("www.google.com", T_A))
1989     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
1990     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie_bad, false));
1991 
1992   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
1993     .WillOnce(SetReply(&server_, &reply_badcookielen))
1994     .WillOnce(SetReply(&server_, &reply));
1995 
1996   /* This test will send back a malformed cookie len, then when it times out and retry occurs will send back a valid cookie. */
1997   QueryResult result1;
1998   ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result1, NULL);
1999   Process();
2000   EXPECT_TRUE(result1.done_);
2001   EXPECT_EQ(1, result1.timeouts_);
2002 }
2003 
2004 
TEST_P(MockUDPChannelTest,DNSCookieServerRotate)2005 TEST_P(MockUDPChannelTest, DNSCookieServerRotate) {
2006   std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2007   std::vector<byte> server_cookie_rotate = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
2008 
2009   DNSPacket reply_cookie1;
2010   reply_cookie1.set_response().set_aa()
2011     .add_question(new DNSQuestion("www.google.com", T_A))
2012     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
2013     .add_additional(new DNSOptRR(0, 0, 0, 1280, {}, server_cookie, false));
2014   DNSPacket reply_cookie2_badcookie;
2015   reply_cookie2_badcookie.set_response().set_aa().set_rcode(ARES_RCODE_BADCOOKIE & 0xF)
2016     .add_question(new DNSQuestion("www.google.com", T_A))
2017     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
2018     .add_additional(new DNSOptRR((ARES_RCODE_BADCOOKIE >> 4) & 0xFF, 0, 0, 1280, { }, server_cookie_rotate, false));
2019   DNSPacket reply_cookie2;
2020   reply_cookie2.set_response().set_aa()
2021     .add_question(new DNSQuestion("www.google.com", T_A))
2022     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
2023     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie_rotate, true));
2024 
2025   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
2026     .WillOnce(SetReply(&server_, &reply_cookie1))
2027     .WillOnce(SetReply(&server_, &reply_cookie2_badcookie))
2028     .WillOnce(SetReply(&server_, &reply_cookie2));
2029 
2030   /* This test will establish the server supports cookies, then the next reply
2031    * the server returns BADCOOKIE indicating the cookie has rotated and
2032    * returns a new cookie. Then the query will be automatically retried with
2033    * the newly returned cookie. No timeouts should be indicated, and the
2034    * client cookie should not rotate. */
2035   QueryResult result1;
2036   ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result1, NULL);
2037   Process();
2038   EXPECT_TRUE(result1.done_);
2039   EXPECT_EQ(0, result1.timeouts_);
2040 
2041   QueryResult result2;
2042   ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result2, NULL);
2043   Process();
2044   EXPECT_TRUE(result2.done_);
2045   EXPECT_EQ(0, result2.timeouts_);
2046 
2047   /* Client cookie should NOT have rotated */
2048   size_t len1;
2049   const unsigned char *client_cookie_1 = fetch_client_cookie(result1.dnsrec_.dnsrec_, &len1);
2050   size_t len2;
2051   const unsigned char *client_cookie_2 = fetch_client_cookie(result2.dnsrec_.dnsrec_, &len2);
2052   EXPECT_EQ(len1, 8);
2053   EXPECT_EQ(len1, len2);
2054   EXPECT_TRUE(memcmp(client_cookie_1, client_cookie_2, len1) == 0);
2055 }
2056 
TEST_P(MockUDPChannelTest,DNSCookieSpoof)2057 TEST_P(MockUDPChannelTest, DNSCookieSpoof) {
2058   std::vector<byte> client_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2059   std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2060 
2061   DNSPacket reply_spoof;
2062   reply_spoof.set_response().set_aa()
2063     .add_question(new DNSQuestion("www.google.com", T_A))
2064     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
2065     .add_additional(new DNSOptRR(0, 0, 0, 1280, client_cookie, server_cookie, false));
2066   DNSPacket reply;
2067   reply.set_response().set_aa()
2068     .add_question(new DNSQuestion("www.google.com", T_A))
2069     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
2070     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, false));
2071 
2072   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
2073     .WillOnce(SetReply(&server_, &reply_spoof))
2074     .WillOnce(SetReply(&server_, &reply));
2075 
2076   /* This test will return a reply that doesn't have the same client cookie as
2077    * was sent, this should result in a drop of the packet alltogether, then
2078    * the library will retry and a proper result will be sent. */
2079   QueryResult result;
2080   ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result, NULL);
2081   Process();
2082   EXPECT_TRUE(result.done_);
2083   EXPECT_EQ(1, result.timeouts_);
2084 }
2085 
TEST_P(MockUDPChannelTest,DNSCookieTCPUpgrade)2086 TEST_P(MockUDPChannelTest, DNSCookieTCPUpgrade) {
2087   std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2088 
2089   DNSPacket reply_badcookie;
2090   reply_badcookie.set_response().set_aa().set_rcode(ARES_RCODE_BADCOOKIE & 0xF)
2091     .add_question(new DNSQuestion("www.google.com", T_A))
2092     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
2093     .add_additional(new DNSOptRR((ARES_RCODE_BADCOOKIE >> 4) & 0xFF, 0, 0, 1280, { }, server_cookie, false));
2094   DNSPacket reply;
2095   reply.set_response().set_aa()
2096     .add_question(new DNSQuestion("www.google.com", T_A))
2097     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
2098     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, { }, false));
2099 
2100   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
2101     .WillOnce(SetReply(&server_, &reply_badcookie))
2102     .WillOnce(SetReply(&server_, &reply_badcookie))
2103     .WillOnce(SetReply(&server_, &reply_badcookie))
2104     .WillOnce(SetReply(&server_, &reply));
2105 
2106   /* This test will establish the server supports cookies, but continuously
2107    * returns BADCOOKIE which is an indicator that there is some form of
2108    * AnyCast issue across servers, so it upgrades to TCP afterwards.  No
2109    * timeouts are recorded as the queries are sent back-to-back as immediate
2110    * reattempts after the response. */
2111   QueryResult result;
2112   ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result, NULL);
2113   Process();
2114   EXPECT_TRUE(result.done_);
2115   EXPECT_EQ(0, result.timeouts_);
2116 }
2117 
2118 
2119 #ifndef WIN32
TEST_P(MockChannelTest,HostAlias)2120 TEST_P(MockChannelTest, HostAlias) {
2121   DNSPacket reply;
2122   reply.set_response().set_aa()
2123     .add_question(new DNSQuestion("www.google.com", T_A))
2124     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
2125   ON_CALL(server_, OnRequest("www.google.com", T_A))
2126     .WillByDefault(SetReply(&server_, &reply));
2127 
2128   TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
2129   EnvValue with_env("HOSTALIASES", aliases.filename());
2130 
2131   HostResult result;
2132   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
2133   Process();
2134   EXPECT_TRUE(result.done_);
2135   std::stringstream ss;
2136   ss << result.host_;
2137   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
2138 }
2139 
TEST_P(MockChannelTest,HostAliasMissing)2140 TEST_P(MockChannelTest, HostAliasMissing) {
2141   DNSPacket yesfirst;
2142   yesfirst.set_response().set_aa()
2143     .add_question(new DNSQuestion("www.first.com", T_A))
2144     .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
2145   ON_CALL(server_, OnRequest("www.first.com", T_A))
2146     .WillByDefault(SetReply(&server_, &yesfirst));
2147 
2148   TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
2149   EnvValue with_env("HOSTALIASES", aliases.filename());
2150   HostResult result;
2151   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
2152   Process();
2153   EXPECT_TRUE(result.done_);
2154   std::stringstream ss;
2155   ss << result.host_;
2156   EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
2157 }
2158 
TEST_P(MockChannelTest,HostAliasMissingFile)2159 TEST_P(MockChannelTest, HostAliasMissingFile) {
2160   DNSPacket yesfirst;
2161   yesfirst.set_response().set_aa()
2162     .add_question(new DNSQuestion("www.first.com", T_A))
2163     .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
2164   ON_CALL(server_, OnRequest("www.first.com", T_A))
2165     .WillByDefault(SetReply(&server_, &yesfirst));
2166 
2167   EnvValue with_env("HOSTALIASES", "bogus.mcfile");
2168   HostResult result;
2169   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
2170   Process();
2171   EXPECT_TRUE(result.done_);
2172   std::stringstream ss;
2173   ss << result.host_;
2174   EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
2175 }
2176 
TEST_P(MockChannelTest,HostAliasUnreadable)2177 TEST_P(MockChannelTest, HostAliasUnreadable) {
2178   TempFile aliases("www www.google.com\n");
2179   EXPECT_EQ(chmod(aliases.filename(), 0), 0);
2180 
2181   /* Perform OS sanity checks.  We are observing on Debian after the chmod(fn, 0)
2182    * that we are still able to fopen() the file which is unexpected.  Skip the
2183    * test if we observe this behavior */
2184   struct stat st;
2185   EXPECT_EQ(stat(aliases.filename(), &st), 0);
2186   EXPECT_EQ(st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO), 0);
2187   FILE *fp = fopen(aliases.filename(), "r");
2188   if (fp != NULL) {
2189     if (verbose) std::cerr << "Skipping Test due to OS incompatibility (open file caching)" << std::endl;
2190     fclose(fp);
2191     return;
2192   }
2193 
2194   EnvValue with_env("HOSTALIASES", aliases.filename());
2195 
2196   HostResult result;
2197   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
2198   Process();
2199   EXPECT_TRUE(result.done_);
2200   EXPECT_EQ(ARES_EFILE, result.status_);
2201   chmod(aliases.filename(), 0777);
2202 }
2203 #endif
2204 
2205 class MockMultiServerChannelTest
2206   : public MockChannelOptsTest,
2207     public ::testing::WithParamInterface< std::pair<int, bool> > {
2208  public:
MockMultiServerChannelTest(ares_options * opts,int optmask)2209   MockMultiServerChannelTest(ares_options *opts, int optmask)
2210     : MockChannelOptsTest(3, GetParam().first, GetParam().second, false, opts, optmask) {}
CheckExample()2211   void CheckExample() {
2212     HostResult result;
2213     ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
2214     Process();
2215     EXPECT_TRUE(result.done_);
2216     std::stringstream ss;
2217     ss << result.host_;
2218     EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
2219   }
2220 };
2221 
2222 class NoRotateMultiMockTest : public MockMultiServerChannelTest {
2223  public:
NoRotateMultiMockTest()2224   NoRotateMultiMockTest() : MockMultiServerChannelTest(nullptr, ARES_OPT_NOROTATE) {}
2225 };
2226 
2227 
TEST_P(NoRotateMultiMockTest,ThirdServer)2228 TEST_P(NoRotateMultiMockTest, ThirdServer) {
2229   struct ares_options opts;
2230   int optmask = 0;
2231   memset(&opts, 0, sizeof(opts));
2232   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
2233   EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
2234   ares_destroy_options(&opts);
2235 
2236   DNSPacket servfailrsp;
2237   servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
2238     .add_question(new DNSQuestion("www.example.com", T_A));
2239   DNSPacket notimplrsp;
2240   notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
2241     .add_question(new DNSQuestion("www.example.com", T_A));
2242   DNSPacket okrsp;
2243   okrsp.set_response().set_aa()
2244     .add_question(new DNSQuestion("www.example.com", T_A))
2245     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
2246 
2247   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2248     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
2249   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2250     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
2251   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2252     .WillOnce(SetReply(servers_[2].get(), &okrsp));
2253   CheckExample();
2254 
2255   // Second time around, still starts from server [2], as [0] and [1] both
2256   // recorded failures
2257   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2258     .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
2259   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2260     .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
2261   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2262     .WillOnce(SetReply(servers_[1].get(), &okrsp));
2263   CheckExample();
2264 
2265   // Third time around, server order is [1] (f0), [2] (f1), [0] (f2), which
2266   // means [1] will get called twice in a row as after the first call
2267   // order will be  [1] (f1), [2] (f1), [0] (f2) since sort order is
2268   // (failure count, index)
2269   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2270     .WillOnce(SetReply(servers_[1].get(), &servfailrsp))
2271     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
2272   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2273     .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
2274   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2275     .WillOnce(SetReply(servers_[0].get(), &okrsp));
2276   CheckExample();
2277 }
2278 
TEST_P(NoRotateMultiMockTest,ServerNoResponseFailover)2279 TEST_P(NoRotateMultiMockTest, ServerNoResponseFailover) {
2280   std::vector<byte> nothing;
2281   DNSPacket okrsp;
2282   okrsp.set_response().set_aa()
2283     .add_question(new DNSQuestion("www.example.com", T_A))
2284     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
2285 
2286   /* Server #1 works fine on first attempt, then acts like its offline on
2287    * second, then backonline on the third. */
2288   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2289     .WillOnce(SetReply(servers_[0].get(), &okrsp))
2290     .WillOnce(SetReplyData(servers_[0].get(), nothing))
2291     .WillOnce(SetReply(servers_[0].get(), &okrsp));
2292 
2293   /* Server #2 always acts like its offline */
2294   ON_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2295     .WillByDefault(SetReplyData(servers_[1].get(), nothing));
2296 
2297   /* Server #3 works fine on first and second request, then no reply on 3rd */
2298   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2299     .WillOnce(SetReply(servers_[2].get(), &okrsp))
2300     .WillOnce(SetReply(servers_[2].get(), &okrsp))
2301     .WillOnce(SetReplyData(servers_[2].get(), nothing));
2302 
2303   HostResult result;
2304 
2305   /* 1. First server returns a response on the first request immediately, normal
2306    *    operation on channel. */
2307   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
2308   Process();
2309   EXPECT_TRUE(result.done_);
2310   EXPECT_EQ(0, result.timeouts_);
2311   std::stringstream ss1;
2312   ss1 << result.host_;
2313   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
2314 
2315   /* 2. On the second request, simulate the first and second servers not
2316    *    returning a response at all, but the 3rd server works, so should have
2317    *    2 timeouts. */
2318   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
2319   Process();
2320   EXPECT_TRUE(result.done_);
2321   EXPECT_EQ(2, result.timeouts_);
2322   std::stringstream ss2;
2323   ss2 << result.host_;
2324   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss2.str());
2325 
2326   /* 3. On the third request, the active server should be #3, so should respond
2327    *    immediately with no timeouts */
2328   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
2329   Process();
2330   EXPECT_TRUE(result.done_);
2331   EXPECT_EQ(0, result.timeouts_);
2332   std::stringstream ss3;
2333   ss3 << result.host_;
2334   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
2335 
2336   /* 4. On the fourth request, the active server should be #3, but will timeout,
2337    *    and the first server should then respond */
2338   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
2339   Process();
2340   EXPECT_TRUE(result.done_);
2341   EXPECT_EQ(1, result.timeouts_);
2342   std::stringstream ss4;
2343   ss4 << result.host_;
2344   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss4.str());
2345 }
2346 
2347 #if defined(_WIN32)
2348 #  define SERVER_FAILOVER_RETRY_DELAY 500
2349 #else
2350 #  define SERVER_FAILOVER_RETRY_DELAY 330
2351 #endif
2352 
2353 class ServerFailoverOptsMultiMockTest
2354   : public MockChannelOptsTest,
2355     public ::testing::WithParamInterface< std::pair<int, bool> > {
2356  public:
ServerFailoverOptsMultiMockTest()2357   ServerFailoverOptsMultiMockTest()
2358     : MockChannelOptsTest(4, GetParam().first, GetParam().second, false,
2359                           FillOptions(&opts_),
2360                           ARES_OPT_SERVER_FAILOVER | ARES_OPT_NOROTATE) {}
CheckExample()2361   void CheckExample() {
2362     HostResult result;
2363     ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
2364     Process();
2365     EXPECT_TRUE(result.done_);
2366     std::stringstream ss;
2367     ss << result.host_;
2368     EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
2369   }
2370 
FillOptions(struct ares_options * opts)2371   static struct ares_options* FillOptions(struct ares_options *opts) {
2372     memset(opts, 0, sizeof(struct ares_options));
2373     opts->server_failover_opts.retry_chance = 1;
2374     opts->server_failover_opts.retry_delay = SERVER_FAILOVER_RETRY_DELAY;
2375     return opts;
2376   }
2377  private:
2378   struct ares_options opts_;
2379 };
2380 
2381 
2382 // Test case to trigger server failover behavior. We use a retry chance of
2383 // 100% and a retry delay so that we can test behavior reliably.
TEST_P(ServerFailoverOptsMultiMockTest,ServerFailoverOpts)2384 TEST_P(ServerFailoverOptsMultiMockTest, ServerFailoverOpts) {
2385  DNSPacket servfailrsp;
2386   servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
2387     .add_question(new DNSQuestion("www.example.com", T_A));
2388   DNSPacket okrsp;
2389   okrsp.set_response().set_aa()
2390     .add_question(new DNSQuestion("www.example.com", T_A))
2391     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
2392 
2393   auto tv_begin = std::chrono::high_resolution_clock::now();
2394   auto tv_now   = std::chrono::high_resolution_clock::now();
2395   unsigned int delay_ms;
2396 
2397   // At start all servers are healthy, first server should be selected
2398   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: First server should be selected" << std::endl;
2399   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2400     .WillOnce(SetReply(servers_[0].get(), &okrsp));
2401   CheckExample();
2402 
2403   // Fail server #0 but leave server #1 as healthy.  This results in server
2404   // order:
2405   //  #1 (failures: 0), #2 (failures: 0), #3 (failures: 0), #0 (failures: 1)
2406   tv_now = std::chrono::high_resolution_clock::now();
2407   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Server0 will fail but leave Server1 as healthy" << std::endl;
2408   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2409     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
2410   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2411     .WillOnce(SetReply(servers_[1].get(), &okrsp));
2412   CheckExample();
2413 
2414   // Sleep for the retry delay (actually a little more than the retry delay to account
2415   // for unreliable timing, e.g. NTP slew) and send in another query. The real
2416   // query will be sent to Server #1 (which will succeed) and Server #0 will
2417   // be probed and return a successful result.  This leaves the server order
2418   // of:
2419   //   #0 (failures: 0), #1 (failures: 0), #2 (failures: 0), #3 (failures: 0)
2420   tv_now = std::chrono::high_resolution_clock::now();
2421   delay_ms = SERVER_FAILOVER_RETRY_DELAY + (SERVER_FAILOVER_RETRY_DELAY / 10);
2422   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
2423   ares_sleep_time(delay_ms);
2424   tv_now = std::chrono::high_resolution_clock::now();
2425   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Server0 should be past retry delay and should be probed (successful), server 1 will respond successful for real query" << std::endl;
2426   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2427     .WillOnce(SetReply(servers_[0].get(), &okrsp));
2428   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2429     .WillOnce(SetReply(servers_[1].get(), &okrsp));
2430   CheckExample();
2431 
2432 
2433   // Fail all servers for the first round of tries. On the second round, #0
2434   // responds successfully. This should leave server order of:
2435   //   #1 (failures: 0), #2 (failures: 1), #3 (failures: 1), #0 (failures: 2)
2436   // NOTE: A single query being retried won't spawn probes to downed servers,
2437   //       only an initial query attempt is eligible to spawn probes.  So
2438   //       no probes are sent for this test.
2439   tv_now = std::chrono::high_resolution_clock::now();
2440   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: All 4 servers will fail on the first attempt, server 0 will fail on second. Server 1 will succeed on second." << std::endl;
2441   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2442     .WillOnce(SetReply(servers_[0].get(), &servfailrsp))
2443     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
2444   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2445     .WillOnce(SetReply(servers_[1].get(), &servfailrsp))
2446     .WillOnce(SetReply(servers_[1].get(), &okrsp));
2447   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2448     .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
2449   EXPECT_CALL(*servers_[3], OnRequest("www.example.com", T_A))
2450     .WillOnce(SetReply(servers_[3].get(), &servfailrsp));
2451   CheckExample();
2452 
2453 
2454   // Sleep for the retry delay and send in another query. Server #1 is the
2455   // highest priority server and will respond with success, however a probe
2456   // will be sent for Server #2 which will succeed:
2457   //  #1 (failures: 0), #2 (failures: 0), #3 (failures: 1 - expired), #0 (failures: 2 - expired)
2458   tv_now = std::chrono::high_resolution_clock::now();
2459   delay_ms = SERVER_FAILOVER_RETRY_DELAY + (SERVER_FAILOVER_RETRY_DELAY / 10);
2460   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
2461   ares_sleep_time(delay_ms);
2462   tv_now = std::chrono::high_resolution_clock::now();
2463   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Past retry delay, will query Server 1 and probe Server 2, both will succeed." << std::endl;
2464   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2465     .WillOnce(SetReply(servers_[1].get(), &okrsp));
2466   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2467     .WillOnce(SetReply(servers_[2].get(), &okrsp));
2468   CheckExample();
2469 
2470   // Cause another server to fail so we have at least one non-expired failed
2471   // server and one expired failed server.  #1 is highest priority, which we
2472   // will fail, #2 will succeed, and #3 will be probed and succeed:
2473   //  #2 (failures: 0), #3 (failures: 0), #1 (failures: 1 not expired), #0 (failures: 2 expired)
2474   tv_now = std::chrono::high_resolution_clock::now();
2475   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Will query Server 1 and fail, Server 2 will answer successfully. Server 3 will be probed and succeed." << std::endl;
2476   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2477     .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
2478   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2479     .WillOnce(SetReply(servers_[2].get(), &okrsp));
2480   EXPECT_CALL(*servers_[3], OnRequest("www.example.com", T_A))
2481     .WillOnce(SetReply(servers_[3].get(), &okrsp));
2482   CheckExample();
2483 
2484   // We need to make sure that if there is a failed server that is higher priority
2485   // but not yet expired that it will probe the next failed server instead.
2486   // In this case #2 is the server that the query will go to and succeed, and
2487   // then a probe will be sent for #0 (since #1 is not expired) and succeed.  We
2488   // will sleep for 1/4 the retry duration before spawning the queries so we can
2489   // then sleep for the rest for the follow-up test.  This will leave the servers
2490   // in this state:
2491   //   #0 (failures: 0), #2 (failures: 0), #3 (failures: 0), #1 (failures: 1 not expired)
2492   tv_now = std::chrono::high_resolution_clock::now();
2493 
2494   // We need to track retry delay time to know what is expired when.
2495   auto elapse_start = tv_now;
2496 
2497   delay_ms = (SERVER_FAILOVER_RETRY_DELAY/4);
2498   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
2499   ares_sleep_time(delay_ms);
2500   tv_now = std::chrono::high_resolution_clock::now();
2501 
2502   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Retry delay has not been hit yet. Server2 will be queried and succeed. Server 0 (not server 1 due to non-expired retry delay) will be probed and succeed." << std::endl;
2503   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2504     .WillOnce(SetReply(servers_[2].get(), &okrsp));
2505   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2506     .WillOnce(SetReply(servers_[0].get(), &okrsp));
2507   CheckExample();
2508 
2509   // Finally we sleep for the remainder of the retry delay, send another
2510   // query, which should succeed on Server #0, and also probe Server #1 which
2511   // will also succeed.
2512   tv_now = std::chrono::high_resolution_clock::now();
2513 
2514   unsigned int elapsed_time = (unsigned int)std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - elapse_start).count();
2515   delay_ms = (SERVER_FAILOVER_RETRY_DELAY) + (SERVER_FAILOVER_RETRY_DELAY / 10);
2516   if (elapsed_time > delay_ms) {
2517     if (verbose) std::cerr << "elapsed duration " << elapsed_time << "ms greater than desired delay of " << delay_ms << "ms, not sleeping" << std::endl;
2518   } else {
2519     delay_ms -= elapsed_time; // subtract already elapsed time
2520     if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
2521     ares_sleep_time(delay_ms);
2522   }
2523   tv_now = std::chrono::high_resolution_clock::now();
2524   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Retry delay has expired on Server1, Server 0 will be queried and succeed, Server 1 will be probed and succeed." << std::endl;
2525   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
2526     .WillOnce(SetReply(servers_[0].get(), &okrsp));
2527   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
2528     .WillOnce(SetReply(servers_[1].get(), &okrsp));
2529   CheckExample();
2530 }
2531 
af_tostr(int af)2532 const char *af_tostr(int af)
2533 {
2534   switch (af) {
2535     case AF_INET:
2536       return "ipv4";
2537     case AF_INET6:
2538       return "ipv6";
2539   }
2540   return "ipunknown";
2541 }
2542 
mode_tostr(bool mode)2543 const char *mode_tostr(bool mode)
2544 {
2545   return mode?"ForceTCP":"DefaultUDP";
2546 }
2547 
PrintFamilyMode(const testing::TestParamInfo<std::pair<int,bool>> & info)2548 std::string PrintFamilyMode(const testing::TestParamInfo<std::pair<int, bool>> &info)
2549 {
2550   std::string name;
2551 
2552   name += af_tostr(std::get<0>(info.param));
2553   name += "_";
2554   name += mode_tostr(std::get<1>(info.param));
2555   return name;
2556 }
2557 
PrintFamily(const testing::TestParamInfo<int> & info)2558 std::string PrintFamily(const testing::TestParamInfo<int> &info)
2559 {
2560   std::string name;
2561 
2562   name += af_tostr(info.param);
2563   return name;
2564 }
2565 
2566 INSTANTIATE_TEST_SUITE_P(AddressFamilies, NoDNS0x20MockTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
2567 
2568 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockChannelTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2569 
2570 #ifdef HAVE_CONTAINER
2571 INSTANTIATE_TEST_SUITE_P(AddressFamilies, ContainedMockChannelSysConfig, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2572 #endif
2573 
2574 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
2575 
2576 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPMaxQueriesTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
2577 
2578 INSTANTIATE_TEST_SUITE_P(AddressFamilies, CacheQueriesTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
2579 
2580 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockTCPChannelTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
2581 
2582 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockExtraOptsTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2583 
2584 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockNoCheckRespChannelTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2585 
2586 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockEDNSChannelTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2587 
2588 INSTANTIATE_TEST_SUITE_P(TransportModes, NoRotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2589 
2590 INSTANTIATE_TEST_SUITE_P(TransportModes, ServerFailoverOptsMultiMockTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2591 
2592 }  // namespace test
2593 }  // namespace ares
2594