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_, ¬hird));
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_, ¬hird));
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_, ¬hird));
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_, ¬hird_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(©, 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(), ¬implrsp));
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(), ¬implrsp));
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(), ¬implrsp));
2272 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
2273 .WillOnce(SetReply(servers_[2].get(), ¬implrsp));
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