1 #include "ares-test.h"
2 #include "dns-proto.h"
3
4 #include <sstream>
5 #include <vector>
6
7 using testing::InvokeWithoutArgs;
8 using testing::DoAll;
9
10 namespace ares {
11 namespace test {
12
TEST_P(MockChannelTest,Basic)13 TEST_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
TEST_P(MockUDPChannelTest,GetHostByNameParallelLookups)54 TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) {
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
TEST_P(MockUDPChannelTest,TruncationRetry)90 TEST_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
110 static int sock_cb_count = 0;
SocketConnectCallback(ares_socket_t fd,int type,void * data)111 static 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
TEST_P(MockChannelTest,SockCallback)118 TEST_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
TEST_P(MockChannelTest,SockFailCallback)141 TEST_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
155 static int sock_config_cb_count = 0;
SocketConfigureCallback(ares_socket_t fd,int type,void * data)156 static 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
TEST_P(MockChannelTest,SockConfigureCallback)163 TEST_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
TEST_P(MockChannelTest,SockConfigureFailCallback)186 TEST_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
TEST_P(MockTCPChannelTest,MalformedResponse)201 TEST_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
TEST_P(MockTCPChannelTest,FormErrResponse)213 TEST_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
TEST_P(MockTCPChannelTest,ServFailResponse)227 TEST_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
TEST_P(MockTCPChannelTest,NotImplResponse)242 TEST_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
TEST_P(MockTCPChannelTest,RefusedResponse)257 TEST_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
TEST_P(MockTCPChannelTest,YXDomainResponse)272 TEST_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
286 class MockExtraOptsTest
287 : public MockChannelOptsTest,
288 public ::testing::WithParamInterface< std::pair<int, bool> > {
289 public:
MockExtraOptsTest()290 MockExtraOptsTest()
291 : MockChannelOptsTest(1, GetParam().first, GetParam().second,
292 FillOptions(&opts_),
293 ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
FillOptions(struct ares_options * opts)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
TEST_P(MockExtraOptsTest,SimpleQuery)305 TEST_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
328 class MockFlagsChannelOptsTest
329 : public MockChannelOptsTest,
330 public ::testing::WithParamInterface< std::pair<int, bool> > {
331 public:
MockFlagsChannelOptsTest(int flags)332 MockFlagsChannelOptsTest(int flags)
333 : MockChannelOptsTest(1, GetParam().first, GetParam().second,
334 FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
FillOptions(struct ares_options * opts,int 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
344 class MockNoCheckRespChannelTest : public MockFlagsChannelOptsTest {
345 public:
MockNoCheckRespChannelTest()346 MockNoCheckRespChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_NOCHECKRESP) {}
347 };
348
TEST_P(MockNoCheckRespChannelTest,ServFailResponse)349 TEST_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
TEST_P(MockNoCheckRespChannelTest,NotImplResponse)363 TEST_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
TEST_P(MockNoCheckRespChannelTest,RefusedResponse)377 TEST_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
391 class MockEDNSChannelTest : public MockFlagsChannelOptsTest {
392 public:
MockEDNSChannelTest()393 MockEDNSChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_EDNS) {}
394 };
395
TEST_P(MockEDNSChannelTest,RetryWithoutEDNS)396 TEST_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
TEST_P(MockChannelTest,SearchDomains)416 TEST_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
TEST_P(MockUDPChannelTest,SearchDomainsWithResentReply)444 TEST_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
TEST_P(MockChannelTest,SearchDomainsBare)475 TEST_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_, ¬hird));
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
TEST_P(MockChannelTest,SearchNoDataThenSuccess)507 TEST_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
TEST_P(MockChannelTest,SearchNoDataThenNoDataBare)535 TEST_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_, ¬hird));
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
TEST_P(MockChannelTest,SearchNoDataThenFail)565 TEST_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_, ¬hird));
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
TEST_P(MockChannelTest,SearchAllocFailure)595 TEST_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
TEST_P(MockChannelTest,SearchHighNdots)604 TEST_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
TEST_P(MockChannelTest,UnspecifiedFamilyV6)629 TEST_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
TEST_P(MockChannelTest,UnspecifiedFamilyV4)649 TEST_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
TEST_P(MockChannelTest,UnspecifiedFamilyNoData)671 TEST_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
TEST_P(MockChannelTest,UnspecifiedFamilyCname6A4)693 TEST_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
TEST_P(MockChannelTest,ExplicitIP)716 TEST_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
TEST_P(MockChannelTest,ExplicitIPAllocFail)726 TEST_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
TEST_P(MockChannelTest,SortListV4)734 TEST_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
TEST_P(MockChannelTest,SortListV6)772 TEST_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
TEST_P(MockUDPChannelTest,SearchDomainsAllocFail)810 TEST_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
TEST_P(MockUDPChannelTest,Resend)855 TEST_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
TEST_P(MockChannelTest,CancelImmediate)877 TEST_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
TEST_P(MockChannelTest,CancelImmediateGetHostByAddr)886 TEST_P(MockChannelTest, CancelImmediateGetHostByAddr) {
887 HostResult result;
888 struct in_addr addr;
889 addr.s_addr = htonl(0x08080808);
890
891 ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
892 ares_cancel(channel_);
893 EXPECT_TRUE(result.done_);
894 EXPECT_EQ(ARES_ECANCELLED, result.status_);
895 EXPECT_EQ(0, result.timeouts_);
896 }
897
898 // Relies on retries so is UDP-only
TEST_P(MockUDPChannelTest,CancelLater)899 TEST_P(MockUDPChannelTest, CancelLater) {
900 std::vector<byte> nothing;
901
902 // On second request, cancel the channel.
903 EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
904 .WillOnce(SetReplyData(&server_, nothing))
905 .WillOnce(CancelChannel(&server_, channel_));
906
907 HostResult result;
908 ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
909 Process();
910 EXPECT_TRUE(result.done_);
911 EXPECT_EQ(ARES_ECANCELLED, result.status_);
912 EXPECT_EQ(0, result.timeouts_);
913 }
914
TEST_P(MockChannelTest,GetHostByNameDestroyAbsolute)915 TEST_P(MockChannelTest, GetHostByNameDestroyAbsolute) {
916 HostResult result;
917 ares_gethostbyname(channel_, "www.google.com.", 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
TEST_P(MockChannelTest,GetHostByNameDestroyRelative)927 TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
928 HostResult result;
929 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
930
931 ares_destroy(channel_);
932 channel_ = nullptr;
933
934 EXPECT_TRUE(result.done_); // Synchronous
935 EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
936 EXPECT_EQ(0, result.timeouts_);
937 }
938
TEST_P(MockChannelTest,GetHostByNameCNAMENoData)939 TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
940 DNSPacket response;
941 response.set_response().set_aa()
942 .add_question(new DNSQuestion("cname.first.com", ns_t_a))
943 .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com"));
944 ON_CALL(server_, OnRequest("cname.first.com", ns_t_a))
945 .WillByDefault(SetReply(&server_, &response));
946
947 HostResult result;
948 ares_gethostbyname(channel_, "cname.first.com", AF_INET, HostCallback, &result);
949 Process();
950 EXPECT_TRUE(result.done_);
951 EXPECT_EQ(ARES_ENODATA, result.status_);
952 }
953
TEST_P(MockChannelTest,GetHostByAddrDestroy)954 TEST_P(MockChannelTest, GetHostByAddrDestroy) {
955 unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
956 HostResult result;
957 ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
958
959 ares_destroy(channel_);
960 channel_ = nullptr;
961
962 EXPECT_TRUE(result.done_); // Synchronous
963 EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
964 EXPECT_EQ(0, result.timeouts_);
965 }
966
967 #ifndef WIN32
TEST_P(MockChannelTest,HostAlias)968 TEST_P(MockChannelTest, HostAlias) {
969 DNSPacket reply;
970 reply.set_response().set_aa()
971 .add_question(new DNSQuestion("www.google.com", ns_t_a))
972 .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
973 ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
974 .WillByDefault(SetReply(&server_, &reply));
975
976 TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
977 EnvValue with_env("HOSTALIASES", aliases.filename());
978
979 HostResult result;
980 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
981 Process();
982 EXPECT_TRUE(result.done_);
983 std::stringstream ss;
984 ss << result.host_;
985 EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
986 }
987
TEST_P(MockChannelTest,HostAliasMissing)988 TEST_P(MockChannelTest, HostAliasMissing) {
989 DNSPacket yesfirst;
990 yesfirst.set_response().set_aa()
991 .add_question(new DNSQuestion("www.first.com", ns_t_a))
992 .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
993 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
994 .WillByDefault(SetReply(&server_, &yesfirst));
995
996 TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
997 EnvValue with_env("HOSTALIASES", aliases.filename());
998 HostResult result;
999 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1000 Process();
1001 EXPECT_TRUE(result.done_);
1002 std::stringstream ss;
1003 ss << result.host_;
1004 EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
1005 }
1006
TEST_P(MockChannelTest,HostAliasMissingFile)1007 TEST_P(MockChannelTest, HostAliasMissingFile) {
1008 DNSPacket yesfirst;
1009 yesfirst.set_response().set_aa()
1010 .add_question(new DNSQuestion("www.first.com", ns_t_a))
1011 .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
1012 ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
1013 .WillByDefault(SetReply(&server_, &yesfirst));
1014
1015 EnvValue with_env("HOSTALIASES", "bogus.mcfile");
1016 HostResult result;
1017 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1018 Process();
1019 EXPECT_TRUE(result.done_);
1020 std::stringstream ss;
1021 ss << result.host_;
1022 EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
1023 }
1024
TEST_P(MockChannelTest,HostAliasUnreadable)1025 TEST_P(MockChannelTest, HostAliasUnreadable) {
1026 TempFile aliases("www www.google.com\n");
1027 chmod(aliases.filename(), 0);
1028 EnvValue with_env("HOSTALIASES", aliases.filename());
1029
1030 HostResult result;
1031 ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1032 EXPECT_TRUE(result.done_);
1033 EXPECT_EQ(ARES_EFILE, result.status_);
1034 chmod(aliases.filename(), 0777);
1035 }
1036 #endif
1037
1038 class MockMultiServerChannelTest
1039 : public MockChannelOptsTest,
1040 public ::testing::WithParamInterface< std::pair<int, bool> > {
1041 public:
MockMultiServerChannelTest(bool rotate)1042 MockMultiServerChannelTest(bool rotate)
1043 : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
CheckExample()1044 void CheckExample() {
1045 HostResult result;
1046 ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
1047 Process();
1048 EXPECT_TRUE(result.done_);
1049 std::stringstream ss;
1050 ss << result.host_;
1051 EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
1052 }
1053 };
1054
1055 class RotateMultiMockTest : public MockMultiServerChannelTest {
1056 public:
RotateMultiMockTest()1057 RotateMultiMockTest() : MockMultiServerChannelTest(true) {}
1058 };
1059
1060 class NoRotateMultiMockTest : public MockMultiServerChannelTest {
1061 public:
NoRotateMultiMockTest()1062 NoRotateMultiMockTest() : MockMultiServerChannelTest(false) {}
1063 };
1064
1065
TEST_P(RotateMultiMockTest,ThirdServer)1066 TEST_P(RotateMultiMockTest, ThirdServer) {
1067 struct ares_options opts = {0};
1068 int optmask = 0;
1069 EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
1070 EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE));
1071 ares_destroy_options(&opts);
1072
1073 DNSPacket servfailrsp;
1074 servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
1075 .add_question(new DNSQuestion("www.example.com", ns_t_a));
1076 DNSPacket notimplrsp;
1077 notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
1078 .add_question(new DNSQuestion("www.example.com", ns_t_a));
1079 DNSPacket okrsp;
1080 okrsp.set_response().set_aa()
1081 .add_question(new DNSQuestion("www.example.com", ns_t_a))
1082 .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
1083
1084 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1085 .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1086 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1087 .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
1088 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1089 .WillOnce(SetReply(servers_[2].get(), &okrsp));
1090 CheckExample();
1091
1092 // Second time around, starts from server [1].
1093 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1094 .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
1095 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1096 .WillOnce(SetReply(servers_[2].get(), ¬implrsp));
1097 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1098 .WillOnce(SetReply(servers_[0].get(), &okrsp));
1099 CheckExample();
1100
1101 // Third time around, starts from server [2].
1102 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1103 .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
1104 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1105 .WillOnce(SetReply(servers_[0].get(), ¬implrsp));
1106 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1107 .WillOnce(SetReply(servers_[1].get(), &okrsp));
1108 CheckExample();
1109 }
1110
TEST_P(NoRotateMultiMockTest,ThirdServer)1111 TEST_P(NoRotateMultiMockTest, ThirdServer) {
1112 struct ares_options opts = {0};
1113 int optmask = 0;
1114 EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
1115 EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
1116 ares_destroy_options(&opts);
1117
1118 DNSPacket servfailrsp;
1119 servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
1120 .add_question(new DNSQuestion("www.example.com", ns_t_a));
1121 DNSPacket notimplrsp;
1122 notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
1123 .add_question(new DNSQuestion("www.example.com", ns_t_a));
1124 DNSPacket okrsp;
1125 okrsp.set_response().set_aa()
1126 .add_question(new DNSQuestion("www.example.com", ns_t_a))
1127 .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
1128
1129 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1130 .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1131 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1132 .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
1133 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1134 .WillOnce(SetReply(servers_[2].get(), &okrsp));
1135 CheckExample();
1136
1137 // Second time around, still starts from server [0].
1138 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1139 .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1140 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1141 .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
1142 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1143 .WillOnce(SetReply(servers_[2].get(), &okrsp));
1144 CheckExample();
1145
1146 // Third time around, still starts from server [0].
1147 EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1148 .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1149 EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1150 .WillOnce(SetReply(servers_[1].get(), ¬implrsp));
1151 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1152 .WillOnce(SetReply(servers_[2].get(), &okrsp));
1153 CheckExample();
1154 }
1155
1156 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockChannelTest, ::testing::ValuesIn(ares::test::families_modes));
1157
1158 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families));
1159
1160 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockTCPChannelTest, ::testing::ValuesIn(ares::test::families));
1161
1162 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockExtraOptsTest, ::testing::ValuesIn(ares::test::families_modes));
1163
1164 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockNoCheckRespChannelTest, ::testing::ValuesIn(ares::test::families_modes));
1165
1166 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockEDNSChannelTest, ::testing::ValuesIn(ares::test::families_modes));
1167
1168 INSTANTIATE_TEST_CASE_P(TransportModes, RotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
1169
1170 INSTANTIATE_TEST_CASE_P(TransportModes, NoRotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
1171
1172 } // namespace test
1173 } // namespace ares
1174