• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

c-ares / c-ares / 12675075779

08 Jan 2025 04:43PM UTC coverage: 91.497% (-0.03%) from 91.526%
12675075779

push

github

web-flow
CI: GitHub actions ubuntu-latest now points to 24.04 causing some minor issues (#957)

Containerized tests now need to be run with sudo to gain access to
chroot(). Also, `gcov` in ubuntu 24.04 is broken with googletest so
revert back to 22.04 for coverage.

Finally, codespell is updated in 24.04 to detect more issues and there
were some typos that needed to be fixed.

Signed-off-by: Brad House (@bradh352)

22404 of 24486 relevant lines covered (91.5%)

11927.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.93
/test/ares-test-mock.cc
1
/* MIT License
2
 *
3
 * Copyright (c) The c-ares project and its contributors
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a copy
6
 * of this software and associated documentation files (the "Software"), to deal
7
 * in the Software without restriction, including without limitation the rights
8
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the Software is
10
 * furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the next
13
 * paragraph) shall be included in all copies or substantial portions of the
14
 * Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 * SOFTWARE.
23
 *
24
 * SPDX-License-Identifier: MIT
25
 */
26
#include "ares-test.h"
27
#include "dns-proto.h"
28

29
#ifndef WIN32
30
#include <sys/types.h>
31
#include <sys/stat.h>
32
#endif
33

34
#include <sstream>
35
#include <vector>
36

37
using testing::InvokeWithoutArgs;
38
using testing::DoAll;
39

40
namespace ares {
41
namespace test {
42

43
class NoDNS0x20MockTest
44
    : public MockChannelOptsTest,
45
      public ::testing::WithParamInterface<int> {
46
 public:
47
  NoDNS0x20MockTest()
2✔
48
    : MockChannelOptsTest(1, GetParam(), false, false,
2✔
49
                          FillOptions(&opts_),
50
                          ARES_OPT_FLAGS) {}
4✔
51
  static struct ares_options* FillOptions(struct ares_options * opts) {
2✔
52
    memset(opts, 0, sizeof(struct ares_options));
2✔
53
    opts->flags = ARES_FLAG_EDNS;
2✔
54
    return opts;
2✔
55
  }
56
 private:
57
  struct ares_options opts_;
58
};
59

60

61
TEST_P(NoDNS0x20MockTest, Basic) {
2✔
62
  std::vector<byte> reply = {
63
    0x00, 0x00,  // qid
64
    0x84, // response + query + AA + not-TC + not-RD
65
    0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
66
    0x00, 0x01,  // 1 question
67
    0x00, 0x01,  // 1 answer RRs
68
    0x00, 0x00,  // 0 authority RRs
69
    0x00, 0x00,  // 0 additional RRs
70
    // Question
71
    0x03, 'w', 'w', 'w',
72
    0x06, 'g', 'o', 'o', 'g', 'l', 'e',
73
    0x03, 'c', 'o', 'm',
74
    0x00,
75
    0x00, 0x01,  // type A
76
    0x00, 0x01,  // class IN
77
    // Answer
78
    0x03, 'w', 'w', 'w',
79
    0x06, 'g', 'o', 'o', 'g', 'l', 'e',
80
    0x03, 'c', 'o', 'm',
81
    0x00,
82
    0x00, 0x01,  // type A
83
    0x00, 0x01,  // class IN
84
    0x00, 0x00, 0x01, 0x00,  // TTL
85
    0x00, 0x04,  // rdata length
86
    0x01, 0x02, 0x03, 0x04
87
  };
2✔
88

89
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
90
    .WillByDefault(SetReplyData(&server_, reply));
2✔
91

92
  HostResult result;
2✔
93
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
94
  Process();
2✔
95
  EXPECT_TRUE(result.done_);
2✔
96
  std::stringstream ss;
4✔
97
  ss << result.host_;
2✔
98
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
4✔
99
}
2✔
100

101
TEST_P(MockUDPChannelTest, DNS0x20BadReply) {
2✔
102
  std::vector<byte> reply = {
103
    0x00, 0x00,  // qid
104
    0x84, // response + query + AA + not-TC + not-RD
105
    0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
106
    0x00, 0x01,  // 1 question
107
    0x00, 0x01,  // 1 answer RRs
108
    0x00, 0x00,  // 0 authority RRs
109
    0x00, 0x00,  // 0 additional RRs
110
    // Question
111
    0x03, 'w', 'w', 'w',
112
    0x1D, 's', 'o', 'm', 'e', 'l', 'o', 'n', 'g', 'd', 'o', 'm', 'a', 'i', 'n', 'n', 'a', 'm', 'e', 'b', 'e', 'c', 'a', 'u', 's', 'e', 'p', 'r', 'n', 'g',
113
    0x03, 'c', 'o', 'm',
114
    0x00,
115
    0x00, 0x01,  // type A
116
    0x00, 0x01,  // class IN
117
    // Answer
118
    0x03, 'w', 'w', 'w',
119
    0x1D, 's', 'o', 'm', 'e', 'l', 'o', 'n', 'g', 'd', 'o', 'm', 'a', 'i', 'n', 'n', 'a', 'm', 'e', 'b', 'e', 'c', 'a', 'u', 's', 'e', 'p', 'r', 'n', 'g',
120
    0x03, 'c', 'o', 'm',
121
    0x00,
122
    0x00, 0x01,  // type A
123
    0x00, 0x01,  // class IN
124
    0x00, 0x00, 0x01, 0x00,  // TTL
125
    0x00, 0x04,  // rdata length
126
    0x01, 0x02, 0x03, 0x04
127
  };
2✔
128

129
  ON_CALL(server_, OnRequest("www.somelongdomainnamebecauseprng.com", T_A))
4✔
130
    .WillByDefault(SetReplyData(&server_, reply));
2✔
131

132
  /* Reply will be thrown out due to mismatched case for DNS 0x20 in response,
133
   * its technically possible this test case may not fail if somehow the
134
   * PRNG returns all lowercase domain name so we need to make this domain
135
   * fairly long to make sure those odds are very very very low */
136
  HostResult result;
2✔
137
  ares_gethostbyname(channel_, "www.somelongdomainnamebecauseprng.com.", AF_INET, HostCallback, &result);
2✔
138
  Process();
2✔
139
  EXPECT_TRUE(result.done_);
2✔
140
  EXPECT_EQ(ARES_ETIMEOUT, result.status_);
2✔
141
}
2✔
142

143
// UDP only so mock server doesn't get confused by concatenated requests
144
TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) {
2✔
145
  DNSPacket rsp1;
2✔
146
  rsp1.set_response().set_aa()
2✔
147
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
148
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
2✔
149
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
150
    .WillByDefault(SetReply(&server_, &rsp1));
2✔
151
  DNSPacket rsp2;
2✔
152
  rsp2.set_response().set_aa()
2✔
153
    .add_question(new DNSQuestion("www.example.com", T_A))
4✔
154
    .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
2✔
155
  ON_CALL(server_, OnRequest("www.example.com", T_A))
4✔
156
    .WillByDefault(SetReply(&server_, &rsp2));
2✔
157

158
  HostResult result1;
2✔
159
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
2✔
160
  HostResult result2;
2✔
161
  ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result2);
2✔
162
  HostResult result3;
2✔
163
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result3);
2✔
164
  Process();
2✔
165
  EXPECT_TRUE(result1.done_);
2✔
166
  EXPECT_TRUE(result2.done_);
2✔
167
  EXPECT_TRUE(result3.done_);
2✔
168
  std::stringstream ss1;
4✔
169
  ss1 << result1.host_;
2✔
170
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
4✔
171
  std::stringstream ss2;
4✔
172
  ss2 << result2.host_;
2✔
173
  EXPECT_EQ("{'www.example.com' aliases=[] addrs=[1.2.3.4]}", ss2.str());
4✔
174
  std::stringstream ss3;
4✔
175
  ss3 << result3.host_;
2✔
176
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
4✔
177
}
2✔
178

179
// UDP to TCP specific test
180
TEST_P(MockUDPChannelTest, TruncationRetry) {
2✔
181
  DNSPacket rsptruncated;
2✔
182
  rsptruncated.set_response().set_aa().set_tc()
2✔
183
    .add_question(new DNSQuestion("www.google.com", T_A));
2✔
184
  DNSPacket rspok;
2✔
185
  rspok.set_response()
2✔
186
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
187
    .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
2✔
188
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
189
    .WillOnce(SetReply(&server_, &rsptruncated))
4✔
190
    .WillOnce(SetReply(&server_, &rspok));
2✔
191
  HostResult result;
2✔
192
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
193
  Process();
2✔
194
  EXPECT_TRUE(result.done_);
2✔
195
  std::stringstream ss;
4✔
196
  ss << result.host_;
2✔
197
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
4✔
198
}
2✔
199

200
TEST_P(MockUDPChannelTest, UTF8BadName) {
2✔
201
  DNSPacket reply;
2✔
202
  reply.set_response().set_aa()
2✔
203
    .add_question(new DNSQuestion("españa.icom.museum", T_A))
4✔
204
    .add_answer(new DNSARR("españa.icom.museum", 100, {2, 3, 4, 5}));
2✔
205
  ON_CALL(server_, OnRequest("españa.icom.museum", T_A))
4✔
206
    .WillByDefault(SetReply(&server_, &reply));
2✔
207

208
  HostResult result;
2✔
209
  ares_gethostbyname(channel_, "españa.icom.museum", AF_INET, HostCallback, &result);
2✔
210
  Process();
2✔
211
  EXPECT_TRUE(result.done_);
2✔
212
  EXPECT_EQ(ARES_EBADNAME, result.status_);
2✔
213
}
2✔
214

215
static int sock_cb_count = 0;
216
static int SocketConnectCallback(ares_socket_t fd, int type, void *data) {
28✔
217
  int rc = *(int*)data;
28✔
218
  (void)type;
219
  if (verbose) std::cerr << "SocketConnectCallback(" << fd << ") invoked" << std::endl;
28✔
220
  sock_cb_count++;
28✔
221
  return rc;
28✔
222
}
223

224
TEST_P(MockChannelTest, SockCallback) {
4✔
225
  DNSPacket rsp;
4✔
226
  rsp.set_response().set_aa()
4✔
227
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
228
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
4✔
229
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
8✔
230
    .WillOnce(SetReply(&server_, &rsp));
4✔
231

232
  // Get notified of new sockets
233
  int rc = ARES_SUCCESS;
4✔
234
  ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
4✔
235

236
  HostResult result;
4✔
237
  sock_cb_count = 0;
4✔
238
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
239
  Process();
4✔
240
  EXPECT_EQ(1, sock_cb_count);
4✔
241
  EXPECT_TRUE(result.done_);
4✔
242
  std::stringstream ss;
8✔
243
  ss << result.host_;
4✔
244
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
245
}
4✔
246

247
TEST_P(MockChannelTest, SockFailCallback) {
4✔
248
  // Notification of new sockets gives an error.
249
  int rc = -1;
4✔
250
  ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
4✔
251

252
  HostResult result;
4✔
253
  sock_cb_count = 0;
4✔
254
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
255
  Process();
4✔
256
  EXPECT_LT(1, sock_cb_count);
4✔
257
  EXPECT_TRUE(result.done_);
4✔
258
  EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
4✔
259
}
4✔
260

261
static int sock_config_cb_count = 0;
262
static int SocketConfigureCallback(ares_socket_t fd, int type, void *data) {
16✔
263
  int rc = *(int*)data;
16✔
264
  (void)type;
265
  if (verbose) std::cerr << "SocketConfigureCallback(" << fd << ") invoked" << std::endl;
16✔
266
  sock_config_cb_count++;
16✔
267
  return rc;
16✔
268
}
269

270
TEST_P(MockChannelTest, SockConfigureCallback) {
4✔
271
  DNSPacket rsp;
4✔
272
  rsp.set_response().set_aa()
4✔
273
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
274
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
4✔
275
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
8✔
276
    .WillOnce(SetReply(&server_, &rsp));
4✔
277

278
  // Get notified of new sockets
279
  int rc = ARES_SUCCESS;
4✔
280
  ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
4✔
281

282
  HostResult result;
4✔
283
  sock_config_cb_count = 0;
4✔
284
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
285
  Process();
4✔
286
  EXPECT_EQ(1, sock_config_cb_count);
4✔
287
  EXPECT_TRUE(result.done_);
4✔
288
  std::stringstream ss;
8✔
289
  ss << result.host_;
4✔
290
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
291
}
4✔
292

293
TEST_P(MockChannelTest, SockConfigureFailCallback) {
4✔
294
  // Notification of new sockets gives an error.
295
  int rc = -1;
4✔
296
  ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
4✔
297

298
  HostResult result;
4✔
299
  sock_config_cb_count = 0;
4✔
300
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
301
  Process();
4✔
302
  EXPECT_LT(1, sock_config_cb_count);
4✔
303
  EXPECT_TRUE(result.done_);
4✔
304
  EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
4✔
305
}
4✔
306

307
// Define a server state callback for testing. The custom userdata should be
308
// the expected server string that the callback is invoked with.
309
static int server_state_cb_success_count = 0;
310
static int server_state_cb_failure_count = 0;
311
static void ServerStateCallback(const char *server_string,
24✔
312
                                ares_bool_t success, int flags, void *data) {
313
  // Increment overall success/failure counts appropriately.
314
  if (verbose) std::cerr << "ServerStateCallback("
24✔
315
                         << server_string << ", "
24✔
316
                         << success       << ", "
24✔
317
                         << flags         << ") invoked" << std::endl;
24✔
318
  if (success == ARES_TRUE) server_state_cb_success_count++;
24✔
319
  else server_state_cb_failure_count++;
16✔
320

321
  // Check that the server string is as expected.
322
  char *exp_server_string = *(char **)(data);
24✔
323
  EXPECT_STREQ(exp_server_string, server_string);
24✔
324

325
  // The callback should be invoked with either the UDP flag or the TCP flag,
326
  // but not both.
327
  ares_bool_t udp = (flags & ARES_SERV_STATE_UDP) ? ARES_TRUE: ARES_FALSE;
24✔
328
  ares_bool_t tcp = (flags & ARES_SERV_STATE_TCP) ? ARES_TRUE: ARES_FALSE;
24✔
329
  EXPECT_NE(udp, tcp);
24✔
330
}
24✔
331

332
TEST_P(MockChannelTest, ServStateCallbackSuccess) {
4✔
333
  // Set up the server response. The server returns successfully with an answer
334
  // to the query.
335
  DNSPacket rsp;
4✔
336
  rsp.set_response().set_aa()
4✔
337
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
338
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
4✔
339
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
8✔
340
    .WillOnce(SetReply(&server_, &rsp));
4✔
341

342
  // Set up the server state callback. The channel used for this test has a
343
  // single server configured.
344
  char *exp_server_string = ares_get_servers_csv(channel_);
4✔
345
  ares_set_server_state_callback(channel_, ServerStateCallback,
4✔
346
                                 &exp_server_string);
347

348
  // Perform the hostname lookup. Expect 1 successful query to the server.
349
  HostResult result;
4✔
350
  server_state_cb_success_count = 0;
4✔
351
  server_state_cb_failure_count = 0;
4✔
352
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback,
4✔
353
                     &result);
354
  Process();
4✔
355
  EXPECT_EQ(1, server_state_cb_success_count);
4✔
356
  EXPECT_EQ(0, server_state_cb_failure_count);
4✔
357
  EXPECT_TRUE(result.done_);
4✔
358
  std::stringstream ss;
8✔
359
  ss << result.host_;
4✔
360
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
361

362
  ares_free_string(exp_server_string);
4✔
363
}
4✔
364

365
TEST_P(MockChannelTest, ServStateCallbackFailure) {
4✔
366
  // Set up the server response. The server always returns SERVFAIL.
367
  DNSPacket rsp;
4✔
368
  rsp.set_response().set_aa()
4✔
369
    .add_question(new DNSQuestion("www.google.com", T_A));
4✔
370
  rsp.set_rcode(SERVFAIL);
4✔
371
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
372
    .WillByDefault(SetReply(&server_, &rsp));
4✔
373

374
  // Set up the server state callback. The channel used for this test has a
375
  // single server configured.
376
  char *exp_server_string = ares_get_servers_csv(channel_);
4✔
377
  ares_set_server_state_callback(channel_, ServerStateCallback,
4✔
378
                                 &exp_server_string);
379

380
  // Perform the hostname lookup. Expect 3 failed queries to the server (due to
381
  // retries).
382
  HostResult result;
4✔
383
  server_state_cb_success_count = 0;
4✔
384
  server_state_cb_failure_count = 0;
4✔
385
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback,
4✔
386
                     &result);
387
  Process();
4✔
388
  EXPECT_EQ(0, server_state_cb_success_count);
4✔
389
  EXPECT_EQ(3, server_state_cb_failure_count);
4✔
390
  EXPECT_TRUE(result.done_);
4✔
391
  EXPECT_EQ(ARES_ESERVFAIL, result.status_);
4✔
392

393
  ares_free_string(exp_server_string);
4✔
394
}
4✔
395

396
TEST_P(MockChannelTest, ServStateCallbackRecover) {
4✔
397
  // Set up the server response. The server initially times out, but then
398
  // returns successfully (with NXDOMAIN) on the first retry.
399
  std::vector<byte> nothing;
4✔
400
  DNSPacket rsp;
4✔
401
  rsp.set_response().set_aa()
4✔
402
    .add_question(new DNSQuestion("www.google.com", T_A));
4✔
403
  rsp.set_rcode(NXDOMAIN);
4✔
404
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
8✔
405
    .WillOnce(SetReplyData(&server_, nothing))
8✔
406
    .WillOnce(SetReply(&server_, &rsp));
4✔
407

408
  // Set up the server state callback. The channel used for this test has a
409
  // single server configured.
410
  char *exp_server_string = ares_get_servers_csv(channel_);
4✔
411
  ares_set_server_state_callback(channel_, ServerStateCallback,
4✔
412
                                 &exp_server_string);
413

414
  // Perform the hostname lookup. Expect 1 failed query and 1 successful query
415
  // to the server.
416
  HostResult result;
4✔
417
  server_state_cb_success_count = 0;
4✔
418
  server_state_cb_failure_count = 0;
4✔
419
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback,
4✔
420
                     &result);
421
  Process();
4✔
422
  EXPECT_EQ(1, server_state_cb_success_count);
4✔
423
  EXPECT_EQ(1, server_state_cb_failure_count);
4✔
424
  EXPECT_TRUE(result.done_);
4✔
425
  EXPECT_EQ(ARES_ENOTFOUND, result.status_);
4✔
426

427
  ares_free_string(exp_server_string);
4✔
428
}
4✔
429

430
TEST_P(MockChannelTest, ReInit) {
4✔
431
  DNSPacket rsp;
4✔
432
  rsp.set_response().set_aa()
4✔
433
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
434
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
4✔
435
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
8✔
436
    .WillOnce(SetReply(&server_, &rsp));
4✔
437

438
  HostResult result;
4✔
439
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
440
  EXPECT_EQ(ARES_SUCCESS, ares_reinit(channel_));
4✔
441
  Process();
4✔
442
  EXPECT_TRUE(result.done_);
4✔
443
  std::stringstream ss;
8✔
444
  ss << result.host_;
4✔
445
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
446
}
4✔
447

448
#define MAXUDPQUERIES_TOTAL 32
449
#define MAXUDPQUERIES_LIMIT 8
450

451
class MockUDPMaxQueriesTest
452
    : public MockChannelOptsTest,
453
      public ::testing::WithParamInterface<int> {
454
 public:
455
  MockUDPMaxQueriesTest()
2✔
456
    : MockChannelOptsTest(1, GetParam(), false, false,
2✔
457
                          FillOptions(&opts_),
458
                          ARES_OPT_UDP_MAX_QUERIES) {}
4✔
459
  static struct ares_options* FillOptions(struct ares_options * opts) {
2✔
460
    memset(opts, 0, sizeof(struct ares_options));
2✔
461
    opts->udp_max_queries = MAXUDPQUERIES_LIMIT;
2✔
462
    return opts;
2✔
463
  }
464
 private:
465
  struct ares_options opts_;
466
};
467

468
TEST_P(MockUDPMaxQueriesTest, GetHostByNameParallelLookups) {
2✔
469
  DNSPacket rsp;
2✔
470
  rsp.set_response().set_aa()
2✔
471
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
472
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
2✔
473
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
474
    .WillByDefault(SetReply(&server_, &rsp));
2✔
475

476
  // Get notified of new sockets so we can validate how many are created
477
  int rc = ARES_SUCCESS;
2✔
478
  ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
2✔
479
  sock_cb_count = 0;
2✔
480

481
  HostResult result[MAXUDPQUERIES_TOTAL];
132✔
482
  for (size_t i=0; i<MAXUDPQUERIES_TOTAL; i++) {
66✔
483
    ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result[i]);
64✔
484
  }
485

486
  Process();
2✔
487

488
  EXPECT_EQ(MAXUDPQUERIES_TOTAL / MAXUDPQUERIES_LIMIT, sock_cb_count);
2✔
489

490
  for (size_t i=0; i<MAXUDPQUERIES_TOTAL; i++) {
66✔
491
    std::stringstream ss;
64✔
492
    EXPECT_TRUE(result[i].done_);
64✔
493
    ss << result[i].host_;
64✔
494
    EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
128✔
495
  }
64✔
496
}
68✔
497

498
class CacheQueriesTest
499
    : public MockChannelOptsTest,
500
      public ::testing::WithParamInterface<int> {
501
 public:
502
  CacheQueriesTest()
6✔
503
    : MockChannelOptsTest(1, GetParam(), false, false,
6✔
504
                          FillOptions(&opts_),
505
                          ARES_OPT_QUERY_CACHE) {}
12✔
506
  static struct ares_options* FillOptions(struct ares_options * opts) {
6✔
507
    memset(opts, 0, sizeof(struct ares_options));
6✔
508
    opts->qcache_max_ttl = 3600;
6✔
509
    return opts;
6✔
510
  }
511
 private:
512
  struct ares_options opts_;
513
};
514

515
TEST_P(CacheQueriesTest, GetHostByNameCache) {
2✔
516
  DNSPacket rsp;
2✔
517
  rsp.set_response().set_aa()
2✔
518
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
519
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
2✔
520
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
521
    .WillByDefault(SetReply(&server_, &rsp));
2✔
522

523
  // Get notified of new sockets so we can validate how many are created
524
  int rc = ARES_SUCCESS;
2✔
525
  ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
2✔
526
  sock_cb_count = 0;
2✔
527

528
  HostResult result1;
2✔
529
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
2✔
530
  Process();
2✔
531

532
  std::stringstream ss1;
2✔
533
  EXPECT_TRUE(result1.done_);
2✔
534
  ss1 << result1.host_;
2✔
535
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
4✔
536

537
  /* Run again, should return cached result */
538
  HostResult result2;
4✔
539
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result2);
2✔
540
  Process();
2✔
541

542
  std::stringstream ss2;
4✔
543
  EXPECT_TRUE(result2.done_);
2✔
544
  ss2 << result2.host_;
2✔
545
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss2.str());
4✔
546

547
  EXPECT_EQ(1, sock_cb_count);
2✔
548
}
2✔
549

550
#define TCPPARALLELLOOKUPS 32
551
TEST_P(MockTCPChannelTest, GetHostByNameParallelLookups) {
2✔
552
  DNSPacket rsp;
2✔
553
  rsp.set_response().set_aa()
2✔
554
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
555
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
2✔
556
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
557
    .WillByDefault(SetReply(&server_, &rsp));
2✔
558

559
  // Get notified of new sockets so we can validate how many are created
560
  int rc = ARES_SUCCESS;
2✔
561
  ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
2✔
562
  sock_cb_count = 0;
2✔
563

564
  HostResult result[TCPPARALLELLOOKUPS];
132✔
565
  for (size_t i=0; i<TCPPARALLELLOOKUPS; i++) {
66✔
566
    ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result[i]);
64✔
567
  }
568

569
  Process();
2✔
570

571
  EXPECT_EQ(1, sock_cb_count);
2✔
572

573
  for (size_t i=0; i<TCPPARALLELLOOKUPS; i++) {
66✔
574
    std::stringstream ss;
64✔
575
    EXPECT_TRUE(result[i].done_);
64✔
576
    ss << result[i].host_;
64✔
577
    EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
128✔
578
  }
64✔
579
}
68✔
580

581
TEST_P(MockTCPChannelTest, MalformedResponse) {
2✔
582
  std::vector<byte> one = {0x00};
2✔
583
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
584
    .WillByDefault(SetReplyData(&server_, one));
2✔
585

586
  HostResult result;
2✔
587
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
588
  Process();
2✔
589
  EXPECT_TRUE(result.done_);
2✔
590
  EXPECT_EQ(ARES_EBADRESP, result.status_);
2✔
591
}
2✔
592

593
TEST_P(MockTCPChannelTest, FormErrResponse) {
2✔
594
  DNSPacket rsp;
2✔
595
  rsp.set_response().set_aa()
2✔
596
    .add_question(new DNSQuestion("www.google.com", T_A));
2✔
597
  rsp.set_rcode(FORMERR);
2✔
598
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
599
    .WillOnce(SetReply(&server_, &rsp));
2✔
600
  HostResult result;
2✔
601
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
602
  Process();
2✔
603
  EXPECT_TRUE(result.done_);
2✔
604
  EXPECT_EQ(ARES_EFORMERR, result.status_);
2✔
605
}
2✔
606

607
TEST_P(MockTCPChannelTest, ServFailResponse) {
2✔
608
  DNSPacket rsp;
2✔
609
  rsp.set_response().set_aa()
2✔
610
    .add_question(new DNSQuestion("www.google.com", T_A));
2✔
611
  rsp.set_rcode(SERVFAIL);
2✔
612
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
613
    .WillByDefault(SetReply(&server_, &rsp));
2✔
614
  HostResult result;
2✔
615
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
616
  Process();
2✔
617
  EXPECT_TRUE(result.done_);
2✔
618
  EXPECT_EQ(ARES_ESERVFAIL, result.status_);
2✔
619
}
2✔
620

621
TEST_P(MockTCPChannelTest, NotImplResponse) {
2✔
622
  DNSPacket rsp;
2✔
623
  rsp.set_response().set_aa()
2✔
624
    .add_question(new DNSQuestion("www.google.com", T_A));
2✔
625
  rsp.set_rcode(NOTIMP);
2✔
626
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
627
    .WillByDefault(SetReply(&server_, &rsp));
2✔
628
  HostResult result;
2✔
629
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
630
  Process();
2✔
631
  EXPECT_TRUE(result.done_);
2✔
632
  EXPECT_EQ(ARES_ENOTIMP, result.status_);
2✔
633
}
2✔
634

635
TEST_P(MockTCPChannelTest, RefusedResponse) {
2✔
636
  DNSPacket rsp;
2✔
637
  rsp.set_response().set_aa()
2✔
638
    .add_question(new DNSQuestion("www.google.com", T_A));
2✔
639
  rsp.set_rcode(REFUSED);
2✔
640
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
641
    .WillByDefault(SetReply(&server_, &rsp));
2✔
642
  HostResult result;
2✔
643
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
644
  Process();
2✔
645
  EXPECT_TRUE(result.done_);
2✔
646
  EXPECT_EQ(ARES_EREFUSED, result.status_);
2✔
647
}
2✔
648

649
TEST_P(MockTCPChannelTest, YXDomainResponse) {
2✔
650
  DNSPacket rsp;
2✔
651
  rsp.set_response().set_aa()
2✔
652
    .add_question(new DNSQuestion("www.google.com", T_A));
2✔
653
  rsp.set_rcode(YXDOMAIN);
2✔
654
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
655
    .WillOnce(SetReply(&server_, &rsp));
2✔
656
  HostResult result;
2✔
657
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
658
  Process();
2✔
659
  EXPECT_TRUE(result.done_);
2✔
660
  EXPECT_EQ(ARES_ENODATA, result.status_);
2✔
661
}
2✔
662

663
class MockExtraOptsTest
664
    : public MockChannelOptsTest,
665
      public ::testing::WithParamInterface< std::pair<int, bool> > {
666
 public:
667
  MockExtraOptsTest()
4✔
668
    : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
4✔
669
                          FillOptions(&opts_),
670
                          ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
8✔
671
  static struct ares_options* FillOptions(struct ares_options * opts) {
4✔
672
    memset(opts, 0, sizeof(struct ares_options));
4✔
673
    // Set a few options that affect socket communications
674
    opts->socket_send_buffer_size = 514;
4✔
675
    opts->socket_receive_buffer_size = 514;
4✔
676
    return opts;
4✔
677
  }
678
 private:
679
  struct ares_options opts_;
680
};
681

682
TEST_P(MockExtraOptsTest, SimpleQuery) {
4✔
683
  ares_set_local_ip4(channel_, 0x7F000001);
4✔
684
  byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4✔
685
                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
686
  ares_set_local_ip6(channel_, addr6);
4✔
687
  ares_set_local_dev(channel_, "dummy");
4✔
688

689
  DNSPacket rsp;
4✔
690
  rsp.set_response().set_aa()
4✔
691
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
692
    .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
4✔
693
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
694
    .WillByDefault(SetReply(&server_, &rsp));
4✔
695

696
  HostResult result;
4✔
697
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
698
  Process();
4✔
699
  EXPECT_TRUE(result.done_);
4✔
700
  std::stringstream ss;
8✔
701
  ss << result.host_;
4✔
702
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
703
}
4✔
704

705
class MockFlagsChannelOptsTest
706
    : public MockChannelOptsTest,
707
      public ::testing::WithParamInterface< std::pair<int, bool> > {
708
 public:
709
  MockFlagsChannelOptsTest(int flags)
16✔
710
    : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
16✔
711
                          FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
32✔
712
  static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
16✔
713
    memset(opts, 0, sizeof(struct ares_options));
16✔
714
    opts->flags = flags;
16✔
715
    return opts;
16✔
716
  }
717
 private:
718
  struct ares_options opts_;
719
};
720

721
class MockNoCheckRespChannelTest : public MockFlagsChannelOptsTest {
722
 public:
723
  MockNoCheckRespChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_NOCHECKRESP) {}
12✔
724
};
725

726
TEST_P(MockNoCheckRespChannelTest, ServFailResponse) {
4✔
727
  DNSPacket rsp;
4✔
728
  rsp.set_response().set_aa()
4✔
729
    .add_question(new DNSQuestion("www.google.com", T_A));
4✔
730
  rsp.set_rcode(SERVFAIL);
4✔
731
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
732
    .WillByDefault(SetReply(&server_, &rsp));
4✔
733
  HostResult result;
4✔
734
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
735
  Process();
4✔
736
  EXPECT_TRUE(result.done_);
4✔
737
  EXPECT_EQ(ARES_ESERVFAIL, result.status_);
4✔
738
}
4✔
739

740
TEST_P(MockNoCheckRespChannelTest, NotImplResponse) {
4✔
741
  DNSPacket rsp;
4✔
742
  rsp.set_response().set_aa()
4✔
743
    .add_question(new DNSQuestion("www.google.com", T_A));
4✔
744
  rsp.set_rcode(NOTIMP);
4✔
745
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
746
    .WillByDefault(SetReply(&server_, &rsp));
4✔
747
  HostResult result;
4✔
748
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
749
  Process();
4✔
750
  EXPECT_TRUE(result.done_);
4✔
751
  EXPECT_EQ(ARES_ENOTIMP, result.status_);
4✔
752
}
4✔
753

754
TEST_P(MockNoCheckRespChannelTest, RefusedResponse) {
4✔
755
  DNSPacket rsp;
4✔
756
  rsp.set_response().set_aa()
4✔
757
    .add_question(new DNSQuestion("www.google.com", T_A));
4✔
758
  rsp.set_rcode(REFUSED);
4✔
759
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
760
    .WillByDefault(SetReply(&server_, &rsp));
4✔
761
  HostResult result;
4✔
762
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
763
  Process();
4✔
764
  EXPECT_TRUE(result.done_);
4✔
765
  EXPECT_EQ(ARES_EREFUSED, result.status_);
4✔
766
}
4✔
767

768
class MockEDNSChannelTest : public MockFlagsChannelOptsTest {
769
 public:
770
  MockEDNSChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_EDNS) {}
4✔
771
};
772

773
TEST_P(MockEDNSChannelTest, RetryWithoutEDNS) {
4✔
774
  DNSPacket rspfail;
4✔
775
  rspfail.set_response().set_aa().set_rcode(FORMERR)
4✔
776
    .add_question(new DNSQuestion("www.google.com", T_A));
4✔
777
  DNSPacket rspok;
4✔
778
  rspok.set_response()
4✔
779
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
780
    .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
4✔
781
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
8✔
782
    .WillOnce(SetReply(&server_, &rspfail))
8✔
783
    .WillOnce(SetReply(&server_, &rspok));
4✔
784
  HostResult result;
4✔
785
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
786
  Process();
4✔
787
  EXPECT_TRUE(result.done_);
4✔
788
  std::stringstream ss;
8✔
789
  ss << result.host_;
4✔
790
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
8✔
791
}
4✔
792

793

794
// Issue #911
795
TEST_P(MockUDPChannelTest, RetryWithoutEDNSNonCompliant) {
2✔
796
  DNSPacket rspfail;
2✔
797
  rspfail.set_response().set_aa().set_rcode(FORMERR)
2✔
798
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
799
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, { }, false));
2✔
800
  DNSPacket rspok;
2✔
801
  rspok.set_response()
2✔
802
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
803
    .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
2✔
804
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
805
    .WillOnce(SetReply(&server_, &rspfail))
4✔
806
    .WillOnce(SetReply(&server_, &rspok));
2✔
807
  HostResult result;
2✔
808
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
809
  Process();
2✔
810
  EXPECT_TRUE(result.done_);
2✔
811
  std::stringstream ss;
4✔
812
  ss << result.host_;
2✔
813
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
4✔
814
}
2✔
815

816
TEST_P(MockChannelTest, SearchDomains) {
4✔
817
  DNSPacket nofirst;
4✔
818
  nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
4✔
819
    .add_question(new DNSQuestion("www.first.com", T_A));
4✔
820
  ON_CALL(server_, OnRequest("www.first.com", T_A))
8✔
821
    .WillByDefault(SetReply(&server_, &nofirst));
4✔
822
  DNSPacket nosecond;
4✔
823
  nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
4✔
824
    .add_question(new DNSQuestion("www.second.org", T_A));
4✔
825
  ON_CALL(server_, OnRequest("www.second.org", T_A))
8✔
826
    .WillByDefault(SetReply(&server_, &nosecond));
4✔
827
  DNSPacket yesthird;
4✔
828
  yesthird.set_response().set_aa()
4✔
829
    .add_question(new DNSQuestion("www.third.gov", T_A))
8✔
830
    .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
4✔
831
  ON_CALL(server_, OnRequest("www.third.gov", T_A))
8✔
832
    .WillByDefault(SetReply(&server_, &yesthird));
4✔
833

834
  HostResult result;
4✔
835
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
836
  Process();
4✔
837
  EXPECT_TRUE(result.done_);
4✔
838
  std::stringstream ss;
8✔
839
  ss << result.host_;
4✔
840
  EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
841
}
4✔
842

843
#ifdef HAVE_CONTAINER
844
// Issue #852
845
class ContainedMockChannelSysConfig
846
    : public MockChannelOptsTest,
847
      public ::testing::WithParamInterface<std::pair<int, bool>> {
848
 public:
849
  ContainedMockChannelSysConfig()
8✔
850
    : MockChannelOptsTest(1, GetParam().first, GetParam().second, true, nullptr, 0) {}
8✔
851
};
852

853
static NameContentList files_no_ndots = {
854
  {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
855
                       "search example.com example.org\n"
856
                       "options edns0 trust-ad\n"}, // ndots:1 is default
857
  {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
858
  {"/etc/nsswitch.conf", "hosts: files dns\n"}};
859
CONTAINED_TEST_P(ContainedMockChannelSysConfig, SysConfigNdotsDefault,
4✔
860
                 "myhostname", "mydomainname.org", files_no_ndots) {
861
  DNSPacket rsp;
4✔
862
  rsp.set_response().set_aa()
4✔
863
    .add_question(new DNSQuestion("www.example.com", T_A))
8✔
864
    .add_answer(new DNSARR("www.example.com", 0x0200, {2, 3, 4, 5}));
4✔
865
  EXPECT_CALL(server_, OnRequest("www.example.com", T_A))
8✔
866
    .WillOnce(SetReply(&server_, &rsp));
4✔
867

868
  HostResult result;
4✔
869
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
870
  Process();
4✔
871
  EXPECT_TRUE(result.done_);
4✔
872
  std::stringstream ss;
4✔
873
  ss << result.host_;
4✔
874
  EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
875
  return HasFailure();
8✔
876
}
4✔
877

878

879
static NameContentList files_ndots0 = {
880
  {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
881
                       "search example.com example.org\n"
882
                       "options edns0 trust-ad ndots:0\n"}, // ndots:1 is default
883
  {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
884
  {"/etc/nsswitch.conf", "hosts: files dns\n"}};
885
CONTAINED_TEST_P(ContainedMockChannelSysConfig, SysConfigNdots0,
4✔
886
                 "myhostname", "mydomainname.org", files_ndots0) {
887
  DNSPacket rsp;
4✔
888
  rsp.set_response().set_aa()
4✔
889
    .add_question(new DNSQuestion("www", T_A))
8✔
890
    .add_answer(new DNSARR("www", 0x0200, {1, 2, 3, 4}));
4✔
891
  EXPECT_CALL(server_, OnRequest("www", T_A))
8✔
892
    .WillOnce(SetReply(&server_, &rsp));
4✔
893

894
  HostResult result;
4✔
895
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
896
  Process();
4✔
897
  EXPECT_TRUE(result.done_);
4✔
898
  std::stringstream ss;
4✔
899
  ss << result.host_;
4✔
900
  EXPECT_EQ("{'www' aliases=[] addrs=[1.2.3.4]}", ss.str());
8✔
901
  return HasFailure();
8✔
902
}
4✔
903
#endif
904

905
// Issue #858
906
TEST_P(CacheQueriesTest, BlankName) {
2✔
907
  DNSPacket rsp;
2✔
908
  rsp.set_response().set_aa()
2✔
909
    .add_question(new DNSQuestion(".", T_SOA))
4✔
910
    .add_answer(new DNSSoaRR(".", 600, "a.root-servers.net", "nstld.verisign-grs.com", 123456, 3600, 3600, 3600, 3600));
2✔
911
  EXPECT_CALL(server_, OnRequest("", T_SOA))
4✔
912
    .WillOnce(SetReply(&server_, &rsp));
2✔
913

914
  QueryResult result;
2✔
915
  ares_query_dnsrec(channel_, ".", ARES_CLASS_IN, ARES_REC_TYPE_SOA, QueryCallback, &result, NULL);
2✔
916
  Process();
2✔
917
  EXPECT_TRUE(result.done_);
2✔
918
  EXPECT_EQ(0, result.timeouts_);
2✔
919

920
  QueryResult cacheresult;
4✔
921
  ares_query_dnsrec(channel_, ".", ARES_CLASS_IN, ARES_REC_TYPE_SOA, QueryCallback, &cacheresult, NULL);
2✔
922
  Process();
2✔
923
  EXPECT_TRUE(cacheresult.done_);
2✔
924
  EXPECT_EQ(0, cacheresult.timeouts_);
2✔
925
}
2✔
926

927
TEST_P(CacheQueriesTest, SearchDomainsCache) {
2✔
928
  DNSPacket nofirst;
2✔
929
  nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
930
    .add_question(new DNSQuestion("www.first.com", T_A))
4✔
931
    .add_auth(new DNSSoaRR("first.com", 600, "ns1.first.com", "admin.first.com", 123456, 3600, 3600, 3600, 3600));
2✔
932
  EXPECT_CALL(server_, OnRequest("www.first.com", T_A))
4✔
933
    .WillOnce(SetReply(&server_, &nofirst));
2✔
934
  DNSPacket nosecond;
2✔
935
  nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
936
    .add_question(new DNSQuestion("www.second.org", T_A))
4✔
937
    .add_auth(new DNSSoaRR("second.org", 600, "ns1.second.org", "admin.second.org", 123456, 3600, 3600, 3600, 3600));
2✔
938
  EXPECT_CALL(server_, OnRequest("www.second.org", T_A))
4✔
939
    .WillOnce(SetReply(&server_, &nosecond));
2✔
940
  DNSPacket yesthird;
2✔
941
  yesthird.set_response().set_aa()
2✔
942
    .add_question(new DNSQuestion("www.third.gov", T_A))
4✔
943
    .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
2✔
944
  EXPECT_CALL(server_, OnRequest("www.third.gov", T_A))
4✔
945
    .WillOnce(SetReply(&server_, &yesthird));
2✔
946

947
  // First pass through should send the queries.  The EXPECT_CALL .WillOnce
948
  // will make sure this only happens once (vs ON_CALL .WillByDefault)
949
  HostResult result;
2✔
950
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
2✔
951
  Process();
2✔
952
  EXPECT_TRUE(result.done_);
2✔
953
  std::stringstream ss;
4✔
954
  ss << result.host_;
2✔
955
  EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
4✔
956

957
  // This pass should be fully served by cache and yield the same result
958
  HostResult cacheresult;
4✔
959
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &cacheresult);
2✔
960
  Process();
2✔
961
  EXPECT_TRUE(cacheresult.done_);
2✔
962
  std::stringstream sscache;
4✔
963
  sscache << cacheresult.host_;
2✔
964
  EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", sscache.str());
4✔
965
}
2✔
966

967
// Relies on retries so is UDP-only
968
TEST_P(MockUDPChannelTest, SearchDomainsWithResentReply) {
2✔
969
  DNSPacket nofirst;
2✔
970
  nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
971
    .add_question(new DNSQuestion("www.first.com", T_A));
2✔
972
  EXPECT_CALL(server_, OnRequest("www.first.com", T_A))
4✔
973
    .WillOnce(SetReply(&server_, &nofirst));
2✔
974
  DNSPacket nosecond;
2✔
975
  nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
976
    .add_question(new DNSQuestion("www.second.org", T_A));
2✔
977
  EXPECT_CALL(server_, OnRequest("www.second.org", T_A))
4✔
978
    .WillOnce(SetReply(&server_, &nosecond));
2✔
979
  DNSPacket yesthird;
2✔
980
  yesthird.set_response().set_aa()
2✔
981
    .add_question(new DNSQuestion("www.third.gov", T_A))
4✔
982
    .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
2✔
983
  // Before sending the real answer, resend an earlier reply
984
  EXPECT_CALL(server_, OnRequest("www.third.gov", T_A))
4✔
985
    .WillOnce(DoAll(SetReply(&server_, &nofirst),
4✔
986
                    SetReplyQID(&server_, 123)))
4✔
987
    .WillOnce(DoAll(SetReply(&server_, &yesthird),
2✔
988
                    SetReplyQID(&server_, -1)));
4✔
989

990
  HostResult result;
2✔
991
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
2✔
992
  Process();
2✔
993
  EXPECT_TRUE(result.done_);
2✔
994
  std::stringstream ss;
4✔
995
  ss << result.host_;
2✔
996
  EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
4✔
997
}
2✔
998

999
TEST_P(MockChannelTest, SearchDomainsBare) {
4✔
1000
  DNSPacket nofirst;
4✔
1001
  nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
4✔
1002
    .add_question(new DNSQuestion("www.first.com", T_A));
4✔
1003
  ON_CALL(server_, OnRequest("www.first.com", T_A))
8✔
1004
    .WillByDefault(SetReply(&server_, &nofirst));
4✔
1005
  DNSPacket nosecond;
4✔
1006
  nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
4✔
1007
    .add_question(new DNSQuestion("www.second.org", T_A));
4✔
1008
  ON_CALL(server_, OnRequest("www.second.org", T_A))
8✔
1009
    .WillByDefault(SetReply(&server_, &nosecond));
4✔
1010
  DNSPacket nothird;
4✔
1011
  nothird.set_response().set_aa().set_rcode(NXDOMAIN)
4✔
1012
    .add_question(new DNSQuestion("www.third.gov", T_A));
4✔
1013
  ON_CALL(server_, OnRequest("www.third.gov", T_A))
8✔
1014
    .WillByDefault(SetReply(&server_, &nothird));
4✔
1015
  DNSPacket yesbare;
4✔
1016
  yesbare.set_response().set_aa()
4✔
1017
    .add_question(new DNSQuestion("www", T_A))
8✔
1018
    .add_answer(new DNSARR("www", 0x0200, {2, 3, 4, 5}));
4✔
1019
  ON_CALL(server_, OnRequest("www", T_A))
8✔
1020
    .WillByDefault(SetReply(&server_, &yesbare));
4✔
1021

1022
  HostResult result;
4✔
1023
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
1024
  Process();
4✔
1025
  EXPECT_TRUE(result.done_);
4✔
1026
  EXPECT_EQ(0, result.timeouts_);
4✔
1027

1028
  std::stringstream ss;
8✔
1029
  ss << result.host_;
4✔
1030
  EXPECT_EQ("{'www' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
1031
}
4✔
1032

1033
TEST_P(MockChannelTest, SearchNoDataThenSuccess) {
4✔
1034
  // First two search domains recognize the name but have no A records.
1035
  DNSPacket nofirst;
4✔
1036
  nofirst.set_response().set_aa()
4✔
1037
    .add_question(new DNSQuestion("www.first.com", T_A));
4✔
1038
  ON_CALL(server_, OnRequest("www.first.com", T_A))
8✔
1039
    .WillByDefault(SetReply(&server_, &nofirst));
4✔
1040
  DNSPacket nosecond;
4✔
1041
  nosecond.set_response().set_aa()
4✔
1042
    .add_question(new DNSQuestion("www.second.org", T_A));
4✔
1043
  ON_CALL(server_, OnRequest("www.second.org", T_A))
8✔
1044
    .WillByDefault(SetReply(&server_, &nosecond));
4✔
1045
  DNSPacket yesthird;
4✔
1046
  yesthird.set_response().set_aa()
4✔
1047
    .add_question(new DNSQuestion("www.third.gov", T_A))
8✔
1048
    .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
4✔
1049
  ON_CALL(server_, OnRequest("www.third.gov", T_A))
8✔
1050
    .WillByDefault(SetReply(&server_, &yesthird));
4✔
1051

1052
  HostResult result;
4✔
1053
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
1054
  Process();
4✔
1055
  EXPECT_TRUE(result.done_);
4✔
1056
  std::stringstream ss;
8✔
1057
  ss << result.host_;
4✔
1058
  EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
1059
}
4✔
1060

1061
TEST_P(MockChannelTest, SearchNoDataThenNoDataBare) {
4✔
1062
  // First two search domains recognize the name but have no A records.
1063
  DNSPacket nofirst;
4✔
1064
  nofirst.set_response().set_aa()
4✔
1065
    .add_question(new DNSQuestion("www.first.com", T_A));
4✔
1066
  ON_CALL(server_, OnRequest("www.first.com", T_A))
8✔
1067
    .WillByDefault(SetReply(&server_, &nofirst));
4✔
1068
  DNSPacket nosecond;
4✔
1069
  nosecond.set_response().set_aa()
4✔
1070
    .add_question(new DNSQuestion("www.second.org", T_A));
4✔
1071
  ON_CALL(server_, OnRequest("www.second.org", T_A))
8✔
1072
    .WillByDefault(SetReply(&server_, &nosecond));
4✔
1073
  DNSPacket nothird;
4✔
1074
  nothird.set_response().set_aa()
4✔
1075
    .add_question(new DNSQuestion("www.third.gov", T_A));
4✔
1076
  ON_CALL(server_, OnRequest("www.third.gov", T_A))
8✔
1077
    .WillByDefault(SetReply(&server_, &nothird));
4✔
1078
  DNSPacket nobare;
4✔
1079
  nobare.set_response().set_aa()
4✔
1080
    .add_question(new DNSQuestion("www", T_A));
4✔
1081
  ON_CALL(server_, OnRequest("www", T_A))
8✔
1082
    .WillByDefault(SetReply(&server_, &nobare));
4✔
1083

1084
  HostResult result;
4✔
1085
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
1086
  Process();
4✔
1087
  EXPECT_TRUE(result.done_);
4✔
1088
  EXPECT_EQ(ARES_ENODATA, result.status_);
4✔
1089
}
4✔
1090

1091
TEST_P(MockChannelTest, SearchNoDataThenFail) {
4✔
1092
  // First two search domains recognize the name but have no A records.
1093
  DNSPacket nofirst;
4✔
1094
  nofirst.set_response().set_aa()
4✔
1095
    .add_question(new DNSQuestion("www.first.com", T_A));
4✔
1096
  ON_CALL(server_, OnRequest("www.first.com", T_A))
8✔
1097
    .WillByDefault(SetReply(&server_, &nofirst));
4✔
1098
  DNSPacket nosecond;
4✔
1099
  nosecond.set_response().set_aa()
4✔
1100
    .add_question(new DNSQuestion("www.second.org", T_A));
4✔
1101
  ON_CALL(server_, OnRequest("www.second.org", T_A))
8✔
1102
    .WillByDefault(SetReply(&server_, &nosecond));
4✔
1103
  DNSPacket nothird;
4✔
1104
  nothird.set_response().set_aa()
4✔
1105
    .add_question(new DNSQuestion("www.third.gov", T_A));
4✔
1106
  ON_CALL(server_, OnRequest("www.third.gov", T_A))
8✔
1107
    .WillByDefault(SetReply(&server_, &nothird));
4✔
1108
  DNSPacket nobare;
4✔
1109
  nobare.set_response().set_aa().set_rcode(NXDOMAIN)
4✔
1110
    .add_question(new DNSQuestion("www", T_A));
4✔
1111
  ON_CALL(server_, OnRequest("www", T_A))
8✔
1112
    .WillByDefault(SetReply(&server_, &nobare));
4✔
1113

1114
  HostResult result;
4✔
1115
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
1116
  Process();
4✔
1117
  EXPECT_TRUE(result.done_);
4✔
1118
  EXPECT_EQ(ARES_ENODATA, result.status_);
4✔
1119
}
4✔
1120

1121
TEST_P(MockChannelTest, SearchAllocFailure) {
4✔
1122
  SearchResult result;
4✔
1123
  SetAllocFail(1);
4✔
1124
  ares_search(channel_, "fully.qualified.", C_IN, T_A, SearchCallback, &result);
4✔
1125
  /* Already done */
1126
  EXPECT_TRUE(result.done_);
4✔
1127
  EXPECT_EQ(ARES_ENOMEM, result.status_);
4✔
1128
}
4✔
1129

1130
TEST_P(MockChannelTest, SearchHighNdots) {
4✔
1131
  DNSPacket nobare;
4✔
1132
  nobare.set_response().set_aa().set_rcode(NXDOMAIN)
4✔
1133
    .add_question(new DNSQuestion("a.b.c.w.w.w", T_A));
4✔
1134
  ON_CALL(server_, OnRequest("a.b.c.w.w.w", T_A))
8✔
1135
    .WillByDefault(SetReply(&server_, &nobare));
4✔
1136
  DNSPacket yesfirst;
4✔
1137
  yesfirst.set_response().set_aa()
4✔
1138
    .add_question(new DNSQuestion("a.b.c.w.w.w.first.com", T_A))
8✔
1139
    .add_answer(new DNSARR("a.b.c.w.w.w.first.com", 0x0200, {2, 3, 4, 5}));
4✔
1140
  ON_CALL(server_, OnRequest("a.b.c.w.w.w.first.com", T_A))
8✔
1141
    .WillByDefault(SetReply(&server_, &yesfirst));
4✔
1142

1143
  SearchResult result;
4✔
1144
  ares_search(channel_, "a.b.c.w.w.w", C_IN, T_A, SearchCallback, &result);
4✔
1145
  Process();
4✔
1146
  EXPECT_TRUE(result.done_);
4✔
1147
  EXPECT_EQ(ARES_SUCCESS, result.status_);
4✔
1148
  std::stringstream ss;
8✔
1149
  ss << PacketToString(result.data_);
4✔
1150
  EXPECT_EQ("RSP QRY AA NOERROR Q:{'a.b.c.w.w.w.first.com' IN A} "
8✔
1151
            "A:{'a.b.c.w.w.w.first.com' IN A TTL=512 2.3.4.5}",
1152
            ss.str());
4✔
1153
}
4✔
1154

1155
// Test that performing an EDNS search with an OPT RR options value works. The
1156
// options value should be included on the requests to the mock server.
1157
// We are going to do this only via TCP since this won't include the dynamically
1158
// generated DNS cookie that would otherwise mess with this result.
1159
TEST_P(MockTCPChannelTest, SearchOptVal) {
2✔
1160
  /* Define the OPT RR options code and value to use. */
1161
  unsigned short opt_opt = 3;
2✔
1162
  unsigned char opt_val[] = { 'c', '-', 'a', 'r', 'e', 's' };
2✔
1163

1164
  /* Set up the expected request and reply on the mock server for the first,
1165
   * second and third domains. The expected requests contain the OPT RR options
1166
   * value defined above.
1167
   */
1168
  std::string nofirst_req = "REQ QRY RD  Q:{'example.first.com' IN A} "
1169
    "ADD:{'' MAXUDP=1232 OPT RCODE2=0 "
1170
    "0003"  // opt_opt
1171
    "0006"  // length of opt_val
1172
    "632d61726573"  // opt_val in hex
1173
    "}";
2✔
1174
  DNSPacket nofirst_rep;
2✔
1175
  nofirst_rep.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
1176
    .add_question(new DNSQuestion("example.first.com", T_A));
2✔
1177
  ON_CALL(server_, OnRequest("example.first.com", T_A))
4✔
1178
    .WillByDefault(SetReplyExpRequest(&server_, &nofirst_rep, nofirst_req));
2✔
1179

1180
  std::string nosecond_req = "REQ QRY RD  Q:{'example.second.org' IN A} "
1181
    "ADD:{'' MAXUDP=1232 OPT RCODE2=0 "
1182
    "0003"  // opt_opt
1183
    "0006"  // length of opt_val
1184
    "632d61726573"  // opt_val in hex
1185
    "}";
2✔
1186
  DNSPacket nosecond_rep;
2✔
1187
  nosecond_rep.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
1188
    .add_question(new DNSQuestion("example.second.org", T_A));
2✔
1189
  ON_CALL(server_, OnRequest("example.second.org", T_A))
4✔
1190
    .WillByDefault(SetReplyExpRequest(&server_, &nosecond_rep, nosecond_req));
2✔
1191

1192
  std::string nothird_req = "REQ QRY RD  Q:{'example.third.gov' IN A} "
1193
    "ADD:{'' MAXUDP=1232 OPT RCODE2=0 "
1194
    "0003"  // opt_opt
1195
    "0006"  // length of opt_val
1196
    "632d61726573"  // opt_val in hex
1197
    "}";
2✔
1198
  DNSPacket nothird_rep;
2✔
1199
  nothird_rep.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
1200
    .add_question(new DNSQuestion("example.third.gov", T_A));
2✔
1201
  ON_CALL(server_, OnRequest("example.third.gov", T_A))
4✔
1202
    .WillByDefault(SetReplyExpRequest(&server_, &nothird_rep, nothird_req));
2✔
1203

1204
  /* Set up the expected request and reply on the mock server for the bare
1205
   * domain. The expected request contains the OPT RR options value defined
1206
   * above.
1207
   */
1208
  std::string yesbare_req = "REQ QRY RD  Q:{'example' IN A} "
1209
    "ADD:{'' MAXUDP=1232 OPT RCODE2=0 "
1210
    "0003"  // opt_opt
1211
    "0006"  // length of opt_val
1212
    "632d61726573"  // opt_val in hex
1213
    "}";
2✔
1214
  DNSPacket yesbare_rep;
2✔
1215
  yesbare_rep.set_response().set_aa()
2✔
1216
    .add_question(new DNSQuestion("example", T_A))
4✔
1217
    .add_answer(new DNSARR("example", 0x0200, {2, 3, 4, 5}));
2✔
1218
  ON_CALL(server_, OnRequest("example", T_A))
4✔
1219
    .WillByDefault(SetReplyExpRequest(&server_, &yesbare_rep, yesbare_req));
2✔
1220

1221
  /* Construct the DNS record to search. */
1222
  ares_dns_record_t *dnsrec = NULL;
2✔
1223
  ares_dns_rr_t *rr = NULL;
2✔
1224
  EXPECT_EQ(ARES_SUCCESS,
2✔
1225
    ares_dns_record_create(&dnsrec, 0, ARES_FLAG_RD, ARES_OPCODE_QUERY,
1226
      ARES_RCODE_NOERROR));
2✔
1227
  EXPECT_EQ(ARES_SUCCESS,
2✔
1228
    ares_dns_record_query_add(dnsrec, "example", (ares_dns_rec_type_t)T_A,
1229
      (ares_dns_class_t)C_IN));
2✔
1230
  EXPECT_EQ(ARES_SUCCESS,
2✔
1231
    ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL, "",
1232
      ARES_REC_TYPE_OPT, ARES_CLASS_IN, 0));
2✔
1233
  EXPECT_EQ(ARES_SUCCESS,
2✔
1234
    ares_dns_rr_set_u16(rr, ARES_RR_OPT_UDP_SIZE, 1232));
2✔
1235
  EXPECT_EQ(ARES_SUCCESS, ares_dns_rr_set_u8(rr, ARES_RR_OPT_VERSION, 0));
2✔
1236
  EXPECT_EQ(ARES_SUCCESS, ares_dns_rr_set_u16(rr, ARES_RR_OPT_FLAGS, 0));
2✔
1237
  EXPECT_EQ(ARES_SUCCESS,
2✔
1238
    ares_dns_rr_set_opt(rr, ARES_RR_OPT_OPTIONS, opt_opt, opt_val,
1239
      sizeof(opt_val)));
2✔
1240

1241
  /* Perform the search. Check that it succeeds with the expected response. */
1242
  SearchResult result;
4✔
1243
  ares_search_dnsrec(channel_, dnsrec, SearchCallbackDnsRec, &result);
2✔
1244
  ares_dns_record_destroy(dnsrec);
2✔
1245
  Process();
2✔
1246
  EXPECT_TRUE(result.done_);
2✔
1247
  EXPECT_EQ(ARES_SUCCESS, result.status_);
2✔
1248
  std::stringstream ss;
4✔
1249
  ss << PacketToString(result.data_);
2✔
1250
  EXPECT_EQ("RSP QRY AA NOERROR Q:{'example' IN A} "
4✔
1251
            "A:{'example' IN A TTL=512 2.3.4.5}",
1252
            ss.str());
2✔
1253
}
2✔
1254

1255
TEST_P(MockChannelTest, V4WorksV6Timeout) {
4✔
1256
  std::vector<byte> nothing;
4✔
1257
  DNSPacket reply;
4✔
1258
  reply.set_response().set_aa()
4✔
1259
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
1260
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
4✔
1261

1262
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
1263
    .WillByDefault(SetReply(&server_, &reply));
4✔
1264

1265
  ON_CALL(server_, OnRequest("www.google.com", T_AAAA))
8✔
1266
    .WillByDefault(SetReplyData(&server_, nothing));
4✔
1267

1268
  HostResult result;
4✔
1269
  ares_gethostbyname(channel_, "www.google.com.", AF_UNSPEC, HostCallback, &result);
4✔
1270
  Process();
4✔
1271
  EXPECT_TRUE(result.done_);
4✔
1272
  EXPECT_EQ(1, result.timeouts_);
4✔
1273
  std::stringstream ss;
8✔
1274
  ss << result.host_;
4✔
1275
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
8✔
1276
}
4✔
1277

1278
// Test case for Issue #662
1279
TEST_P(MockChannelTest, PartialQueryCancel) {
4✔
1280
  std::vector<byte> nothing;
4✔
1281
  DNSPacket reply;
4✔
1282
  reply.set_response().set_aa()
4✔
1283
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
1284
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
4✔
1285

1286
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
1287
    .WillByDefault(SetReply(&server_, &reply));
4✔
1288

1289
  ON_CALL(server_, OnRequest("www.google.com", T_AAAA))
8✔
1290
    .WillByDefault(SetReplyData(&server_, nothing));
4✔
1291

1292
  HostResult result;
4✔
1293
  ares_gethostbyname(channel_, "www.google.com.", AF_UNSPEC, HostCallback, &result);
4✔
1294
  // After 100ms, issues ares_cancel(), this should be enough time for the A
1295
  // record reply, but before the timeout on the AAAA record.
1296
  Process(100);
4✔
1297
  EXPECT_TRUE(result.done_);
4✔
1298
  EXPECT_EQ(ARES_ECANCELLED, result.status_);
4✔
1299
}
4✔
1300

1301
TEST_P(MockChannelTest, UnspecifiedFamilyV6) {
4✔
1302
  DNSPacket rsp6;
4✔
1303
  rsp6.set_response().set_aa()
4✔
1304
    .add_question(new DNSQuestion("example.com", T_AAAA))
8✔
1305
    .add_answer(new DNSAaaaRR("example.com", 100,
8✔
1306
                              {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
4✔
1308
  ON_CALL(server_, OnRequest("example.com", T_AAAA))
8✔
1309
    .WillByDefault(SetReply(&server_, &rsp6));
4✔
1310

1311
  DNSPacket rsp4;
4✔
1312
  rsp4.set_response().set_aa()
4✔
1313
    .add_question(new DNSQuestion("example.com", T_A));
4✔
1314
  ON_CALL(server_, OnRequest("example.com", T_A))
8✔
1315
    .WillByDefault(SetReply(&server_, &rsp4));
4✔
1316

1317
  HostResult result;
4✔
1318
  ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
4✔
1319
  Process();
4✔
1320
  EXPECT_TRUE(result.done_);
4✔
1321
  std::stringstream ss;
8✔
1322
  ss << result.host_;
4✔
1323
  // Default to IPv6 when both are available.
1324
  EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
8✔
1325
}
4✔
1326

1327
TEST_P(MockChannelTest, UnspecifiedFamilyV4) {
4✔
1328
  DNSPacket rsp6;
4✔
1329
  rsp6.set_response().set_aa()
4✔
1330
    .add_question(new DNSQuestion("example.com", T_AAAA));
4✔
1331
  ON_CALL(server_, OnRequest("example.com", T_AAAA))
8✔
1332
    .WillByDefault(SetReply(&server_, &rsp6));
4✔
1333
  DNSPacket rsp4;
4✔
1334
  rsp4.set_response().set_aa()
4✔
1335
    .add_question(new DNSQuestion("example.com", T_A))
8✔
1336
    .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
4✔
1337
  ON_CALL(server_, OnRequest("example.com", T_A))
8✔
1338
    .WillByDefault(SetReply(&server_, &rsp4));
4✔
1339

1340
  HostResult result;
4✔
1341
  ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
4✔
1342
  Process();
4✔
1343
  EXPECT_TRUE(result.done_);
4✔
1344
  std::stringstream ss;
8✔
1345
  ss << result.host_;
4✔
1346
  EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
1347
}
4✔
1348

1349
TEST_P(MockChannelTest, UnspecifiedFamilyNoData) {
4✔
1350
  DNSPacket rsp6;
4✔
1351
  rsp6.set_response().set_aa()
4✔
1352
    .add_question(new DNSQuestion("example.com", T_AAAA))
8✔
1353
    .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
4✔
1354
  ON_CALL(server_, OnRequest("example.com", T_AAAA))
8✔
1355
    .WillByDefault(SetReply(&server_, &rsp6));
4✔
1356
  DNSPacket rsp4;
4✔
1357
  rsp4.set_response().set_aa()
4✔
1358
    .add_question(new DNSQuestion("example.com", T_A));
4✔
1359
  ON_CALL(server_, OnRequest("example.com", T_A))
8✔
1360
    .WillByDefault(SetReply(&server_, &rsp4));
4✔
1361

1362
  HostResult result;
4✔
1363
  ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
4✔
1364
  Process();
4✔
1365
  EXPECT_TRUE(result.done_);
4✔
1366
  std::stringstream ss;
8✔
1367
  ss << result.host_;
4✔
1368
  EXPECT_EQ("{'' aliases=[] addrs=[]}", ss.str());
8✔
1369
}
4✔
1370

1371
TEST_P(MockChannelTest, UnspecifiedFamilyCname6A4) {
4✔
1372
  DNSPacket rsp6;
4✔
1373
  rsp6.set_response().set_aa()
4✔
1374
    .add_question(new DNSQuestion("example.com", T_AAAA))
8✔
1375
    .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
4✔
1376
  ON_CALL(server_, OnRequest("example.com", T_AAAA))
8✔
1377
    .WillByDefault(SetReply(&server_, &rsp6));
4✔
1378
  DNSPacket rsp4;
4✔
1379
  rsp4.set_response().set_aa()
4✔
1380
    .add_question(new DNSQuestion("example.com", T_A))
8✔
1381
    .add_answer(new DNSARR("example.com", 100, {1, 2, 3, 4}));
4✔
1382
  ON_CALL(server_, OnRequest("example.com", T_A))
8✔
1383
    .WillByDefault(SetReply(&server_, &rsp4));
4✔
1384

1385
  HostResult result;
4✔
1386
  ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
4✔
1387
  Process();
4✔
1388
  EXPECT_TRUE(result.done_);
4✔
1389
  std::stringstream ss;
8✔
1390
  ss << result.host_;
4✔
1391
  EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
8✔
1392
}
4✔
1393

1394
TEST_P(MockChannelTest, ExplicitIP) {
4✔
1395
  HostResult result;
4✔
1396
  ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
4✔
1397
  EXPECT_TRUE(result.done_);  // Immediate return
4✔
1398
  EXPECT_EQ(ARES_SUCCESS, result.status_);
4✔
1399
  std::stringstream ss;
8✔
1400
  ss << result.host_;
4✔
1401
  EXPECT_EQ("{'1.2.3.4' aliases=[] addrs=[1.2.3.4]}", ss.str());
8✔
1402
}
4✔
1403

1404
TEST_P(MockChannelTest, ExplicitIPAllocFail) {
4✔
1405
  HostResult result;
4✔
1406
  SetAllocSizeFail(strlen("1.2.3.4") + 1);
4✔
1407
  ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
4✔
1408
  EXPECT_TRUE(result.done_);  // Immediate return
4✔
1409
  EXPECT_EQ(ARES_ENOMEM, result.status_);
4✔
1410
}
4✔
1411

1412
TEST_P(MockChannelTest, SortListV4) {
4✔
1413
  DNSPacket rsp;
4✔
1414
  rsp.set_response().set_aa()
4✔
1415
    .add_question(new DNSQuestion("example.com", T_A))
8✔
1416
    .add_answer(new DNSARR("example.com", 100, {22, 23, 24, 25}))
8✔
1417
    .add_answer(new DNSARR("example.com", 100, {12, 13, 14, 15}))
8✔
1418
    .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
4✔
1419
  ON_CALL(server_, OnRequest("example.com", T_A))
8✔
1420
    .WillByDefault(SetReply(&server_, &rsp));
4✔
1421

1422
  {
1423
    EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "12.13.0.0/255.255.0.0 1234::5678"));
4✔
1424
    HostResult result;
8✔
1425
    ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
4✔
1426
    Process();
4✔
1427
    EXPECT_TRUE(result.done_);
4✔
1428
    std::stringstream ss;
8✔
1429
    ss << result.host_;
4✔
1430
    EXPECT_EQ("{'example.com' aliases=[] addrs=[12.13.14.15, 22.23.24.25, 2.3.4.5]}", ss.str());
8✔
1431
  }
1432
  {
1433
    EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "2.3.0.0/16 130.140.150.160/26"));
4✔
1434
    HostResult result;
8✔
1435
    ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
4✔
1436
    Process();
4✔
1437
    EXPECT_TRUE(result.done_);
4✔
1438
    std::stringstream ss;
8✔
1439
    ss << result.host_;
4✔
1440
    EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5, 22.23.24.25, 12.13.14.15]}", ss.str());
8✔
1441
  }
1442
  struct ares_options options;
1443
  memset(&options, 0, sizeof(options));
4✔
1444
  int optmask = 0;
4✔
1445
  EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &options, &optmask));
4✔
1446
  EXPECT_TRUE((optmask & ARES_OPT_SORTLIST) == ARES_OPT_SORTLIST);
4✔
1447
  ares_destroy_options(&options);
4✔
1448
}
4✔
1449

1450
TEST_P(MockChannelTest, SortListV6) {
4✔
1451
  DNSPacket rsp;
4✔
1452
  rsp.set_response().set_aa()
4✔
1453
    .add_question(new DNSQuestion("example.com", T_AAAA))
8✔
1454
    .add_answer(new DNSAaaaRR("example.com", 100,
12✔
1455
                              {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1456
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02}))
4✔
1457
    .add_answer(new DNSAaaaRR("example.com", 100,
8✔
1458
                              {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1459
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
4✔
1460
  ON_CALL(server_, OnRequest("example.com", T_AAAA))
8✔
1461
    .WillByDefault(SetReply(&server_, &rsp));
4✔
1462

1463
  {
1464
    ares_set_sortlist(channel_, "1111::/16 2.3.0.0/255.255.0.0");
4✔
1465
    HostResult result;
4✔
1466
    ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
4✔
1467
    Process();
4✔
1468
    EXPECT_TRUE(result.done_);
4✔
1469
    std::stringstream ss;
8✔
1470
    ss << result.host_;
4✔
1471
    EXPECT_EQ("{'example.com' aliases=[] addrs=[1111:0000:0000:0000:0000:0000:0000:0202, "
8✔
1472
              "2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
4✔
1473
  }
4✔
1474
  {
1475
    ares_set_sortlist(channel_, "2121::/8");
4✔
1476
    HostResult result;
4✔
1477
    ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
4✔
1478
    Process();
4✔
1479
    EXPECT_TRUE(result.done_);
4✔
1480
    std::stringstream ss;
8✔
1481
    ss << result.host_;
4✔
1482
    EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303, "
8✔
1483
              "1111:0000:0000:0000:0000:0000:0000:0202]}", ss.str());
4✔
1484
  }
4✔
1485
}
4✔
1486

1487
// Relies on retries so is UDP-only
1488
TEST_P(MockUDPChannelTest, SearchDomainsAllocFail) {
2✔
1489
  DNSPacket nofirst;
2✔
1490
  nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
1491
    .add_question(new DNSQuestion("www.first.com", T_A));
2✔
1492
  ON_CALL(server_, OnRequest("www.first.com", T_A))
4✔
1493
    .WillByDefault(SetReply(&server_, &nofirst));
2✔
1494
  DNSPacket nosecond;
2✔
1495
  nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
2✔
1496
    .add_question(new DNSQuestion("www.second.org", T_A));
2✔
1497
  ON_CALL(server_, OnRequest("www.second.org", T_A))
4✔
1498
    .WillByDefault(SetReply(&server_, &nosecond));
2✔
1499
  DNSPacket yesthird;
2✔
1500
  yesthird.set_response().set_aa()
2✔
1501
    .add_question(new DNSQuestion("www.third.gov", T_A))
4✔
1502
    .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
2✔
1503
  ON_CALL(server_, OnRequest("www.third.gov", T_A))
4✔
1504
    .WillByDefault(SetReply(&server_, &yesthird));
2✔
1505

1506
  // Fail a variety of different memory allocations, and confirm
1507
  // that the operation either fails with ENOMEM or succeeds
1508
  // with the expected result.
1509
  const int kCount = 34;
2✔
1510
  HostResult results[kCount];
138✔
1511
  for (int ii = 1; ii <= kCount; ii++) {
70✔
1512
    HostResult* result = &(results[ii - 1]);
68✔
1513
    ClearFails();
68✔
1514
    SetAllocFail(ii);
68✔
1515
    ares_gethostbyname(channel_, "www", AF_INET, HostCallback, result);
68✔
1516
    Process();
68✔
1517
    EXPECT_TRUE(result->done_);
68✔
1518
    if (result->status_ == ARES_SUCCESS) {
68✔
1519
      std::stringstream ss;
48✔
1520
      ss << result->host_;
48✔
1521
      EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str()) << " failed alloc #" << ii;
96✔
1522
      if (verbose) std::cerr << "Succeeded despite failure of alloc #" << ii << std::endl;
48✔
1523
    }
48✔
1524
  }
1525

1526
  // Explicitly destroy the channel now, so that the HostResult objects
1527
  // are still valid (in case any pending work refers to them).
1528
  ares_destroy(channel_);
2✔
1529
  channel_ = nullptr;
2✔
1530
}
72✔
1531

1532
// Relies on retries so is UDP-only
1533
TEST_P(MockUDPChannelTest, Resend) {
2✔
1534
  std::vector<byte> nothing;
2✔
1535
  DNSPacket reply;
2✔
1536
  reply.set_response().set_aa()
2✔
1537
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1538
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
2✔
1539

1540
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
1541
    .WillOnce(SetReplyData(&server_, nothing))
4✔
1542
    .WillOnce(SetReplyData(&server_, nothing))
4✔
1543
    .WillOnce(SetReply(&server_, &reply));
2✔
1544

1545
  HostResult result;
2✔
1546
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
1547
  Process();
2✔
1548
  EXPECT_TRUE(result.done_);
2✔
1549
  EXPECT_EQ(2, result.timeouts_);
2✔
1550
  std::stringstream ss;
4✔
1551
  ss << result.host_;
2✔
1552
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
4✔
1553
}
2✔
1554

1555
TEST_P(MockChannelTest, CancelImmediate) {
4✔
1556
  HostResult result;
4✔
1557
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
1558
  ares_cancel(channel_);
4✔
1559
  EXPECT_TRUE(result.done_);
4✔
1560
  EXPECT_EQ(ARES_ECANCELLED, result.status_);
4✔
1561
  EXPECT_EQ(0, result.timeouts_);
4✔
1562
}
4✔
1563

1564
TEST_P(MockChannelTest, CancelImmediateGetHostByAddr) {
4✔
1565
  HostResult result;
4✔
1566
  struct in_addr addr;
1567
  addr.s_addr = htonl(0x08080808);
4✔
1568

1569
  ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
4✔
1570
  ares_cancel(channel_);
4✔
1571
  EXPECT_TRUE(result.done_);
4✔
1572
  EXPECT_EQ(ARES_ECANCELLED, result.status_);
4✔
1573
  EXPECT_EQ(0, result.timeouts_);
4✔
1574
}
4✔
1575

1576
// Relies on retries so is UDP-only
1577
TEST_P(MockUDPChannelTest, CancelLater) {
2✔
1578
  std::vector<byte> nothing;
2✔
1579

1580
  // On second request, cancel the channel.
1581
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
1582
    .WillOnce(SetReplyData(&server_, nothing))
4✔
1583
    .WillOnce(CancelChannel(&server_, channel_));
2✔
1584

1585
  HostResult result;
2✔
1586
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
1587
  Process();
2✔
1588
  EXPECT_TRUE(result.done_);
2✔
1589
  EXPECT_EQ(ARES_ECANCELLED, result.status_);
2✔
1590
  EXPECT_EQ(0, result.timeouts_);
2✔
1591
}
2✔
1592

1593
TEST_P(MockChannelTest, DisconnectFirstAttempt) {
4✔
1594
  DNSPacket reply;
4✔
1595
  reply.set_response().set_aa()
4✔
1596
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
1597
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
4✔
1598

1599
  // On second request, cancel the channel.
1600
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
8✔
1601
    .WillOnce(Disconnect(&server_))
8✔
1602
    .WillOnce(SetReply(&server_, &reply));
4✔
1603

1604
  HostResult result;
4✔
1605
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
1606
  Process();
4✔
1607
  EXPECT_TRUE(result.done_);
4✔
1608
  std::stringstream ss;
8✔
1609
  ss << result.host_;
4✔
1610
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
8✔
1611
}
4✔
1612

1613
TEST_P(MockChannelTest, GetHostByNameDestroyAbsolute) {
4✔
1614
  HostResult result;
4✔
1615
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
1616

1617
  ares_destroy(channel_);
4✔
1618
  channel_ = nullptr;
4✔
1619

1620
  EXPECT_TRUE(result.done_);  // Synchronous
4✔
1621
  EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
4✔
1622
  EXPECT_EQ(0, result.timeouts_);
4✔
1623
}
4✔
1624

1625
TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
4✔
1626
  HostResult result;
4✔
1627
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
1628

1629
  ares_destroy(channel_);
4✔
1630
  channel_ = nullptr;
4✔
1631

1632
  EXPECT_TRUE(result.done_);  // Synchronous
4✔
1633
  EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
4✔
1634
  EXPECT_EQ(0, result.timeouts_);
4✔
1635
}
4✔
1636

1637
TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
4✔
1638
  DNSPacket response;
4✔
1639
  response.set_response().set_aa()
4✔
1640
    .add_question(new DNSQuestion("cname.first.com", T_A))
8✔
1641
    .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com"));
4✔
1642
  ON_CALL(server_, OnRequest("cname.first.com", T_A))
8✔
1643
    .WillByDefault(SetReply(&server_, &response));
4✔
1644

1645
  HostResult result;
4✔
1646
  ares_gethostbyname(channel_, "cname.first.com.", AF_INET, HostCallback, &result);
4✔
1647
  Process();
4✔
1648
  EXPECT_TRUE(result.done_);
4✔
1649
  EXPECT_EQ(ARES_ENODATA, result.status_);
4✔
1650
}
4✔
1651

1652
TEST_P(MockChannelTest, GetHostByAddrDestroy) {
4✔
1653
  unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
4✔
1654
  HostResult result;
4✔
1655
  ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
4✔
1656

1657
  ares_destroy(channel_);
4✔
1658
  channel_ = nullptr;
4✔
1659

1660
  EXPECT_TRUE(result.done_);  // Synchronous
4✔
1661
  EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
4✔
1662
  EXPECT_EQ(0, result.timeouts_);
4✔
1663
}
4✔
1664

1665
TEST_P(MockUDPChannelTest, GetSock) {
2✔
1666
  DNSPacket reply;
2✔
1667
  reply.set_response().set_aa()
2✔
1668
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1669
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
2✔
1670
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
1671
    .WillByDefault(SetReply(&server_, &reply));
2✔
1672

1673
  ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD};
2✔
1674
  int bitmask;
1675

1676
  bitmask = ares_getsock(channel_, socks, 3);
2✔
1677
  EXPECT_EQ(0, bitmask);
2✔
1678
  bitmask = ares_getsock(channel_, nullptr, 0);
2✔
1679
  EXPECT_EQ(0, bitmask);
2✔
1680

1681
  // Ask again with a pending query.
1682
  HostResult result;
4✔
1683
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
1684
  bitmask = ares_getsock(channel_, socks, 3);
2✔
1685
  EXPECT_NE(0, bitmask);
2✔
1686

1687
  size_t sock_cnt = 0;
2✔
1688
  for (size_t i=0; i<3; i++) {
8✔
1689
    if (ARES_GETSOCK_READABLE(bitmask, i) || ARES_GETSOCK_WRITABLE(bitmask, i)) {
6✔
1690
      EXPECT_NE(ARES_SOCKET_BAD, socks[i]);
2✔
1691
      if (socks[i] != ARES_SOCKET_BAD)
2✔
1692
        sock_cnt++;
2✔
1693
    }
1694
  }
1695
  EXPECT_NE((size_t)0, sock_cnt);
2✔
1696

1697
  Process();
2✔
1698

1699
  bitmask = ares_getsock(channel_, nullptr, 0);
2✔
1700
  EXPECT_EQ(0, bitmask);
2✔
1701
}
2✔
1702

1703
TEST_P(MockTCPChannelTest, GetSock) {
2✔
1704
  DNSPacket reply;
2✔
1705
  reply.set_response().set_aa()
2✔
1706
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1707
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
2✔
1708
  ON_CALL(server_, OnRequest("www.google.com", T_A))
4✔
1709
    .WillByDefault(SetReply(&server_, &reply));
2✔
1710

1711
  ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD};
2✔
1712
  int bitmask;
1713

1714
  bitmask = ares_getsock(channel_, socks, 3);
2✔
1715
  EXPECT_EQ(0, bitmask);
2✔
1716
  bitmask = ares_getsock(channel_, nullptr, 0);
2✔
1717
  EXPECT_EQ(0, bitmask);
2✔
1718

1719
  // Ask again with a pending query.
1720
  HostResult result;
4✔
1721
  ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
2✔
1722
  bitmask = ares_getsock(channel_, socks, 3);
2✔
1723
  EXPECT_NE(0, bitmask);
2✔
1724

1725
  size_t sock_cnt = 0;
2✔
1726
  for (size_t i=0; i<3; i++) {
8✔
1727
    if (ARES_GETSOCK_READABLE(bitmask, i) || ARES_GETSOCK_WRITABLE(bitmask, i)) {
6✔
1728
      EXPECT_NE(ARES_SOCKET_BAD, socks[i]);
2✔
1729
      if (socks[i] != ARES_SOCKET_BAD)
2✔
1730
        sock_cnt++;
2✔
1731
    }
1732
  }
1733
  EXPECT_NE((size_t)0, sock_cnt);
2✔
1734

1735
  Process();
2✔
1736

1737
  bitmask = ares_getsock(channel_, nullptr, 0);
2✔
1738
  EXPECT_EQ(0, bitmask);
2✔
1739
}
2✔
1740

1741

1742
TEST_P(MockChannelTest, VerifySocketFunctionCallback) {
4✔
1743
  ares_socket_functions sock_funcs;
1744
  memset(&sock_funcs, 0, sizeof(sock_funcs));
4✔
1745

1746
  DNSPacket reply;
4✔
1747
  reply.set_response().set_aa()
4✔
1748
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
1749
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
4✔
1750
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
1751
    .WillByDefault(SetReply(&server_, &reply));
4✔
1752

1753
  size_t count = 0;
4✔
1754

1755
  sock_funcs.asocket = [](int af, int type, int protocol, void * p) -> ares_socket_t {
16✔
1756
    EXPECT_NE(nullptr, p);
16✔
1757
    (*reinterpret_cast<size_t *>(p))++;
16✔
1758
    return ::socket(af, type, protocol);
16✔
1759
  };
4✔
1760

1761
  ares_set_socket_functions(channel_, &sock_funcs, &count);
4✔
1762

1763
  {
1764
    count = 0;
4✔
1765
    HostResult result;
4✔
1766
    ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
4✔
1767
    Process();
4✔
1768

1769
    EXPECT_TRUE(result.done_);
4✔
1770
    EXPECT_EQ(ARES_SUCCESS, result.status_);
4✔
1771
    EXPECT_EQ(0, result.timeouts_);
4✔
1772
    EXPECT_NE((size_t)0, count);
4✔
1773
  }
4✔
1774

1775
  {
1776
    count = 0;
4✔
1777
    ares_channel_t *copy;
1778
    EXPECT_EQ(ARES_SUCCESS, ares_dup(&copy, channel_));
4✔
1779

1780
    HostResult result;
8✔
1781
    ares_gethostbyname(copy, "www.google.com.", AF_INET, HostCallback, &result);
4✔
1782

1783
    ProcessAltChannel(copy);
4✔
1784

1785
    EXPECT_TRUE(result.done_);
4✔
1786
    ares_destroy(copy);
4✔
1787
    EXPECT_NE((size_t)0, count);
4✔
1788
    EXPECT_EQ(ARES_SUCCESS, result.status_);
4✔
1789
    EXPECT_EQ(0, result.timeouts_);
4✔
1790
  }
1791

1792
}
4✔
1793

1794
static const unsigned char *
1795
  fetch_server_cookie(const ares_dns_record_t *dnsrec, size_t *len)
2✔
1796
{
1797
  const ares_dns_rr_t *rr  = fetch_rr_opt(dnsrec);
2✔
1798
  const unsigned char *val = NULL;
2✔
1799
  *len                     = 0;
2✔
1800

1801
  if (rr == NULL) {
2✔
1802
    return NULL;
×
1803
  }
1804

1805
  if (!ares_dns_rr_get_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE,
2✔
1806
                                &val, len)) {
1807
    return NULL;
×
1808
  }
1809

1810
  if (*len <= 8) {
2✔
1811
    *len = 0;
×
1812
    return NULL;
×
1813
  }
1814

1815
  *len -= 8;
2✔
1816
  val  += 8;
2✔
1817
  return val;
2✔
1818
}
1819

1820
static const unsigned char *
1821
  fetch_client_cookie(const ares_dns_record_t *dnsrec, size_t *len)
8✔
1822
{
1823
  const ares_dns_rr_t *rr  = fetch_rr_opt(dnsrec);
8✔
1824
  const unsigned char *val = NULL;
8✔
1825
  *len                     = 0;
8✔
1826

1827
  if (rr == NULL) {
8✔
1828
    return NULL;
×
1829
  }
1830

1831
  if (!ares_dns_rr_get_opt_byid(rr, ARES_RR_OPT_OPTIONS, ARES_OPT_PARAM_COOKIE,
8✔
1832
                                &val, len)) {
1833
    return NULL;
×
1834
  }
1835

1836
  if (*len < 8) {
8✔
1837
    *len = 0;
×
1838
    return NULL;
×
1839
  }
1840

1841
  *len = 8;
8✔
1842
  return val;
8✔
1843
}
1844

1845
TEST_P(MockUDPChannelTest, DNSCookieSingle) {
2✔
1846
  DNSPacket reply;
2✔
1847
  std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2✔
1848
  reply.set_response().set_aa()
2✔
1849
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1850
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1851
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, false));
2✔
1852
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
1853
    .WillOnce(SetReply(&server_, &reply));
2✔
1854

1855
  QueryResult result;
2✔
1856
  ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result, NULL);
2✔
1857
  Process();
2✔
1858
  EXPECT_TRUE(result.done_);
2✔
1859
  EXPECT_EQ(0, result.timeouts_);
2✔
1860

1861
  size_t len;
1862
  const unsigned char *returned_cookie = fetch_server_cookie(result.dnsrec_.dnsrec_, &len);
2✔
1863
  EXPECT_EQ(len, server_cookie.size());
2✔
1864
  EXPECT_TRUE(memcmp(server_cookie.data(), returned_cookie, len) == 0);
2✔
1865
}
2✔
1866

1867
TEST_P(MockUDPChannelTest, DNSCookieMissingAfterGood) {
2✔
1868
  std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2✔
1869
  DNSPacket reply;
2✔
1870
  reply.set_response().set_aa()
2✔
1871
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1872
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1873
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, false));
2✔
1874
  DNSPacket reply_nocookie;
2✔
1875
  reply_nocookie.set_response().set_aa()
2✔
1876
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1877
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1878
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, { }, false));
2✔
1879
  DNSPacket reply_ensurecookie;
2✔
1880
  reply_ensurecookie.set_response().set_aa()
2✔
1881
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1882
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1883
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, true));
2✔
1884

1885
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
1886
    .WillOnce(SetReply(&server_, &reply))
4✔
1887
    .WillOnce(SetReply(&server_, &reply_nocookie))
4✔
1888
    .WillOnce(SetReply(&server_, &reply_ensurecookie));
2✔
1889

1890
  /* This test will establish the server supports cookies, then the next reply
1891
   * will be missing the server cookie and therefore be rejected and timeout, then
1892
   * an internal retry will occur and the cookie will be present again and it
1893
   * will be verified a server cookie was actually present that matches the
1894
   * server cookie. */
1895
  QueryResult result1;
2✔
1896
  ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result1, NULL);
2✔
1897
  Process();
2✔
1898
  EXPECT_TRUE(result1.done_);
2✔
1899
  EXPECT_EQ(0, result1.timeouts_);
2✔
1900

1901
  QueryResult result2;
4✔
1902
  ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result2, NULL);
2✔
1903
  Process();
2✔
1904
  EXPECT_TRUE(result2.done_);
2✔
1905
  EXPECT_EQ(1, result2.timeouts_);
2✔
1906

1907
  /* Client cookie should NOT have rotated */
1908
  size_t len1;
1909
  const unsigned char *client_cookie_1 = fetch_client_cookie(result1.dnsrec_.dnsrec_, &len1);
2✔
1910
  size_t len2;
1911
  const unsigned char *client_cookie_2 = fetch_client_cookie(result2.dnsrec_.dnsrec_, &len2);
2✔
1912
  EXPECT_EQ(len1, 8);
2✔
1913
  EXPECT_EQ(len1, len2);
2✔
1914
  EXPECT_TRUE(memcmp(client_cookie_1, client_cookie_2, len1) == 0);
2✔
1915
}
2✔
1916

1917

1918
TEST_P(MockUDPChannelTest, DNSCookieBadLen) {
2✔
1919
  std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2✔
1920
  std::vector<byte> server_cookie_bad = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0 };
2✔
1921
  DNSPacket reply;
2✔
1922
  reply.set_response().set_aa()
2✔
1923
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1924
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1925
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, false));
2✔
1926
  DNSPacket reply_badcookielen;
2✔
1927
  reply_badcookielen.set_response().set_aa()
2✔
1928
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1929
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1930
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie_bad, false));
2✔
1931

1932
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
1933
    .WillOnce(SetReply(&server_, &reply_badcookielen))
4✔
1934
    .WillOnce(SetReply(&server_, &reply));
2✔
1935

1936
  /* This test will send back a malformed cookie len, then when it times out and retry occurs will send back a valid cookie. */
1937
  QueryResult result1;
2✔
1938
  ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result1, NULL);
2✔
1939
  Process();
2✔
1940
  EXPECT_TRUE(result1.done_);
2✔
1941
  EXPECT_EQ(1, result1.timeouts_);
2✔
1942
}
2✔
1943

1944

1945
TEST_P(MockUDPChannelTest, DNSCookieServerRotate) {
2✔
1946
  std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2✔
1947
  std::vector<byte> server_cookie_rotate = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
2✔
1948

1949
  DNSPacket reply_cookie1;
2✔
1950
  reply_cookie1.set_response().set_aa()
2✔
1951
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1952
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1953
    .add_additional(new DNSOptRR(0, 0, 0, 1280, {}, server_cookie, false));
2✔
1954
  DNSPacket reply_cookie2_badcookie;
2✔
1955
  reply_cookie2_badcookie.set_response().set_aa().set_rcode(ARES_RCODE_BADCOOKIE & 0xF)
2✔
1956
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1957
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1958
    .add_additional(new DNSOptRR((ARES_RCODE_BADCOOKIE >> 4) & 0xFF, 0, 0, 1280, { }, server_cookie_rotate, false));
2✔
1959
  DNSPacket reply_cookie2;
2✔
1960
  reply_cookie2.set_response().set_aa()
2✔
1961
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
1962
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
1963
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie_rotate, true));
2✔
1964

1965
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
1966
    .WillOnce(SetReply(&server_, &reply_cookie1))
4✔
1967
    .WillOnce(SetReply(&server_, &reply_cookie2_badcookie))
4✔
1968
    .WillOnce(SetReply(&server_, &reply_cookie2));
2✔
1969

1970
  /* This test will establish the server supports cookies, then the next reply
1971
   * the server returns BADCOOKIE indicating the cookie has rotated and
1972
   * returns a new cookie. Then the query will be automatically retried with
1973
   * the newly returned cookie. No timeouts should be indicated, and the
1974
   * client cookie should not rotate. */
1975
  QueryResult result1;
2✔
1976
  ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result1, NULL);
2✔
1977
  Process();
2✔
1978
  EXPECT_TRUE(result1.done_);
2✔
1979
  EXPECT_EQ(0, result1.timeouts_);
2✔
1980

1981
  QueryResult result2;
4✔
1982
  ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result2, NULL);
2✔
1983
  Process();
2✔
1984
  EXPECT_TRUE(result2.done_);
2✔
1985
  EXPECT_EQ(0, result2.timeouts_);
2✔
1986

1987
  /* Client cookie should NOT have rotated */
1988
  size_t len1;
1989
  const unsigned char *client_cookie_1 = fetch_client_cookie(result1.dnsrec_.dnsrec_, &len1);
2✔
1990
  size_t len2;
1991
  const unsigned char *client_cookie_2 = fetch_client_cookie(result2.dnsrec_.dnsrec_, &len2);
2✔
1992
  EXPECT_EQ(len1, 8);
2✔
1993
  EXPECT_EQ(len1, len2);
2✔
1994
  EXPECT_TRUE(memcmp(client_cookie_1, client_cookie_2, len1) == 0);
2✔
1995
}
2✔
1996

1997
TEST_P(MockUDPChannelTest, DNSCookieSpoof) {
2✔
1998
  std::vector<byte> client_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2✔
1999
  std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2✔
2000

2001
  DNSPacket reply_spoof;
2✔
2002
  reply_spoof.set_response().set_aa()
2✔
2003
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
2004
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
2005
    .add_additional(new DNSOptRR(0, 0, 0, 1280, client_cookie, server_cookie, false));
2✔
2006
  DNSPacket reply;
2✔
2007
  reply.set_response().set_aa()
2✔
2008
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
2009
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
2010
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, server_cookie, false));
2✔
2011

2012
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
2013
    .WillOnce(SetReply(&server_, &reply_spoof))
4✔
2014
    .WillOnce(SetReply(&server_, &reply));
2✔
2015

2016
  /* This test will return a reply that doesn't have the same client cookie as
2017
   * was sent, this should result in a drop of the packet alltogether, then
2018
   * the library will retry and a proper result will be sent. */
2019
  QueryResult result;
2✔
2020
  ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result, NULL);
2✔
2021
  Process();
2✔
2022
  EXPECT_TRUE(result.done_);
2✔
2023
  EXPECT_EQ(1, result.timeouts_);
2✔
2024
}
2✔
2025

2026
TEST_P(MockUDPChannelTest, DNSCookieTCPUpgrade) {
2✔
2027
  std::vector<byte> server_cookie = { 1, 2, 3, 4, 5, 6, 7, 8 };
2✔
2028

2029
  DNSPacket reply_badcookie;
2✔
2030
  reply_badcookie.set_response().set_aa().set_rcode(ARES_RCODE_BADCOOKIE & 0xF)
2✔
2031
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
2032
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
2033
    .add_additional(new DNSOptRR((ARES_RCODE_BADCOOKIE >> 4) & 0xFF, 0, 0, 1280, { }, server_cookie, false));
2✔
2034
  DNSPacket reply;
2✔
2035
  reply.set_response().set_aa()
2✔
2036
    .add_question(new DNSQuestion("www.google.com", T_A))
4✔
2037
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}))
4✔
2038
    .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, { }, false));
2✔
2039

2040
  EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
4✔
2041
    .WillOnce(SetReply(&server_, &reply_badcookie))
4✔
2042
    .WillOnce(SetReply(&server_, &reply_badcookie))
4✔
2043
    .WillOnce(SetReply(&server_, &reply_badcookie))
4✔
2044
    .WillOnce(SetReply(&server_, &reply));
2✔
2045

2046
  /* This test will establish the server supports cookies, but continuously
2047
   * returns BADCOOKIE which is an indicator that there is some form of
2048
   * AnyCast issue across servers, so it upgrades to TCP afterwards.  No
2049
   * timeouts are recorded as the queries are sent back-to-back as immediate
2050
   * reattempts after the response. */
2051
  QueryResult result;
2✔
2052
  ares_query_dnsrec(channel_, "www.google.com", ARES_CLASS_IN, ARES_REC_TYPE_A, QueryCallback, &result, NULL);
2✔
2053
  Process();
2✔
2054
  EXPECT_TRUE(result.done_);
2✔
2055
  EXPECT_EQ(0, result.timeouts_);
2✔
2056
}
2✔
2057

2058

2059
#ifndef WIN32
2060
TEST_P(MockChannelTest, HostAlias) {
4✔
2061
  DNSPacket reply;
4✔
2062
  reply.set_response().set_aa()
4✔
2063
    .add_question(new DNSQuestion("www.google.com", T_A))
8✔
2064
    .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
4✔
2065
  ON_CALL(server_, OnRequest("www.google.com", T_A))
8✔
2066
    .WillByDefault(SetReply(&server_, &reply));
4✔
2067

2068
  TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
8✔
2069
  EnvValue with_env("HOSTALIASES", aliases.filename());
4✔
2070

2071
  HostResult result;
4✔
2072
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
2073
  Process();
4✔
2074
  EXPECT_TRUE(result.done_);
4✔
2075
  std::stringstream ss;
8✔
2076
  ss << result.host_;
4✔
2077
  EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
8✔
2078
}
4✔
2079

2080
TEST_P(MockChannelTest, HostAliasMissing) {
4✔
2081
  DNSPacket yesfirst;
4✔
2082
  yesfirst.set_response().set_aa()
4✔
2083
    .add_question(new DNSQuestion("www.first.com", T_A))
8✔
2084
    .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
4✔
2085
  ON_CALL(server_, OnRequest("www.first.com", T_A))
8✔
2086
    .WillByDefault(SetReply(&server_, &yesfirst));
4✔
2087

2088
  TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
8✔
2089
  EnvValue with_env("HOSTALIASES", aliases.filename());
4✔
2090
  HostResult result;
4✔
2091
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
2092
  Process();
4✔
2093
  EXPECT_TRUE(result.done_);
4✔
2094
  std::stringstream ss;
8✔
2095
  ss << result.host_;
4✔
2096
  EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
2097
}
4✔
2098

2099
TEST_P(MockChannelTest, HostAliasMissingFile) {
4✔
2100
  DNSPacket yesfirst;
4✔
2101
  yesfirst.set_response().set_aa()
4✔
2102
    .add_question(new DNSQuestion("www.first.com", T_A))
8✔
2103
    .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
4✔
2104
  ON_CALL(server_, OnRequest("www.first.com", T_A))
8✔
2105
    .WillByDefault(SetReply(&server_, &yesfirst));
4✔
2106

2107
  EnvValue with_env("HOSTALIASES", "bogus.mcfile");
4✔
2108
  HostResult result;
4✔
2109
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
4✔
2110
  Process();
4✔
2111
  EXPECT_TRUE(result.done_);
4✔
2112
  std::stringstream ss;
8✔
2113
  ss << result.host_;
4✔
2114
  EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
8✔
2115
}
4✔
2116

2117
TEST_P(MockChannelTest, HostAliasUnreadable) {
4✔
2118
  TempFile aliases("www www.google.com\n");
8✔
2119
  EXPECT_EQ(chmod(aliases.filename(), 0), 0);
4✔
2120

2121
  /* Perform OS sanity checks.  We are observing on Debian after the chmod(fn, 0)
2122
   * that we are still able to fopen() the file which is unexpected.  Skip the
2123
   * test if we observe this behavior */
2124
  struct stat st;
2125
  EXPECT_EQ(stat(aliases.filename(), &st), 0);
4✔
2126
  EXPECT_EQ(st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO), 0);
4✔
2127
  FILE *fp = fopen(aliases.filename(), "r");
4✔
2128
  if (fp != NULL) {
4✔
2129
    if (verbose) std::cerr << "Skipping Test due to OS incompatibility (open file caching)" << std::endl;
4✔
2130
    fclose(fp);
4✔
2131
    return;
4✔
2132
  }
2133

2134
  EnvValue with_env("HOSTALIASES", aliases.filename());
×
2135

2136
  HostResult result;
×
2137
  ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
×
2138
  Process();
×
2139
  EXPECT_TRUE(result.done_);
×
2140
  EXPECT_EQ(ARES_EFILE, result.status_);
×
2141
  chmod(aliases.filename(), 0777);
×
2142
}
4✔
2143
#endif
2144

2145
class MockMultiServerChannelTest
2146
  : public MockChannelOptsTest,
2147
    public ::testing::WithParamInterface< std::pair<int, bool> > {
2148
 public:
2149
  MockMultiServerChannelTest(ares_options *opts, int optmask)
8✔
2150
    : MockChannelOptsTest(3, GetParam().first, GetParam().second, false, opts, optmask) {}
8✔
2151
  void CheckExample() {
12✔
2152
    HostResult result;
12✔
2153
    ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
12✔
2154
    Process();
12✔
2155
    EXPECT_TRUE(result.done_);
12✔
2156
    std::stringstream ss;
24✔
2157
    ss << result.host_;
12✔
2158
    EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
24✔
2159
  }
12✔
2160
};
2161

2162
class NoRotateMultiMockTest : public MockMultiServerChannelTest {
2163
 public:
2164
  NoRotateMultiMockTest() : MockMultiServerChannelTest(nullptr, ARES_OPT_NOROTATE) {}
8✔
2165
};
2166

2167

2168
TEST_P(NoRotateMultiMockTest, ThirdServer) {
4✔
2169
  struct ares_options opts;
2170
  int optmask = 0;
4✔
2171
  memset(&opts, 0, sizeof(opts));
4✔
2172
  EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
4✔
2173
  EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
4✔
2174
  ares_destroy_options(&opts);
4✔
2175

2176
  DNSPacket servfailrsp;
8✔
2177
  servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
4✔
2178
    .add_question(new DNSQuestion("www.example.com", T_A));
4✔
2179
  DNSPacket notimplrsp;
8✔
2180
  notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
4✔
2181
    .add_question(new DNSQuestion("www.example.com", T_A));
4✔
2182
  DNSPacket okrsp;
8✔
2183
  okrsp.set_response().set_aa()
4✔
2184
    .add_question(new DNSQuestion("www.example.com", T_A))
8✔
2185
    .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
4✔
2186

2187
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2188
    .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
4✔
2189
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2190
    .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
4✔
2191
  EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
8✔
2192
    .WillOnce(SetReply(servers_[2].get(), &okrsp));
4✔
2193
  CheckExample();
4✔
2194

2195
  // Second time around, still starts from server [2], as [0] and [1] both
2196
  // recorded failures
2197
  EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
8✔
2198
    .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
4✔
2199
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2200
    .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
4✔
2201
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2202
    .WillOnce(SetReply(servers_[1].get(), &okrsp));
4✔
2203
  CheckExample();
4✔
2204

2205
  // Third time around, server order is [1] (f0), [2] (f1), [0] (f2), which
2206
  // means [1] will get called twice in a row as after the first call
2207
  // order will be  [1] (f1), [2] (f1), [0] (f2) since sort order is
2208
  // (failure count, index)
2209
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2210
    .WillOnce(SetReply(servers_[1].get(), &servfailrsp))
8✔
2211
    .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
4✔
2212
  EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
8✔
2213
    .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
4✔
2214
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2215
    .WillOnce(SetReply(servers_[0].get(), &okrsp));
4✔
2216
  CheckExample();
4✔
2217
}
4✔
2218

2219
TEST_P(NoRotateMultiMockTest, ServerNoResponseFailover) {
4✔
2220
  std::vector<byte> nothing;
4✔
2221
  DNSPacket okrsp;
4✔
2222
  okrsp.set_response().set_aa()
4✔
2223
    .add_question(new DNSQuestion("www.example.com", T_A))
8✔
2224
    .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
4✔
2225

2226
  /* Server #1 works fine on first attempt, then acts like its offline on
2227
   * second, then backonline on the third. */
2228
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2229
    .WillOnce(SetReply(servers_[0].get(), &okrsp))
8✔
2230
    .WillOnce(SetReplyData(servers_[0].get(), nothing))
8✔
2231
    .WillOnce(SetReply(servers_[0].get(), &okrsp));
4✔
2232

2233
  /* Server #2 always acts like its offline */
2234
  ON_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2235
    .WillByDefault(SetReplyData(servers_[1].get(), nothing));
4✔
2236

2237
  /* Server #3 works fine on first and second request, then no reply on 3rd */
2238
  EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
8✔
2239
    .WillOnce(SetReply(servers_[2].get(), &okrsp))
8✔
2240
    .WillOnce(SetReply(servers_[2].get(), &okrsp))
8✔
2241
    .WillOnce(SetReplyData(servers_[2].get(), nothing));
4✔
2242

2243
  HostResult result;
4✔
2244

2245
  /* 1. First server returns a response on the first request immediately, normal
2246
   *    operation on channel. */
2247
  ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
4✔
2248
  Process();
4✔
2249
  EXPECT_TRUE(result.done_);
4✔
2250
  EXPECT_EQ(0, result.timeouts_);
4✔
2251
  std::stringstream ss1;
8✔
2252
  ss1 << result.host_;
4✔
2253
  EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
8✔
2254

2255
  /* 2. On the second request, simulate the first and second servers not
2256
   *    returning a response at all, but the 3rd server works, so should have
2257
   *    2 timeouts. */
2258
  ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
4✔
2259
  Process();
4✔
2260
  EXPECT_TRUE(result.done_);
4✔
2261
  EXPECT_EQ(2, result.timeouts_);
4✔
2262
  std::stringstream ss2;
8✔
2263
  ss2 << result.host_;
4✔
2264
  EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss2.str());
8✔
2265

2266
  /* 3. On the third request, the active server should be #3, so should respond
2267
   *    immediately with no timeouts */
2268
  ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
4✔
2269
  Process();
4✔
2270
  EXPECT_TRUE(result.done_);
4✔
2271
  EXPECT_EQ(0, result.timeouts_);
4✔
2272
  std::stringstream ss3;
8✔
2273
  ss3 << result.host_;
4✔
2274
  EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
8✔
2275

2276
  /* 4. On the fourth request, the active server should be #3, but will timeout,
2277
   *    and the first server should then respond */
2278
  ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
4✔
2279
  Process();
4✔
2280
  EXPECT_TRUE(result.done_);
4✔
2281
  EXPECT_EQ(1, result.timeouts_);
4✔
2282
  std::stringstream ss4;
8✔
2283
  ss4 << result.host_;
4✔
2284
  EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss4.str());
8✔
2285
}
4✔
2286

2287
#if defined(_WIN32)
2288
#  define SERVER_FAILOVER_RETRY_DELAY 500
2289
#else
2290
#  define SERVER_FAILOVER_RETRY_DELAY 330
2291
#endif
2292

2293
class ServerFailoverOptsMultiMockTest
2294
  : public MockChannelOptsTest,
2295
    public ::testing::WithParamInterface< std::pair<int, bool> > {
2296
 public:
2297
  ServerFailoverOptsMultiMockTest()
4✔
2298
    : MockChannelOptsTest(4, GetParam().first, GetParam().second, false,
4✔
2299
                          FillOptions(&opts_),
2300
                          ARES_OPT_SERVER_FAILOVER | ARES_OPT_NOROTATE) {}
8✔
2301
  void CheckExample() {
32✔
2302
    HostResult result;
32✔
2303
    ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
32✔
2304
    Process();
32✔
2305
    EXPECT_TRUE(result.done_);
32✔
2306
    std::stringstream ss;
64✔
2307
    ss << result.host_;
32✔
2308
    EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
64✔
2309
  }
32✔
2310

2311
  static struct ares_options* FillOptions(struct ares_options *opts) {
4✔
2312
    memset(opts, 0, sizeof(struct ares_options));
4✔
2313
    opts->server_failover_opts.retry_chance = 1;
4✔
2314
    opts->server_failover_opts.retry_delay = SERVER_FAILOVER_RETRY_DELAY;
4✔
2315
    return opts;
4✔
2316
  }
2317
 private:
2318
  struct ares_options opts_;
2319
};
2320

2321

2322
// Test case to trigger server failover behavior. We use a retry chance of
2323
// 100% and a retry delay so that we can test behavior reliably.
2324
TEST_P(ServerFailoverOptsMultiMockTest, ServerFailoverOpts) {
4✔
2325
 DNSPacket servfailrsp;
4✔
2326
  servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
4✔
2327
    .add_question(new DNSQuestion("www.example.com", T_A));
4✔
2328
  DNSPacket okrsp;
4✔
2329
  okrsp.set_response().set_aa()
4✔
2330
    .add_question(new DNSQuestion("www.example.com", T_A))
8✔
2331
    .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
4✔
2332

2333
  auto tv_begin = std::chrono::high_resolution_clock::now();
4✔
2334
  auto tv_now   = std::chrono::high_resolution_clock::now();
4✔
2335
  unsigned int delay_ms;
2336

2337
  // At start all servers are healthy, first server should be selected
2338
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: First server should be selected" << std::endl;
4✔
2339
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2340
    .WillOnce(SetReply(servers_[0].get(), &okrsp));
4✔
2341
  CheckExample();
4✔
2342

2343
  // Fail server #0 but leave server #1 as healthy.  This results in server
2344
  // order:
2345
  //  #1 (failures: 0), #2 (failures: 0), #3 (failures: 0), #0 (failures: 1)
2346
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2347
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Server0 will fail but leave Server1 as healthy" << std::endl;
4✔
2348
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2349
    .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
4✔
2350
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2351
    .WillOnce(SetReply(servers_[1].get(), &okrsp));
4✔
2352
  CheckExample();
4✔
2353

2354
  // Sleep for the retry delay (actually a little more than the retry delay to account
2355
  // for unreliable timing, e.g. NTP slew) and send in another query. The real
2356
  // query will be sent to Server #1 (which will succeed) and Server #0 will
2357
  // be probed and return a successful result.  This leaves the server order
2358
  // of:
2359
  //   #0 (failures: 0), #1 (failures: 0), #2 (failures: 0), #3 (failures: 0)
2360
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2361
  delay_ms = SERVER_FAILOVER_RETRY_DELAY + (SERVER_FAILOVER_RETRY_DELAY / 10);
4✔
2362
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
4✔
2363
  ares_sleep_time(delay_ms);
4✔
2364
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2365
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Server0 should be past retry delay and should be probed (successful), server 1 will respond successful for real query" << std::endl;
4✔
2366
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2367
    .WillOnce(SetReply(servers_[0].get(), &okrsp));
4✔
2368
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2369
    .WillOnce(SetReply(servers_[1].get(), &okrsp));
4✔
2370
  CheckExample();
4✔
2371

2372

2373
  // Fail all servers for the first round of tries. On the second round, #0
2374
  // responds successfully. This should leave server order of:
2375
  //   #1 (failures: 0), #2 (failures: 1), #3 (failures: 1), #0 (failures: 2)
2376
  // NOTE: A single query being retried won't spawn probes to downed servers,
2377
  //       only an initial query attempt is eligible to spawn probes.  So
2378
  //       no probes are sent for this test.
2379
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2380
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: All 4 servers will fail on the first attempt, server 0 will fail on second. Server 1 will succeed on second." << std::endl;
4✔
2381
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2382
    .WillOnce(SetReply(servers_[0].get(), &servfailrsp))
8✔
2383
    .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
4✔
2384
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2385
    .WillOnce(SetReply(servers_[1].get(), &servfailrsp))
8✔
2386
    .WillOnce(SetReply(servers_[1].get(), &okrsp));
4✔
2387
  EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
8✔
2388
    .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
4✔
2389
  EXPECT_CALL(*servers_[3], OnRequest("www.example.com", T_A))
8✔
2390
    .WillOnce(SetReply(servers_[3].get(), &servfailrsp));
4✔
2391
  CheckExample();
4✔
2392

2393

2394
  // Sleep for the retry delay and send in another query. Server #1 is the
2395
  // highest priority server and will respond with success, however a probe
2396
  // will be sent for Server #2 which will succeed:
2397
  //  #1 (failures: 0), #2 (failures: 0), #3 (failures: 1 - expired), #0 (failures: 2 - expired)
2398
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2399
  delay_ms = SERVER_FAILOVER_RETRY_DELAY + (SERVER_FAILOVER_RETRY_DELAY / 10);
4✔
2400
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
4✔
2401
  ares_sleep_time(delay_ms);
4✔
2402
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2403
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Past retry delay, will query Server 1 and probe Server 2, both will succeed." << std::endl;
4✔
2404
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2405
    .WillOnce(SetReply(servers_[1].get(), &okrsp));
4✔
2406
  EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
8✔
2407
    .WillOnce(SetReply(servers_[2].get(), &okrsp));
4✔
2408
  CheckExample();
4✔
2409

2410
  // Cause another server to fail so we have at least one non-expired failed
2411
  // server and one expired failed server.  #1 is highest priority, which we
2412
  // will fail, #2 will succeed, and #3 will be probed and succeed:
2413
  //  #2 (failures: 0), #3 (failures: 0), #1 (failures: 1 not expired), #0 (failures: 2 expired)
2414
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2415
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Will query Server 1 and fail, Server 2 will answer successfully. Server 3 will be probed and succeed." << std::endl;
4✔
2416
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2417
    .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
4✔
2418
  EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
8✔
2419
    .WillOnce(SetReply(servers_[2].get(), &okrsp));
4✔
2420
  EXPECT_CALL(*servers_[3], OnRequest("www.example.com", T_A))
8✔
2421
    .WillOnce(SetReply(servers_[3].get(), &okrsp));
4✔
2422
  CheckExample();
4✔
2423

2424
  // We need to make sure that if there is a failed server that is higher priority
2425
  // but not yet expired that it will probe the next failed server instead.
2426
  // In this case #2 is the server that the query will go to and succeed, and
2427
  // then a probe will be sent for #0 (since #1 is not expired) and succeed.  We
2428
  // will sleep for 1/4 the retry duration before spawning the queries so we can
2429
  // then sleep for the rest for the follow-up test.  This will leave the servers
2430
  // in this state:
2431
  //   #0 (failures: 0), #2 (failures: 0), #3 (failures: 0), #1 (failures: 1 not expired)
2432
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2433

2434
  // We need to track retry delay time to know what is expired when.
2435
  auto elapse_start = tv_now;
4✔
2436

2437
  delay_ms = (SERVER_FAILOVER_RETRY_DELAY/4);
4✔
2438
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
4✔
2439
  ares_sleep_time(delay_ms);
4✔
2440
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2441

2442
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Retry delay has not been hit yet. Server2 will be queried and succeed. Server 0 (not server 1 due to non-expired retry delay) will be probed and succeed." << std::endl;
4✔
2443
  EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
8✔
2444
    .WillOnce(SetReply(servers_[2].get(), &okrsp));
4✔
2445
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2446
    .WillOnce(SetReply(servers_[0].get(), &okrsp));
4✔
2447
  CheckExample();
4✔
2448

2449
  // Finally we sleep for the remainder of the retry delay, send another
2450
  // query, which should succeed on Server #0, and also probe Server #1 which
2451
  // will also succeed.
2452
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2453

2454
  unsigned int elapsed_time = (unsigned int)std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - elapse_start).count();
4✔
2455
  delay_ms = (SERVER_FAILOVER_RETRY_DELAY) + (SERVER_FAILOVER_RETRY_DELAY / 10);
4✔
2456
  if (elapsed_time > delay_ms) {
4✔
2457
    if (verbose) std::cerr << "elapsed duration " << elapsed_time << "ms greater than desired delay of " << delay_ms << "ms, not sleeping" << std::endl;
×
2458
  } else {
2459
    delay_ms -= elapsed_time; // subtract already elapsed time
4✔
2460
    if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
4✔
2461
    ares_sleep_time(delay_ms);
4✔
2462
  }
2463
  tv_now = std::chrono::high_resolution_clock::now();
4✔
2464
  if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Retry delay has expired on Server1, Server 0 will be queried and succeed, Server 1 will be probed and succeed." << std::endl;
4✔
2465
  EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
8✔
2466
    .WillOnce(SetReply(servers_[0].get(), &okrsp));
4✔
2467
  EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
8✔
2468
    .WillOnce(SetReply(servers_[1].get(), &okrsp));
4✔
2469
  CheckExample();
4✔
2470
}
4✔
2471

2472
const char *af_tostr(int af)
910✔
2473
{
2474
  switch (af) {
910✔
2475
    case AF_INET:
455✔
2476
      return "ipv4";
455✔
2477
    case AF_INET6:
455✔
2478
      return "ipv6";
455✔
2479
  }
2480
  return "ipunknown";
×
2481
}
2482

2483
const char *mode_tostr(bool mode)
744✔
2484
{
2485
  return mode?"ForceTCP":"DefaultUDP";
744✔
2486
}
2487

2488
std::string PrintFamilyMode(const testing::TestParamInfo<std::pair<int, bool>> &info)
312✔
2489
{
2490
  std::string name;
312✔
2491

2492
  name += af_tostr(std::get<0>(info.param));
312✔
2493
  name += "_";
312✔
2494
  name += mode_tostr(std::get<1>(info.param));
312✔
2495
  return name;
312✔
2496
}
×
2497

2498
std::string PrintFamily(const testing::TestParamInfo<int> &info)
76✔
2499
{
2500
  std::string name;
76✔
2501

2502
  name += af_tostr(info.param);
76✔
2503
  return name;
76✔
2504
}
×
2505

2506
INSTANTIATE_TEST_SUITE_P(AddressFamilies, NoDNS0x20MockTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
1✔
2507

2508
INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockChannelTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
37✔
2509

2510
#ifdef HAVE_CONTAINER
2511
INSTANTIATE_TEST_SUITE_P(AddressFamilies, ContainedMockChannelSysConfig, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2✔
2512
#endif
2513

2514
INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
16✔
2515

2516
INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPMaxQueriesTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
1✔
2517

2518
INSTANTIATE_TEST_SUITE_P(AddressFamilies, CacheQueriesTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
3✔
2519

2520
INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockTCPChannelTest, ::testing::ValuesIn(ares::test::families), PrintFamily);
9✔
2521

2522
INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockExtraOptsTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1✔
2523

2524
INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockNoCheckRespChannelTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
3✔
2525

2526
INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockEDNSChannelTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1✔
2527

2528
INSTANTIATE_TEST_SUITE_P(TransportModes, NoRotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
2✔
2529

2530
INSTANTIATE_TEST_SUITE_P(TransportModes, ServerFailoverOptsMultiMockTest, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
1✔
2531

2532
}  // namespace test
2533
}  // namespace ares
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc