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