blob: 2cbe6b4a171c90eb72ade079172ce23a43a787f5 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#include "ares-test.h"
2#include "dns-proto.h"
3
4#include <sstream>
5#include <vector>
6
7using testing::InvokeWithoutArgs;
8using testing::DoAll;
9
10namespace ares {
11namespace test {
12
13TEST_P(MockChannelTest, Basic) {
14 std::vector<byte> reply = {
15 0x00, 0x00, // qid
16 0x84, // response + query + AA + not-TC + not-RD
17 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
18 0x00, 0x01, // 1 question
19 0x00, 0x01, // 1 answer RRs
20 0x00, 0x00, // 0 authority RRs
21 0x00, 0x00, // 0 additional RRs
22 // Question
23 0x03, 'w', 'w', 'w',
24 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
25 0x03, 'c', 'o', 'm',
26 0x00,
27 0x00, 0x01, // type A
28 0x00, 0x01, // class IN
29 // Answer
30 0x03, 'w', 'w', 'w',
31 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
32 0x03, 'c', 'o', 'm',
33 0x00,
34 0x00, 0x01, // type A
35 0x00, 0x01, // class IN
36 0x00, 0x00, 0x01, 0x00, // TTL
37 0x00, 0x04, // rdata length
38 0x01, 0x02, 0x03, 0x04
39 };
40
41 ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
42 .WillByDefault(SetReplyData(&server_, reply));
43
44 HostResult result;
45 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
46 Process();
47 EXPECT_TRUE(result.done_);
48 std::stringstream ss;
49 ss << result.host_;
50 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
51}
52
53// UDP only so mock server doesn't get confused by concatenated requests
54TEST_P(MockUDPChannelTest, ParallelLookups) {
55 DNSPacket rsp1;
56 rsp1.set_response().set_aa()
57 .add_question(new DNSQuestion("www.google.com", ns_t_a))
58 .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
59 ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
60 .WillByDefault(SetReply(&server_, &rsp1));
61 DNSPacket rsp2;
62 rsp2.set_response().set_aa()
63 .add_question(new DNSQuestion("www.example.com", ns_t_a))
64 .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
65 ON_CALL(server_, OnRequest("www.example.com", ns_t_a))
66 .WillByDefault(SetReply(&server_, &rsp2));
67
68 HostResult result1;
69 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
70 HostResult result2;
71 ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result2);
72 HostResult result3;
73 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result3);
74 Process();
75 EXPECT_TRUE(result1.done_);
76 EXPECT_TRUE(result2.done_);
77 EXPECT_TRUE(result3.done_);
78 std::stringstream ss1;
79 ss1 << result1.host_;
80 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
81 std::stringstream ss2;
82 ss2 << result2.host_;
83 EXPECT_EQ("{'www.example.com' aliases=[] addrs=[1.2.3.4]}", ss2.str());
84 std::stringstream ss3;
85 ss3 << result3.host_;
86 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
87}
88
89// UDP to TCP specific test
90TEST_P(MockUDPChannelTest, TruncationRetry) {
91 DNSPacket rsptruncated;
92 rsptruncated.set_response().set_aa().set_tc()
93 .add_question(new DNSQuestion("www.google.com", ns_t_a));
94 DNSPacket rspok;
95 rspok.set_response()
96 .add_question(new DNSQuestion("www.google.com", ns_t_a))
97 .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
98 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
99 .WillOnce(SetReply(&server_, &rsptruncated))
100 .WillOnce(SetReply(&server_, &rspok));
101 HostResult result;
102 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
103 Process();
104 EXPECT_TRUE(result.done_);
105 std::stringstream ss;
106 ss << result.host_;
107 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
108}
109
110static int sock_cb_count = 0;
111static int SocketConnectCallback(ares_socket_t fd, int type, void *data) {
112 int rc = *(int*)data;
113 if (verbose) std::cerr << "SocketConnectCallback(" << fd << ") invoked" << std::endl;
114 sock_cb_count++;
115 return rc;
116}
117
118TEST_P(MockChannelTest, SockCallback) {
119 DNSPacket rsp;
120 rsp.set_response().set_aa()
121 .add_question(new DNSQuestion("www.google.com", ns_t_a))
122 .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
123 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
124 .WillOnce(SetReply(&server_, &rsp));
125
126 // Get notified of new sockets
127 int rc = ARES_SUCCESS;
128 ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
129
130 HostResult result;
131 sock_cb_count = 0;
132 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
133 Process();
134 EXPECT_EQ(1, sock_cb_count);
135 EXPECT_TRUE(result.done_);
136 std::stringstream ss;
137 ss << result.host_;
138 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
139}
140
141TEST_P(MockChannelTest, SockFailCallback) {
142 // Notification of new sockets gives an error.
143 int rc = -1;
144 ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
145
146 HostResult result;
147 sock_cb_count = 0;
148 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
149 Process();
150 EXPECT_LT(1, sock_cb_count);
151 EXPECT_TRUE(result.done_);
152 EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
153}
154
155static int sock_config_cb_count = 0;
156static int SocketConfigureCallback(ares_socket_t fd, int type, void *data) {
157 int rc = *(int*)data;
158 if (verbose) std::cerr << "SocketConfigureCallback(" << fd << ") invoked" << std::endl;
159 sock_config_cb_count++;
160 return rc;
161}
162
163TEST_P(MockChannelTest, SockConfigureCallback) {
164 DNSPacket rsp;
165 rsp.set_response().set_aa()
166 .add_question(new DNSQuestion("www.google.com", ns_t_a))
167 .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
168 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
169 .WillOnce(SetReply(&server_, &rsp));
170
171 // Get notified of new sockets
172 int rc = ARES_SUCCESS;
173 ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
174
175 HostResult result;
176 sock_config_cb_count = 0;
177 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
178 Process();
179 EXPECT_EQ(1, sock_config_cb_count);
180 EXPECT_TRUE(result.done_);
181 std::stringstream ss;
182 ss << result.host_;
183 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
184}
185
186TEST_P(MockChannelTest, SockConfigureFailCallback) {
187 // Notification of new sockets gives an error.
188 int rc = -1;
189 ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
190
191 HostResult result;
192 sock_config_cb_count = 0;
193 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
194 Process();
195 EXPECT_LT(1, sock_config_cb_count);
196 EXPECT_TRUE(result.done_);
197 EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
198}
199
200// TCP only to prevent retries
201TEST_P(MockTCPChannelTest, MalformedResponse) {
202 std::vector<byte> one = {0x01};
203 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
204 .WillOnce(SetReplyData(&server_, one));
205
206 HostResult result;
207 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
208 Process();
209 EXPECT_TRUE(result.done_);
210 EXPECT_EQ(ARES_ETIMEOUT, result.status_);
211}
212
213TEST_P(MockTCPChannelTest, FormErrResponse) {
214 DNSPacket rsp;
215 rsp.set_response().set_aa()
216 .add_question(new DNSQuestion("www.google.com", ns_t_a));
217 rsp.set_rcode(ns_r_formerr);
218 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
219 .WillOnce(SetReply(&server_, &rsp));
220 HostResult result;
221 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
222 Process();
223 EXPECT_TRUE(result.done_);
224 EXPECT_EQ(ARES_EFORMERR, result.status_);
225}
226
227TEST_P(MockTCPChannelTest, ServFailResponse) {
228 DNSPacket rsp;
229 rsp.set_response().set_aa()
230 .add_question(new DNSQuestion("www.google.com", ns_t_a));
231 rsp.set_rcode(ns_r_servfail);
232 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
233 .WillOnce(SetReply(&server_, &rsp));
234 HostResult result;
235 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
236 Process();
237 EXPECT_TRUE(result.done_);
238 // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
239 EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
240}
241
242TEST_P(MockTCPChannelTest, NotImplResponse) {
243 DNSPacket rsp;
244 rsp.set_response().set_aa()
245 .add_question(new DNSQuestion("www.google.com", ns_t_a));
246 rsp.set_rcode(ns_r_notimpl);
247 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
248 .WillOnce(SetReply(&server_, &rsp));
249 HostResult result;
250 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
251 Process();
252 EXPECT_TRUE(result.done_);
253 // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed
254 EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
255}
256
257TEST_P(MockTCPChannelTest, RefusedResponse) {
258 DNSPacket rsp;
259 rsp.set_response().set_aa()
260 .add_question(new DNSQuestion("www.google.com", ns_t_a));
261 rsp.set_rcode(ns_r_refused);
262 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
263 .WillOnce(SetReply(&server_, &rsp));
264 HostResult result;
265 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
266 Process();
267 EXPECT_TRUE(result.done_);
268 // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
269 EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
270}
271
272TEST_P(MockTCPChannelTest, YXDomainResponse) {
273 DNSPacket rsp;
274 rsp.set_response().set_aa()
275 .add_question(new DNSQuestion("www.google.com", ns_t_a));
276 rsp.set_rcode(ns_r_yxdomain);
277 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
278 .WillOnce(SetReply(&server_, &rsp));
279 HostResult result;
280 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
281 Process();
282 EXPECT_TRUE(result.done_);
283 EXPECT_EQ(ARES_ENODATA, result.status_);
284}
285
286class MockExtraOptsTest
287 : public MockChannelOptsTest,
288 public ::testing::WithParamInterface< std::pair<int, bool> > {
289 public:
290 MockExtraOptsTest()
291 : MockChannelOptsTest(1, GetParam().first, GetParam().second,
292 FillOptions(&opts_),
293 ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
294 static struct ares_options* FillOptions(struct ares_options * opts) {
295 memset(opts, 0, sizeof(struct ares_options));
296 // Set a few options that affect socket communications
297 opts->socket_send_buffer_size = 514;
298 opts->socket_receive_buffer_size = 514;
299 return opts;
300 }
301 private:
302 struct ares_options opts_;
303};
304
305TEST_P(MockExtraOptsTest, SimpleQuery) {
306 ares_set_local_ip4(channel_, 0x7F000001);
307 byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
309 ares_set_local_ip6(channel_, addr6);
310 ares_set_local_dev(channel_, "dummy");
311
312 DNSPacket rsp;
313 rsp.set_response().set_aa()
314 .add_question(new DNSQuestion("www.google.com", ns_t_a))
315 .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
316 ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
317 .WillByDefault(SetReply(&server_, &rsp));
318
319 HostResult result;
320 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
321 Process();
322 EXPECT_TRUE(result.done_);
323 std::stringstream ss;
324 ss << result.host_;
325 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
326}
327
328class MockFlagsChannelOptsTest
329 : public MockChannelOptsTest,
330 public ::testing::WithParamInterface< std::pair<int, bool> > {
331 public:
332 MockFlagsChannelOptsTest(int flags)
333 : MockChannelOptsTest(1, GetParam().first, GetParam().second,
334 FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
335 static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
336 memset(opts, 0, sizeof(struct ares_options));
337 opts->flags = flags;
338 return opts;
339 }
340 private:
341 struct ares_options opts_;
342};
343
344class MockNoCheckRespChannelTest : public MockFlagsChannelOptsTest {
345 public:
346 MockNoCheckRespChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_NOCHECKRESP) {}
347};
348
349TEST_P(MockNoCheckRespChannelTest, ServFailResponse) {
350 DNSPacket rsp;
351 rsp.set_response().set_aa()
352 .add_question(new DNSQuestion("www.google.com", ns_t_a));
353 rsp.set_rcode(ns_r_servfail);
354 ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
355 .WillByDefault(SetReply(&server_, &rsp));
356 HostResult result;
357 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
358 Process();
359 EXPECT_TRUE(result.done_);
360 EXPECT_EQ(ARES_ESERVFAIL, result.status_);
361}
362
363TEST_P(MockNoCheckRespChannelTest, NotImplResponse) {
364 DNSPacket rsp;
365 rsp.set_response().set_aa()
366 .add_question(new DNSQuestion("www.google.com", ns_t_a));
367 rsp.set_rcode(ns_r_notimpl);
368 ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
369 .WillByDefault(SetReply(&server_, &rsp));
370 HostResult result;
371 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
372 Process();
373 EXPECT_TRUE(result.done_);
374 EXPECT_EQ(ARES_ENOTIMP, result.status_);
375}
376
377TEST_P(MockNoCheckRespChannelTest, RefusedResponse) {
378 DNSPacket rsp;
379 rsp.set_response().set_aa()
380 .add_question(new DNSQuestion("www.google.com", ns_t_a));
381 rsp.set_rcode(ns_r_refused);
382 ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
383 .WillByDefault(SetReply(&server_, &rsp));
384 HostResult result;
385 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
386 Process();
387 EXPECT_TRUE(result.done_);
388 EXPECT_EQ(ARES_EREFUSED, result.status_);
389}
390
391class MockEDNSChannelTest : public MockFlagsChannelOptsTest {
392 public:
393 MockEDNSChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_EDNS) {}
394};
395
396TEST_P(MockEDNSChannelTest, RetryWithoutEDNS) {
397 DNSPacket rspfail;
398 rspfail.set_response().set_aa().set_rcode(ns_r_servfail)
399 .add_question(new DNSQuestion("www.google.com", ns_t_a));
400 DNSPacket rspok;
401 rspok.set_response()
402 .add_question(new DNSQuestion("www.google.com", ns_t_a))
403 .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
404 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
405 .WillOnce(SetReply(&server_, &rspfail))
406 .WillOnce(SetReply(&server_, &rspok));
407 HostResult result;
408 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
409 Process();
410 EXPECT_TRUE(result.done_);
411 std::stringstream ss;
412 ss << result.host_;
413 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
414}
415
416TEST_P(MockChannelTest, SearchDomains) {
417 DNSPacket nofirst;
418 nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
419 .add_question(new DNSQuestion("www.first.com", ns_t_a));
420 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
421 .WillByDefault(SetReply(&server_, &nofirst));
422 DNSPacket nosecond;
423 nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
424 .add_question(new DNSQuestion("www.second.org", ns_t_a));
425 ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
426 .WillByDefault(SetReply(&server_, &nosecond));
427 DNSPacket yesthird;
428 yesthird.set_response().set_aa()
429 .add_question(new DNSQuestion("www.third.gov", ns_t_a))
430 .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
431 ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
432 .WillByDefault(SetReply(&server_, &yesthird));
433
434 HostResult result;
435 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
436 Process();
437 EXPECT_TRUE(result.done_);
438 std::stringstream ss;
439 ss << result.host_;
440 EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
441}
442
443// Relies on retries so is UDP-only
444TEST_P(MockUDPChannelTest, SearchDomainsWithResentReply) {
445 DNSPacket nofirst;
446 nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
447 .add_question(new DNSQuestion("www.first.com", ns_t_a));
448 EXPECT_CALL(server_, OnRequest("www.first.com", ns_t_a))
449 .WillOnce(SetReply(&server_, &nofirst));
450 DNSPacket nosecond;
451 nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
452 .add_question(new DNSQuestion("www.second.org", ns_t_a));
453 EXPECT_CALL(server_, OnRequest("www.second.org", ns_t_a))
454 .WillOnce(SetReply(&server_, &nosecond));
455 DNSPacket yesthird;
456 yesthird.set_response().set_aa()
457 .add_question(new DNSQuestion("www.third.gov", ns_t_a))
458 .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
459 // Before sending the real answer, resend an earlier reply
460 EXPECT_CALL(server_, OnRequest("www.third.gov", ns_t_a))
461 .WillOnce(DoAll(SetReply(&server_, &nofirst),
462 SetReplyQID(&server_, 123)))
463 .WillOnce(DoAll(SetReply(&server_, &yesthird),
464 SetReplyQID(&server_, -1)));
465
466 HostResult result;
467 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
468 Process();
469 EXPECT_TRUE(result.done_);
470 std::stringstream ss;
471 ss << result.host_;
472 EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
473}
474
475TEST_P(MockChannelTest, SearchDomainsBare) {
476 DNSPacket nofirst;
477 nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
478 .add_question(new DNSQuestion("www.first.com", ns_t_a));
479 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
480 .WillByDefault(SetReply(&server_, &nofirst));
481 DNSPacket nosecond;
482 nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
483 .add_question(new DNSQuestion("www.second.org", ns_t_a));
484 ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
485 .WillByDefault(SetReply(&server_, &nosecond));
486 DNSPacket nothird;
487 nothird.set_response().set_aa().set_rcode(ns_r_nxdomain)
488 .add_question(new DNSQuestion("www.third.gov", ns_t_a));
489 ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
490 .WillByDefault(SetReply(&server_, &nothird));
491 DNSPacket yesbare;
492 yesbare.set_response().set_aa()
493 .add_question(new DNSQuestion("www", ns_t_a))
494 .add_answer(new DNSARR("www", 0x0200, {2, 3, 4, 5}));
495 ON_CALL(server_, OnRequest("www", ns_t_a))
496 .WillByDefault(SetReply(&server_, &yesbare));
497
498 HostResult result;
499 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
500 Process();
501 EXPECT_TRUE(result.done_);
502 std::stringstream ss;
503 ss << result.host_;
504 EXPECT_EQ("{'www' aliases=[] addrs=[2.3.4.5]}", ss.str());
505}
506
507TEST_P(MockChannelTest, SearchNoDataThenSuccess) {
508 // First two search domains recognize the name but have no A records.
509 DNSPacket nofirst;
510 nofirst.set_response().set_aa()
511 .add_question(new DNSQuestion("www.first.com", ns_t_a));
512 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
513 .WillByDefault(SetReply(&server_, &nofirst));
514 DNSPacket nosecond;
515 nosecond.set_response().set_aa()
516 .add_question(new DNSQuestion("www.second.org", ns_t_a));
517 ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
518 .WillByDefault(SetReply(&server_, &nosecond));
519 DNSPacket yesthird;
520 yesthird.set_response().set_aa()
521 .add_question(new DNSQuestion("www.third.gov", ns_t_a))
522 .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
523 ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
524 .WillByDefault(SetReply(&server_, &yesthird));
525
526 HostResult result;
527 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
528 Process();
529 EXPECT_TRUE(result.done_);
530 std::stringstream ss;
531 ss << result.host_;
532 EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
533}
534
535TEST_P(MockChannelTest, SearchNoDataThenNoDataBare) {
536 // First two search domains recognize the name but have no A records.
537 DNSPacket nofirst;
538 nofirst.set_response().set_aa()
539 .add_question(new DNSQuestion("www.first.com", ns_t_a));
540 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
541 .WillByDefault(SetReply(&server_, &nofirst));
542 DNSPacket nosecond;
543 nosecond.set_response().set_aa()
544 .add_question(new DNSQuestion("www.second.org", ns_t_a));
545 ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
546 .WillByDefault(SetReply(&server_, &nosecond));
547 DNSPacket nothird;
548 nothird.set_response().set_aa()
549 .add_question(new DNSQuestion("www.third.gov", ns_t_a));
550 ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
551 .WillByDefault(SetReply(&server_, &nothird));
552 DNSPacket nobare;
553 nobare.set_response().set_aa()
554 .add_question(new DNSQuestion("www", ns_t_a));
555 ON_CALL(server_, OnRequest("www", ns_t_a))
556 .WillByDefault(SetReply(&server_, &nobare));
557
558 HostResult result;
559 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
560 Process();
561 EXPECT_TRUE(result.done_);
562 EXPECT_EQ(ARES_ENODATA, result.status_);
563}
564
565TEST_P(MockChannelTest, SearchNoDataThenFail) {
566 // First two search domains recognize the name but have no A records.
567 DNSPacket nofirst;
568 nofirst.set_response().set_aa()
569 .add_question(new DNSQuestion("www.first.com", ns_t_a));
570 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
571 .WillByDefault(SetReply(&server_, &nofirst));
572 DNSPacket nosecond;
573 nosecond.set_response().set_aa()
574 .add_question(new DNSQuestion("www.second.org", ns_t_a));
575 ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
576 .WillByDefault(SetReply(&server_, &nosecond));
577 DNSPacket nothird;
578 nothird.set_response().set_aa()
579 .add_question(new DNSQuestion("www.third.gov", ns_t_a));
580 ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
581 .WillByDefault(SetReply(&server_, &nothird));
582 DNSPacket nobare;
583 nobare.set_response().set_aa().set_rcode(ns_r_nxdomain)
584 .add_question(new DNSQuestion("www", ns_t_a));
585 ON_CALL(server_, OnRequest("www", ns_t_a))
586 .WillByDefault(SetReply(&server_, &nobare));
587
588 HostResult result;
589 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
590 Process();
591 EXPECT_TRUE(result.done_);
592 EXPECT_EQ(ARES_ENODATA, result.status_);
593}
594
595TEST_P(MockChannelTest, SearchAllocFailure) {
596 SearchResult result;
597 SetAllocFail(1);
598 ares_search(channel_, "fully.qualified.", ns_c_in, ns_t_a, SearchCallback, &result);
599 /* Already done */
600 EXPECT_TRUE(result.done_);
601 EXPECT_EQ(ARES_ENOMEM, result.status_);
602}
603
604TEST_P(MockChannelTest, SearchHighNdots) {
605 DNSPacket nobare;
606 nobare.set_response().set_aa().set_rcode(ns_r_nxdomain)
607 .add_question(new DNSQuestion("a.b.c.w.w.w", ns_t_a));
608 ON_CALL(server_, OnRequest("a.b.c.w.w.w", ns_t_a))
609 .WillByDefault(SetReply(&server_, &nobare));
610 DNSPacket yesfirst;
611 yesfirst.set_response().set_aa()
612 .add_question(new DNSQuestion("a.b.c.w.w.w.first.com", ns_t_a))
613 .add_answer(new DNSARR("a.b.c.w.w.w.first.com", 0x0200, {2, 3, 4, 5}));
614 ON_CALL(server_, OnRequest("a.b.c.w.w.w.first.com", ns_t_a))
615 .WillByDefault(SetReply(&server_, &yesfirst));
616
617 SearchResult result;
618 ares_search(channel_, "a.b.c.w.w.w", ns_c_in, ns_t_a, SearchCallback, &result);
619 Process();
620 EXPECT_TRUE(result.done_);
621 EXPECT_EQ(ARES_SUCCESS, result.status_);
622 std::stringstream ss;
623 ss << PacketToString(result.data_);
624 EXPECT_EQ("RSP QRY AA NOERROR Q:{'a.b.c.w.w.w.first.com' IN A} "
625 "A:{'a.b.c.w.w.w.first.com' IN A TTL=512 2.3.4.5}",
626 ss.str());
627}
628
629TEST_P(MockChannelTest, UnspecifiedFamilyV6) {
630 DNSPacket rsp6;
631 rsp6.set_response().set_aa()
632 .add_question(new DNSQuestion("example.com", ns_t_aaaa))
633 .add_answer(new DNSAaaaRR("example.com", 100,
634 {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
636 ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
637 .WillByDefault(SetReply(&server_, &rsp6));
638
639 HostResult result;
640 ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
641 Process();
642 EXPECT_TRUE(result.done_);
643 std::stringstream ss;
644 ss << result.host_;
645 // Default to IPv6 when both are available.
646 EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
647}
648
649TEST_P(MockChannelTest, UnspecifiedFamilyV4) {
650 DNSPacket rsp6;
651 rsp6.set_response().set_aa()
652 .add_question(new DNSQuestion("example.com", ns_t_aaaa));
653 ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
654 .WillByDefault(SetReply(&server_, &rsp6));
655 DNSPacket rsp4;
656 rsp4.set_response().set_aa()
657 .add_question(new DNSQuestion("example.com", ns_t_a))
658 .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
659 ON_CALL(server_, OnRequest("example.com", ns_t_a))
660 .WillByDefault(SetReply(&server_, &rsp4));
661
662 HostResult result;
663 ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
664 Process();
665 EXPECT_TRUE(result.done_);
666 std::stringstream ss;
667 ss << result.host_;
668 EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
669}
670
671TEST_P(MockChannelTest, UnspecifiedFamilyNoData) {
672 DNSPacket rsp6;
673 rsp6.set_response().set_aa()
674 .add_question(new DNSQuestion("example.com", ns_t_aaaa))
675 .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
676 ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
677 .WillByDefault(SetReply(&server_, &rsp6));
678 DNSPacket rsp4;
679 rsp4.set_response().set_aa()
680 .add_question(new DNSQuestion("example.com", ns_t_a));
681 ON_CALL(server_, OnRequest("example.com", ns_t_a))
682 .WillByDefault(SetReply(&server_, &rsp4));
683
684 HostResult result;
685 ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
686 Process();
687 EXPECT_TRUE(result.done_);
688 std::stringstream ss;
689 ss << result.host_;
690 EXPECT_EQ("{'' aliases=[] addrs=[]}", ss.str());
691}
692
693TEST_P(MockChannelTest, UnspecifiedFamilyCname6A4) {
694 DNSPacket rsp6;
695 rsp6.set_response().set_aa()
696 .add_question(new DNSQuestion("example.com", ns_t_aaaa))
697 .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
698 ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
699 .WillByDefault(SetReply(&server_, &rsp6));
700 DNSPacket rsp4;
701 rsp4.set_response().set_aa()
702 .add_question(new DNSQuestion("example.com", ns_t_a))
703 .add_answer(new DNSARR("example.com", 100, {1, 2, 3, 4}));
704 ON_CALL(server_, OnRequest("example.com", ns_t_a))
705 .WillByDefault(SetReply(&server_, &rsp4));
706
707 HostResult result;
708 ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
709 Process();
710 EXPECT_TRUE(result.done_);
711 std::stringstream ss;
712 ss << result.host_;
713 EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
714}
715
716TEST_P(MockChannelTest, ExplicitIP) {
717 HostResult result;
718 ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
719 EXPECT_TRUE(result.done_); // Immediate return
720 EXPECT_EQ(ARES_SUCCESS, result.status_);
721 std::stringstream ss;
722 ss << result.host_;
723 EXPECT_EQ("{'1.2.3.4' aliases=[] addrs=[1.2.3.4]}", ss.str());
724}
725
726TEST_P(MockChannelTest, ExplicitIPAllocFail) {
727 HostResult result;
728 SetAllocSizeFail(strlen("1.2.3.4") + 1);
729 ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
730 EXPECT_TRUE(result.done_); // Immediate return
731 EXPECT_EQ(ARES_ENOMEM, result.status_);
732}
733
734TEST_P(MockChannelTest, SortListV4) {
735 DNSPacket rsp;
736 rsp.set_response().set_aa()
737 .add_question(new DNSQuestion("example.com", ns_t_a))
738 .add_answer(new DNSARR("example.com", 100, {22, 23, 24, 25}))
739 .add_answer(new DNSARR("example.com", 100, {12, 13, 14, 15}))
740 .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
741 ON_CALL(server_, OnRequest("example.com", ns_t_a))
742 .WillByDefault(SetReply(&server_, &rsp));
743
744 {
745 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "12.13.0.0/255.255.0.0 1234::5678"));
746 HostResult result;
747 ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
748 Process();
749 EXPECT_TRUE(result.done_);
750 std::stringstream ss;
751 ss << result.host_;
752 EXPECT_EQ("{'example.com' aliases=[] addrs=[12.13.14.15, 22.23.24.25, 2.3.4.5]}", ss.str());
753 }
754 {
755 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "2.3.0.0/16 130.140.150.160/26"));
756 HostResult result;
757 ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
758 Process();
759 EXPECT_TRUE(result.done_);
760 std::stringstream ss;
761 ss << result.host_;
762 EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5, 22.23.24.25, 12.13.14.15]}", ss.str());
763 }
764 struct ares_options options;
765 memset(&options, 0, sizeof(options));
766 int optmask = 0;
767 EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &options, &optmask));
768 EXPECT_TRUE((optmask & ARES_OPT_SORTLIST) == ARES_OPT_SORTLIST);
769 ares_destroy_options(&options);
770}
771
772TEST_P(MockChannelTest, SortListV6) {
773 DNSPacket rsp;
774 rsp.set_response().set_aa()
775 .add_question(new DNSQuestion("example.com", ns_t_aaaa))
776 .add_answer(new DNSAaaaRR("example.com", 100,
777 {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02}))
779 .add_answer(new DNSAaaaRR("example.com", 100,
780 {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
782 ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
783 .WillByDefault(SetReply(&server_, &rsp));
784
785 {
786 ares_set_sortlist(channel_, "1111::/16 2.3.0.0/255.255.0.0");
787 HostResult result;
788 ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
789 Process();
790 EXPECT_TRUE(result.done_);
791 std::stringstream ss;
792 ss << result.host_;
793 EXPECT_EQ("{'example.com' aliases=[] addrs=[1111:0000:0000:0000:0000:0000:0000:0202, "
794 "2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
795 }
796 {
797 ares_set_sortlist(channel_, "2121::/8");
798 HostResult result;
799 ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
800 Process();
801 EXPECT_TRUE(result.done_);
802 std::stringstream ss;
803 ss << result.host_;
804 EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303, "
805 "1111:0000:0000:0000:0000:0000:0000:0202]}", ss.str());
806 }
807}
808
809// Relies on retries so is UDP-only
810TEST_P(MockUDPChannelTest, SearchDomainsAllocFail) {
811 DNSPacket nofirst;
812 nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
813 .add_question(new DNSQuestion("www.first.com", ns_t_a));
814 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
815 .WillByDefault(SetReply(&server_, &nofirst));
816 DNSPacket nosecond;
817 nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
818 .add_question(new DNSQuestion("www.second.org", ns_t_a));
819 ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
820 .WillByDefault(SetReply(&server_, &nosecond));
821 DNSPacket yesthird;
822 yesthird.set_response().set_aa()
823 .add_question(new DNSQuestion("www.third.gov", ns_t_a))
824 .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
825 ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
826 .WillByDefault(SetReply(&server_, &yesthird));
827
828 // Fail a variety of different memory allocations, and confirm
829 // that the operation either fails with ENOMEM or succeeds
830 // with the expected result.
831 const int kCount = 34;
832 HostResult results[kCount];
833 for (int ii = 1; ii <= kCount; ii++) {
834 HostResult* result = &(results[ii - 1]);
835 ClearFails();
836 SetAllocFail(ii);
837 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, result);
838 Process();
839 EXPECT_TRUE(result->done_);
840 if (result->status_ == ARES_SUCCESS) {
841 std::stringstream ss;
842 ss << result->host_;
843 EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str()) << " failed alloc #" << ii;
844 if (verbose) std::cerr << "Succeeded despite failure of alloc #" << ii << std::endl;
845 }
846 }
847
848 // Explicitly destroy the channel now, so that the HostResult objects
849 // are still valid (in case any pending work refers to them).
850 ares_destroy(channel_);
851 channel_ = nullptr;
852}
853
854// Relies on retries so is UDP-only
855TEST_P(MockUDPChannelTest, Resend) {
856 std::vector<byte> nothing;
857 DNSPacket reply;
858 reply.set_response().set_aa()
859 .add_question(new DNSQuestion("www.google.com", ns_t_a))
860 .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
861
862 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
863 .WillOnce(SetReplyData(&server_, nothing))
864 .WillOnce(SetReplyData(&server_, nothing))
865 .WillOnce(SetReply(&server_, &reply));
866
867 HostResult result;
868 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
869 Process();
870 EXPECT_TRUE(result.done_);
871 EXPECT_EQ(2, result.timeouts_);
872 std::stringstream ss;
873 ss << result.host_;
874 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
875}
876
877TEST_P(MockChannelTest, CancelImmediate) {
878 HostResult result;
879 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
880 ares_cancel(channel_);
881 EXPECT_TRUE(result.done_);
882 EXPECT_EQ(ARES_ECANCELLED, result.status_);
883 EXPECT_EQ(0, result.timeouts_);
884}
885
886// Relies on retries so is UDP-only
887TEST_P(MockUDPChannelTest, CancelLater) {
888 std::vector<byte> nothing;
889
890 // On second request, cancel the channel.
891 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
892 .WillOnce(SetReplyData(&server_, nothing))
893 .WillOnce(CancelChannel(&server_, channel_));
894
895 HostResult result;
896 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
897 Process();
898 EXPECT_TRUE(result.done_);
899 EXPECT_EQ(ARES_ECANCELLED, result.status_);
900 EXPECT_EQ(0, result.timeouts_);
901}
902
903TEST_P(MockChannelTest, GetHostByNameDestroyAbsolute) {
904 HostResult result;
905 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
906
907 ares_destroy(channel_);
908 channel_ = nullptr;
909
910 EXPECT_TRUE(result.done_); // Synchronous
911 EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
912 EXPECT_EQ(0, result.timeouts_);
913}
914
915TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
916 HostResult result;
917 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
918
919 ares_destroy(channel_);
920 channel_ = nullptr;
921
922 EXPECT_TRUE(result.done_); // Synchronous
923 EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
924 EXPECT_EQ(0, result.timeouts_);
925}
926
927TEST_P(MockChannelTest, GetHostByAddrDestroy) {
928 unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
929 HostResult result;
930 ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
931
932 ares_destroy(channel_);
933 channel_ = nullptr;
934
935 EXPECT_TRUE(result.done_); // Synchronous
936 EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
937 EXPECT_EQ(0, result.timeouts_);
938}
939
940#ifndef WIN32
941TEST_P(MockChannelTest, HostAlias) {
942 DNSPacket reply;
943 reply.set_response().set_aa()
944 .add_question(new DNSQuestion("www.google.com", ns_t_a))
945 .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
946 ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
947 .WillByDefault(SetReply(&server_, &reply));
948
949 TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
950 EnvValue with_env("HOSTALIASES", aliases.filename());
951
952 HostResult result;
953 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
954 Process();
955 EXPECT_TRUE(result.done_);
956 std::stringstream ss;
957 ss << result.host_;
958 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
959}
960
961TEST_P(MockChannelTest, HostAliasMissing) {
962 DNSPacket yesfirst;
963 yesfirst.set_response().set_aa()
964 .add_question(new DNSQuestion("www.first.com", ns_t_a))
965 .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
966 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
967 .WillByDefault(SetReply(&server_, &yesfirst));
968
969 TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
970 EnvValue with_env("HOSTALIASES", aliases.filename());
971 HostResult result;
972 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
973 Process();
974 EXPECT_TRUE(result.done_);
975 std::stringstream ss;
976 ss << result.host_;
977 EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
978}
979
980TEST_P(MockChannelTest, HostAliasMissingFile) {
981 DNSPacket yesfirst;
982 yesfirst.set_response().set_aa()
983 .add_question(new DNSQuestion("www.first.com", ns_t_a))
984 .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
985 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
986 .WillByDefault(SetReply(&server_, &yesfirst));
987
988 EnvValue with_env("HOSTALIASES", "bogus.mcfile");
989 HostResult result;
990 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
991 Process();
992 EXPECT_TRUE(result.done_);
993 std::stringstream ss;
994 ss << result.host_;
995 EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
996}
997
998TEST_P(MockChannelTest, HostAliasUnreadable) {
999 TempFile aliases("www www.google.com\n");
1000 chmod(aliases.filename(), 0);
1001 EnvValue with_env("HOSTALIASES", aliases.filename());
1002
1003 HostResult result;
1004 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1005 EXPECT_TRUE(result.done_);
1006 EXPECT_EQ(ARES_EFILE, result.status_);
1007 chmod(aliases.filename(), 0777);
1008}
1009#endif
1010
1011class MockMultiServerChannelTest
1012 : public MockChannelOptsTest,
1013 public ::testing::WithParamInterface< std::pair<int, bool> > {
1014 public:
1015 MockMultiServerChannelTest(bool rotate)
1016 : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : 0) {}
1017 void CheckExample() {
1018 HostResult result;
1019 ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
1020 Process();
1021 EXPECT_TRUE(result.done_);
1022 std::stringstream ss;
1023 ss << result.host_;
1024 EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
1025 }
1026};
1027
1028class RotateMultiMockTest : public MockMultiServerChannelTest {
1029 public:
1030 RotateMultiMockTest() : MockMultiServerChannelTest(true) {}
1031};
1032
1033class NoRotateMultiMockTest : public MockMultiServerChannelTest {
1034 public:
1035 NoRotateMultiMockTest() : MockMultiServerChannelTest(false) {}
1036};
1037
1038
1039TEST_P(RotateMultiMockTest, ThirdServer) {
1040 DNSPacket servfailrsp;
1041 servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
1042 .add_question(new DNSQuestion("www.example.com", ns_t_a));
1043 DNSPacket notimplrsp;
1044 notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
1045 .add_question(new DNSQuestion("www.example.com", ns_t_a));
1046 DNSPacket okrsp;
1047 okrsp.set_response().set_aa()
1048 .add_question(new DNSQuestion("www.example.com", ns_t_a))
1049 .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
1050
1051 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1052 .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1053 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1054 .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1055 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1056 .WillOnce(SetReply(servers_[2].get(), &okrsp));
1057 CheckExample();
1058
1059 // Second time around, starts from server [1].
1060 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1061 .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
1062 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1063 .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
1064 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1065 .WillOnce(SetReply(servers_[0].get(), &okrsp));
1066 CheckExample();
1067
1068 // Third time around, starts from server [2].
1069 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1070 .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
1071 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1072 .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
1073 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1074 .WillOnce(SetReply(servers_[1].get(), &okrsp));
1075 CheckExample();
1076}
1077
1078TEST_P(NoRotateMultiMockTest, ThirdServer) {
1079 DNSPacket servfailrsp;
1080 servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
1081 .add_question(new DNSQuestion("www.example.com", ns_t_a));
1082 DNSPacket notimplrsp;
1083 notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
1084 .add_question(new DNSQuestion("www.example.com", ns_t_a));
1085 DNSPacket okrsp;
1086 okrsp.set_response().set_aa()
1087 .add_question(new DNSQuestion("www.example.com", ns_t_a))
1088 .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
1089
1090 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1091 .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1092 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1093 .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1094 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1095 .WillOnce(SetReply(servers_[2].get(), &okrsp));
1096 CheckExample();
1097
1098 // Second time around, still starts from server [0].
1099 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1100 .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1101 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1102 .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1103 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1104 .WillOnce(SetReply(servers_[2].get(), &okrsp));
1105 CheckExample();
1106
1107 // Third time around, still starts from server [0].
1108 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1109 .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1110 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1111 .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1112 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1113 .WillOnce(SetReply(servers_[2].get(), &okrsp));
1114 CheckExample();
1115}
1116
1117
1118INSTANTIATE_TEST_CASE_P(AddressFamilies, MockChannelTest,
1119 ::testing::Values(std::make_pair<int, bool>(AF_INET, false),
1120 std::make_pair<int, bool>(AF_INET, true),
1121 std::make_pair<int, bool>(AF_INET6, false),
1122 std::make_pair<int, bool>(AF_INET6, true)));
1123
1124INSTANTIATE_TEST_CASE_P(AddressFamilies, MockUDPChannelTest,
1125 ::testing::Values(AF_INET, AF_INET6));
1126
1127INSTANTIATE_TEST_CASE_P(AddressFamilies, MockTCPChannelTest,
1128 ::testing::Values(AF_INET, AF_INET6));
1129
1130INSTANTIATE_TEST_CASE_P(AddressFamilies, MockExtraOptsTest,
1131 ::testing::Values(std::make_pair<int, bool>(AF_INET, false),
1132 std::make_pair<int, bool>(AF_INET, true),
1133 std::make_pair<int, bool>(AF_INET6, false),
1134 std::make_pair<int, bool>(AF_INET6, true)));
1135
1136INSTANTIATE_TEST_CASE_P(AddressFamilies, MockNoCheckRespChannelTest,
1137 ::testing::Values(std::make_pair<int, bool>(AF_INET, false),
1138 std::make_pair<int, bool>(AF_INET, true),
1139 std::make_pair<int, bool>(AF_INET6, false),
1140 std::make_pair<int, bool>(AF_INET6, true)));
1141
1142INSTANTIATE_TEST_CASE_P(AddressFamilies, MockEDNSChannelTest,
1143 ::testing::Values(std::make_pair<int, bool>(AF_INET, false),
1144 std::make_pair<int, bool>(AF_INET, true),
1145 std::make_pair<int, bool>(AF_INET6, false),
1146 std::make_pair<int, bool>(AF_INET6, true)));
1147
1148INSTANTIATE_TEST_CASE_P(TransportModes, RotateMultiMockTest,
1149 ::testing::Values(std::make_pair<int, bool>(AF_INET, false),
1150 std::make_pair<int, bool>(AF_INET, true),
1151 std::make_pair<int, bool>(AF_INET6, false),
1152 std::make_pair<int, bool>(AF_INET6, true)));
1153
1154INSTANTIATE_TEST_CASE_P(TransportModes, NoRotateMultiMockTest,
1155 ::testing::Values(std::make_pair<int, bool>(AF_INET, false),
1156 std::make_pair<int, bool>(AF_INET, true),
1157 std::make_pair<int, bool>(AF_INET6, false),
1158 std::make_pair<int, bool>(AF_INET6, true)));
1159
1160} // namespace test
1161} // namespace ares