• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_setup.h"
27 #include "ares.h"
28 #include "ares_nameser.h"
29 #include "ares-test.h"
30 #include "ares-test-ai.h"
31 #include "dns-proto.h"
32 #include "ares_dns.h"
33 
34 extern "C" {
35 // Remove command-line defines of package variables for the test project...
36 #undef PACKAGE_NAME
37 #undef PACKAGE_BUGREPORT
38 #undef PACKAGE_STRING
39 #undef PACKAGE_TARNAME
40 // ... so we can include the library's config without symbol redefinitions.
41 #include "ares_setup.h"
42 #include "ares_inet_net_pton.h"
43 #include "ares_data.h"
44 #include "str/ares_strsplit.h"
45 #include "ares_private.h"
46 }
47 
48 
49 #ifdef HAVE_NETDB_H
50 #include <netdb.h>
51 #endif
52 #ifdef HAVE_NETINET_TCP_H
53 #include <netinet/tcp.h>
54 #endif
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 
59 #include <functional>
60 #include <sstream>
61 #include <algorithm>
62 #include <chrono>
63 
64 #ifdef WIN32
65 #define BYTE_CAST (char *)
66 #define mkdir_(d, p) mkdir(d)
67 #else
68 #define BYTE_CAST
69 #define mkdir_(d, p) mkdir(d, p)
70 #endif
71 
72 namespace ares {
73 namespace test {
74 
75 bool verbose = false;
76 static constexpr unsigned short dynamic_port = 0;
77 unsigned short mock_port = dynamic_port;
78 
79 const std::vector<int> both_families = {AF_INET, AF_INET6};
80 const std::vector<int> ipv4_family = {AF_INET};
81 const std::vector<int> ipv6_family = {AF_INET6};
82 
83 const std::vector<std::pair<int, bool>> both_families_both_modes = {
84   std::make_pair<int, bool>(AF_INET, false),
85   std::make_pair<int, bool>(AF_INET, true),
86   std::make_pair<int, bool>(AF_INET6, false),
87   std::make_pair<int, bool>(AF_INET6, true)
88 };
89 const std::vector<std::pair<int, bool>> ipv4_family_both_modes = {
90   std::make_pair<int, bool>(AF_INET, false),
91   std::make_pair<int, bool>(AF_INET, true)
92 };
93 const std::vector<std::pair<int, bool>> ipv6_family_both_modes = {
94   std::make_pair<int, bool>(AF_INET6, false),
95   std::make_pair<int, bool>(AF_INET6, true)
96 };
97 
98 
99 const std::vector<std::tuple<ares_evsys_t, int, bool>> all_evsys_ipv4_family_both_modes = {
100 #ifdef _WIN32
101   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_WIN32, AF_INET, false),
102   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_WIN32, AF_INET, true),
103 #endif
104 #ifdef HAVE_KQUEUE
105   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_KQUEUE, AF_INET, false),
106   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_KQUEUE, AF_INET, true),
107 #endif
108 #ifdef HAVE_EPOLL
109   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_EPOLL, AF_INET, false),
110   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_EPOLL, AF_INET, true),
111 #endif
112 #ifdef HAVE_POLL
113   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_POLL, AF_INET, false),
114   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_POLL, AF_INET, true),
115 #endif
116 #ifdef HAVE_PIPE
117   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_SELECT, AF_INET, false),
118   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_SELECT, AF_INET, true),
119 #endif
120 };
121 
122 const std::vector<std::tuple<ares_evsys_t, int, bool>> all_evsys_ipv6_family_both_modes = {
123 #ifdef _WIN32
124   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_WIN32, AF_INET6, false),
125   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_WIN32, AF_INET6, true),
126 #endif
127 #ifdef HAVE_KQUEUE
128   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_KQUEUE, AF_INET6, false),
129   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_KQUEUE, AF_INET6, true),
130 #endif
131 #ifdef HAVE_EPOLL
132   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_EPOLL, AF_INET6, false),
133   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_EPOLL, AF_INET6, true),
134 #endif
135 #ifdef HAVE_POLL
136   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_POLL, AF_INET6, false),
137   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_POLL, AF_INET6, true),
138 #endif
139 #ifdef HAVE_PIPE
140   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_SELECT, AF_INET6, false),
141   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_SELECT, AF_INET6, true),
142 #endif
143 };
144 
145 const std::vector<std::tuple<ares_evsys_t, int, bool>> all_evsys_both_families_both_modes = {
146 #ifdef _WIN32
147   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_WIN32, AF_INET, false),
148   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_WIN32, AF_INET, true),
149   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_WIN32, AF_INET6, false),
150   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_WIN32, AF_INET6, true),
151 #endif
152 #ifdef HAVE_KQUEUE
153   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_KQUEUE, AF_INET, false),
154   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_KQUEUE, AF_INET, true),
155   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_KQUEUE, AF_INET6, false),
156   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_KQUEUE, AF_INET6, true),
157 #endif
158 #ifdef HAVE_EPOLL
159   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_EPOLL, AF_INET, false),
160   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_EPOLL, AF_INET, true),
161   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_EPOLL, AF_INET6, false),
162   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_EPOLL, AF_INET6, true),
163 #endif
164 #ifdef HAVE_POLL
165   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_POLL, AF_INET, false),
166   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_POLL, AF_INET, true),
167   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_POLL, AF_INET6, false),
168   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_POLL, AF_INET6, true),
169 #endif
170 #ifdef HAVE_PIPE
171   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_SELECT, AF_INET, false),
172   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_SELECT, AF_INET, true),
173   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_SELECT, AF_INET6, false),
174   std::make_tuple<ares_evsys_t, int, bool>(ARES_EVSYS_SELECT, AF_INET6, true),
175 #endif
176 };
177 
178 
179 std::vector<std::tuple<ares_evsys_t, int, bool>> evsys_families_modes = all_evsys_both_families_both_modes;
180 
181 
182 const std::vector<std::tuple<ares_evsys_t, int>> all_evsys_ipv4_family = {
183 #ifdef _WIN32
184   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_WIN32, AF_INET),
185 #endif
186 #ifdef HAVE_KQUEUE
187   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_KQUEUE, AF_INET),
188 #endif
189 #ifdef HAVE_EPOLL
190   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_EPOLL, AF_INET),
191 #endif
192 #ifdef HAVE_POLL
193   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_POLL, AF_INET),
194 #endif
195 #ifdef HAVE_PIPE
196   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_SELECT, AF_INET),
197 #endif
198 };
199 
200 const std::vector<std::tuple<ares_evsys_t, int>> all_evsys_ipv6_family = {
201 #ifdef _WIN32
202   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_WIN32, AF_INET6),
203 #endif
204 #ifdef HAVE_KQUEUE
205   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_KQUEUE, AF_INET6),
206 #endif
207 #ifdef HAVE_EPOLL
208   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_EPOLL, AF_INET6),
209 #endif
210 #ifdef HAVE_POLL
211   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_POLL, AF_INET6),
212 #endif
213 #ifdef HAVE_PIPE
214   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_SELECT, AF_INET6),
215 #endif
216 };
217 
218 const std::vector<std::tuple<ares_evsys_t, int>> all_evsys_both_families = {
219 #ifdef _WIN32
220   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_WIN32, AF_INET),
221   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_WIN32, AF_INET6),
222 #endif
223 #ifdef HAVE_KQUEUE
224   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_KQUEUE, AF_INET),
225   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_KQUEUE, AF_INET6),
226 #endif
227 #ifdef HAVE_EPOLL
228   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_EPOLL, AF_INET),
229   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_EPOLL, AF_INET6),
230 #endif
231 #ifdef HAVE_POLL
232   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_POLL, AF_INET),
233   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_POLL, AF_INET6),
234 #endif
235 #ifdef HAVE_PIPE
236   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_SELECT, AF_INET),
237   std::make_tuple<ares_evsys_t, int>(ARES_EVSYS_SELECT, AF_INET6),
238 #endif
239 };
240 
241 
242 
243 std::vector<std::tuple<ares_evsys_t, int>> evsys_families = all_evsys_both_families;
244 
245 
246 // Which parameters to use in tests
247 std::vector<int> families = both_families;
248 std::vector<std::pair<int, bool>> families_modes = both_families_both_modes;
249 
250 unsigned long long LibraryTest::fails_ = 0;
251 std::map<size_t, int> LibraryTest::size_fails_;
252 std::mutex            LibraryTest::lock_;
253 bool LibraryTest::failsend_ = false;
254 
ares_sleep_time(unsigned int ms)255 void ares_sleep_time(unsigned int ms)
256 {
257   auto duration   = std::chrono::milliseconds(ms);
258   auto start_time = std::chrono::high_resolution_clock::now();
259   auto wake_time  = start_time + duration;
260   std::this_thread::sleep_until(wake_time);
261   auto end_time   = std::chrono::high_resolution_clock::now();
262   if (verbose) std::cerr << "sleep requested " << ms << "ms, slept for " << std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count() << "ms" << std::endl;
263 }
264 
ProcessWork(ares_channel_t * channel,std::function<std::set<ares_socket_t> ()> get_extrafds,std::function<void (ares_socket_t)> process_extra,unsigned int cancel_ms)265 void ProcessWork(ares_channel_t *channel,
266                  std::function<std::set<ares_socket_t>()> get_extrafds,
267                  std::function<void(ares_socket_t)> process_extra,
268                  unsigned int cancel_ms) {
269   int nfds, count;
270   fd_set readers, writers;
271 
272   auto tv_begin = std::chrono::high_resolution_clock::now();
273   auto tv_cancel = tv_begin;
274 
275   if (cancel_ms) {
276     if (verbose) std::cerr << "ares_cancel will be called after " << cancel_ms << "ms" << std::endl;
277     tv_cancel += std::chrono::milliseconds(cancel_ms);
278   }
279 
280   while (true) {
281     struct timeval  tv;
282     struct timeval *tv_select;
283 
284     // Retrieve the set of file descriptors that the library wants us to monitor.
285     FD_ZERO(&readers);
286     FD_ZERO(&writers);
287     nfds = ares_fds(channel, &readers, &writers);
288     if (nfds == 0)  // no work left to do in the library
289       return;
290 
291     // Add in the extra FDs if present.
292     std::set<ares_socket_t> extrafds = get_extrafds();
293     for (ares_socket_t extrafd : extrafds) {
294       FD_SET(extrafd, &readers);
295       if (extrafd >= (ares_socket_t)nfds) {
296         nfds = (int)extrafd + 1;
297       }
298     }
299 
300     /* If ares_timeout returns NULL, it means there are no requests in queue,
301      * so we can break out */
302     tv_select = ares_timeout(channel, NULL, &tv);
303     if (tv_select == NULL)
304       return;
305 
306     if (cancel_ms) {
307       auto tv_now       = std::chrono::high_resolution_clock::now();
308       auto remaining_ms = std::chrono::duration_cast<std::chrono::milliseconds>(tv_cancel - tv_now).count();
309 
310       if (remaining_ms <= 0) {
311         if (verbose) std::cerr << "Issuing ares_cancel()" << std::endl;
312         ares_cancel(channel);
313         cancel_ms = 0; /* Disable issuing cancel again */
314       } else {
315         struct timeval tv_remaining;
316 
317         tv_remaining.tv_sec = remaining_ms / 1000;
318         tv_remaining.tv_usec = (int)(remaining_ms % 1000);
319 
320         /* Recalculate proper timeout since we also have a cancel to wait on */
321         tv_select = ares_timeout(channel, &tv_remaining, &tv);
322       }
323     }
324 
325     count = select(nfds, &readers, &writers, nullptr, tv_select);
326     if (count < 0) {
327       fprintf(stderr, "select() failed, errno %d\n", errno);
328       return;
329     }
330 
331     // Let the library process any activity.
332     ares_process(channel, &readers, &writers);
333 
334     // Let the provided callback process any activity on the extra FD.
335     for (ares_socket_t extrafd : extrafds) {
336       if (FD_ISSET(extrafd, &readers)) {
337         process_extra(extrafd);
338       }
339     }
340   }
341 }
342 
343 
SetFailSend()344 void LibraryTest::SetFailSend() {
345   failsend_ = true;
346 }
347 
348 // static
ares_sendv_fail(ares_socket_t socket,const struct iovec * vec,int len,void * user_data)349 ares_ssize_t LibraryTest::ares_sendv_fail(ares_socket_t socket, const struct iovec *vec, int len, void *user_data)
350 {
351   (void)user_data;
352 
353   if (failsend_) {
354 #ifdef USE_WINSOCK
355     WSASetLastError(WSAECONNREFUSED);
356 #else
357     errno = ECONNREFUSED;
358 #endif
359     failsend_ = false;
360     return -1;
361   }
362 
363   return send(socket, (const char *)vec[0].iov_base, vec[0].iov_len, 0);
364 }
365 
366 
SetAllocFail(int nth)367 void LibraryTest::SetAllocFail(int nth) {
368   lock_.lock();
369   assert(nth > 0);
370   assert(nth <= (int)(8 * sizeof(fails_)));
371   fails_ |= (1LL << (nth - 1));
372   lock_.unlock();
373 }
374 
375 // static
SetAllocSizeFail(size_t size)376 void LibraryTest::SetAllocSizeFail(size_t size) {
377   lock_.lock();
378   size_fails_[size]++;
379   lock_.unlock();
380 }
381 
382 // static
ClearFails()383 void LibraryTest::ClearFails() {
384   lock_.lock();
385   fails_ = 0;
386   size_fails_.clear();
387   lock_.unlock();
388 }
389 
390 
391 // static
ShouldAllocFail(size_t size)392 bool LibraryTest::ShouldAllocFail(size_t size) {
393   lock_.lock();
394   bool fail = (fails_ & 0x01);
395   fails_ >>= 1;
396   if (size_fails_[size] > 0) {
397     size_fails_[size]--;
398     fail = true;
399   }
400   lock_.unlock();
401   return fail;
402 }
403 
404 // static
amalloc(size_t size)405 void* LibraryTest::amalloc(size_t size) {
406   if (ShouldAllocFail(size) || size == 0) {
407     if (verbose) std::cerr << "Failing malloc(" << size << ") request" << std::endl;
408     return nullptr;
409   } else {
410     return malloc(size);
411   }
412 }
413 
414 // static
arealloc(void * ptr,size_t size)415 void* LibraryTest::arealloc(void *ptr, size_t size) {
416   if (ShouldAllocFail(size)) {
417     if (verbose) std::cerr << "Failing realloc(" << ptr << ", " << size << ") request" << std::endl;
418     return nullptr;
419   } else {
420     return realloc(ptr, size);
421   }
422 }
423 
424 // static
afree(void * ptr)425 void LibraryTest::afree(void *ptr) {
426   free(ptr);
427 }
428 
NoExtraFDs()429 std::set<ares_socket_t> NoExtraFDs() {
430   return std::set<ares_socket_t>();
431 }
432 
Process(unsigned int cancel_ms)433 void DefaultChannelTest::Process(unsigned int cancel_ms) {
434   ProcessWork(channel_, NoExtraFDs, nullptr, cancel_ms);
435 }
436 
Process(unsigned int cancel_ms)437 void FileChannelTest::Process(unsigned int cancel_ms) {
438   ProcessWork(channel_, NoExtraFDs, nullptr, cancel_ms);
439 }
440 
Process(unsigned int cancel_ms)441 void DefaultChannelModeTest::Process(unsigned int cancel_ms) {
442   ProcessWork(channel_, NoExtraFDs, nullptr, cancel_ms);
443 }
444 
MockServer(int family,unsigned short port)445 MockServer::MockServer(int family, unsigned short port)
446   : udpport_(port), tcpport_(port), qid_(-1) {
447   reply_ = nullptr;
448   // Create a TCP socket to receive data on.
449   tcp_data_ = NULL;
450   tcp_data_len_ = 0;
451   tcpfd_ = socket(family, SOCK_STREAM, 0);
452   EXPECT_NE(ARES_SOCKET_BAD, tcpfd_);
453   int optval = 1;
454   setsockopt(tcpfd_, SOL_SOCKET, SO_REUSEADDR,
455              BYTE_CAST &optval , sizeof(int));
456   // Send TCP data right away.
457   setsockopt(tcpfd_, IPPROTO_TCP, TCP_NODELAY,
458              BYTE_CAST &optval , sizeof(int));
459 #if defined(SO_NOSIGPIPE)
460   setsockopt(tcpfd_, SOL_SOCKET, SO_NOSIGPIPE, (void *)&optval, sizeof(optval));
461 #endif
462 
463   /* Test system enable TCP FastOpen */
464 #if defined(TCP_FASTOPEN)
465 #  ifdef __linux__
466   int qlen = 32;
467   setsockopt(tcpfd_, IPPROTO_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen));
468 #  else
469   int on = 1;
470   setsockopt(tcpfd_, IPPROTO_TCP, TCP_FASTOPEN, BYTE_CAST &on, sizeof(on));
471 #  endif
472 #endif
473 
474   // Create a UDP socket to receive data on.
475   udpfd_ = socket(family, SOCK_DGRAM, 0);
476   EXPECT_NE(ARES_SOCKET_BAD, udpfd_);
477 #if defined(SO_NOSIGPIPE)
478   setsockopt(udpfd_, SOL_SOCKET, SO_NOSIGPIPE, (void *)&optval, sizeof(optval));
479 #endif
480 
481   // Bind the sockets to the given port.
482   if (family == AF_INET) {
483     struct sockaddr_in addr;
484     memset(&addr, 0, sizeof(addr));
485     addr.sin_family = AF_INET;
486     addr.sin_addr.s_addr = htonl(INADDR_ANY);
487     addr.sin_port = htons(tcpport_);
488     int tcprc = bind(tcpfd_, (struct sockaddr*)&addr, sizeof(addr));
489     EXPECT_EQ(0, tcprc) << "Failed to bind AF_INET to TCP port " << tcpport_;
490     addr.sin_port = htons(udpport_);
491     int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr));
492     EXPECT_EQ(0, udprc) << "Failed to bind AF_INET to UDP port " << udpport_;
493     // retrieve system-assigned port
494     if (udpport_ == dynamic_port) {
495       ares_socklen_t len = sizeof(addr);
496       auto result = getsockname(udpfd_, (struct sockaddr*)&addr, &len);
497       EXPECT_EQ(0, result);
498       udpport_ = ntohs(addr.sin_port);
499       EXPECT_NE(dynamic_port, udpport_);
500     }
501     if (tcpport_ == dynamic_port) {
502       ares_socklen_t len = sizeof(addr);
503       auto result = getsockname(tcpfd_, (struct sockaddr*)&addr, &len);
504       EXPECT_EQ(0, result);
505       tcpport_ = ntohs(addr.sin_port);
506       EXPECT_NE(dynamic_port, tcpport_);
507     }
508   } else {
509     EXPECT_EQ(AF_INET6, family);
510     struct sockaddr_in6 addr;
511     memset(&addr, 0, sizeof(addr));
512     addr.sin6_family = AF_INET6;
513     memset(&addr.sin6_addr, 0, sizeof(addr.sin6_addr));  // in6addr_any
514     addr.sin6_port = htons(tcpport_);
515     int tcprc = bind(tcpfd_, (struct sockaddr*)&addr, sizeof(addr));
516     EXPECT_EQ(0, tcprc) << "Failed to bind AF_INET6 to TCP port " << tcpport_;
517     addr.sin6_port = htons(udpport_);
518     int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr));
519     EXPECT_EQ(0, udprc) << "Failed to bind AF_INET6 to UDP port " << udpport_;
520     // retrieve system-assigned port
521     if (udpport_ == dynamic_port) {
522       ares_socklen_t len = sizeof(addr);
523       auto result = getsockname(udpfd_, (struct sockaddr*)&addr, &len);
524       EXPECT_EQ(0, result);
525       udpport_ = ntohs(addr.sin6_port);
526       EXPECT_NE(dynamic_port, udpport_);
527     }
528     if (tcpport_ == dynamic_port) {
529       ares_socklen_t len = sizeof(addr);
530       auto result = getsockname(tcpfd_, (struct sockaddr*)&addr, &len);
531       EXPECT_EQ(0, result);
532       tcpport_ = ntohs(addr.sin6_port);
533       EXPECT_NE(dynamic_port, tcpport_);
534     }
535   }
536   if (verbose) std::cerr << "Configured "
537                          << (family == AF_INET ? "IPv4" : "IPv6")
538                          << " mock server with TCP socket " << tcpfd_
539                          << " on port " << tcpport_
540                          << " and UDP socket " << udpfd_
541                          << " on port " << udpport_ << std::endl;
542 
543   // For TCP, also need to listen for connections.
544   EXPECT_EQ(0, listen(tcpfd_, 5)) << "Failed to listen for TCP connections";
545 }
546 
~MockServer()547 MockServer::~MockServer() {
548   for (ares_socket_t fd : connfds_) {
549     sclose(fd);
550   }
551   sclose(tcpfd_);
552   sclose(udpfd_);
553   free(tcp_data_);
554 }
555 
getaddrport(struct sockaddr_storage * addr)556 static unsigned short getaddrport(struct sockaddr_storage *addr)
557 {
558   if (addr->ss_family == AF_INET)
559     return ntohs(((struct sockaddr_in *)(void *)addr)->sin_port);
560   if (addr->ss_family == AF_INET6)
561     return ntohs(((struct sockaddr_in6 *)(void *)addr)->sin6_port);
562 
563   /* TCP should use getpeername() to get the port, getting this from recvfrom
564    * won't work */
565   return 0;
566 }
567 
ProcessPacket(ares_socket_t fd,struct sockaddr_storage * addr,ares_socklen_t addrlen,byte * data,int len)568 void MockServer::ProcessPacket(ares_socket_t fd, struct sockaddr_storage *addr, ares_socklen_t addrlen,
569                                byte *data, int len) {
570 
571   // Assume the packet is a well-formed DNS request and extract the request
572   // details.
573   if (len < NS_HFIXEDSZ) {
574     std::cerr << "Packet too short (" << len << ")" << std::endl;
575     return;
576   }
577   int qid = DNS_HEADER_QID(data);
578   if (DNS_HEADER_QR(data) != 0) {
579     std::cerr << "Not a request" << std::endl;
580     return;
581   }
582   if (DNS_HEADER_OPCODE(data) != O_QUERY) {
583     std::cerr << "Not a query (opcode " << DNS_HEADER_OPCODE(data)
584               << ")" << std::endl;
585     return;
586   }
587   if (DNS_HEADER_QDCOUNT(data) != 1) {
588     std::cerr << "Unexpected question count (" << DNS_HEADER_QDCOUNT(data)
589               << ")" << std::endl;
590     return;
591   }
592   byte* question = data + NS_HFIXEDSZ;
593   int qlen = len - NS_HFIXEDSZ;
594 
595   char *name = nullptr;
596   long enclen;
597   ares_expand_name(question, data, len, &name, &enclen);
598   if (!name) {
599     std::cerr << "Failed to retrieve name" << std::endl;
600     return;
601   }
602   if (enclen > qlen) {
603     std::cerr << "(error, encoded name len " << enclen << "bigger than remaining data " << qlen << " bytes)" << std::endl;
604     ares_free_string(name);
605     return;
606   }
607   qlen -= (int)enclen;
608   question += enclen;
609 
610   if (qlen < 4) {
611     std::cerr << "Unexpected question size (" << qlen
612               << " bytes after name)" << std::endl;
613     ares_free_string(name);
614     return;
615   }
616   if (DNS_QUESTION_CLASS(question) != C_IN) {
617     std::cerr << "Unexpected question class (" << DNS_QUESTION_CLASS(question)
618               << ")" << std::endl;
619     ares_free_string(name);
620     return;
621   }
622   int rrtype = DNS_QUESTION_TYPE(question);
623 
624   std::vector<byte> req(data, data + len);
625   std::string reqstr = PacketToString(req);
626   if (verbose) {
627     std::cerr << "received " << (fd == udpfd_ ? "UDP" : "TCP") << " request " << reqstr
628               << " on port " << (fd == udpfd_ ? udpport_ : tcpport_)
629               << ":" << getaddrport(addr) << std::endl;
630     std::cerr << "ProcessRequest(" << qid << ", '" << name
631               << "', " << RRTypeToString(rrtype) << ")" << std::endl;
632   }
633   ProcessRequest(fd, addr, addrlen, req, reqstr, qid, name, rrtype);
634   ares_free_string(name);
635 }
636 
ProcessFD(ares_socket_t fd)637 void MockServer::ProcessFD(ares_socket_t fd) {
638   if (fd != tcpfd_ && fd != udpfd_ && connfds_.find(fd) == connfds_.end()) {
639     // Not one of our FDs.
640     return;
641   }
642   if (fd == tcpfd_) {
643     ares_socket_t connfd = accept(tcpfd_, NULL, NULL);
644     if (connfd == ARES_SOCKET_BAD) {
645       std::cerr << "Error accepting connection on fd " << fd << std::endl;
646     } else {
647       connfds_.insert(connfd);
648     }
649     return;
650   }
651 
652   // Activity on a data-bearing file descriptor.
653   struct sockaddr_storage addr;
654   socklen_t addrlen = sizeof(addr);
655   memset(&addr, 0, sizeof(addr));
656   byte buffer[2048];
657   ares_ssize_t len = (ares_ssize_t)recvfrom(fd, BYTE_CAST buffer, sizeof(buffer), 0,
658                      (struct sockaddr *)&addr, &addrlen);
659 
660   if (fd != udpfd_) {
661     if (len <= 0) {
662       connfds_.erase(std::find(connfds_.begin(), connfds_.end(), fd));
663       sclose(fd);
664       free(tcp_data_);
665       tcp_data_ = NULL;
666       tcp_data_len_ = 0;
667       return;
668     }
669     tcp_data_ = (unsigned char *)realloc(tcp_data_, tcp_data_len_ + (size_t)len);
670     memcpy(tcp_data_ + tcp_data_len_, buffer, (size_t)len);
671     tcp_data_len_ += (size_t)len;
672 
673     /* TCP might aggregate the various requests into a single packet, so we
674      * need to split */
675     while (tcp_data_len_ > 2) {
676       size_t tcplen = ((size_t)tcp_data_[0] << 8) + (size_t)tcp_data_[1];
677       if (tcp_data_len_ - 2 < tcplen)
678         break;
679 
680       ProcessPacket(fd, &addr, addrlen, tcp_data_ + 2, (int)tcplen);
681 
682       /* strip off processed data if connection not terminated */
683       if (tcp_data_ != NULL) {
684         memmove(tcp_data_, tcp_data_ + tcplen + 2, tcp_data_len_ - 2 - tcplen);
685         tcp_data_len_ -= 2 + tcplen;
686       }
687     }
688   } else {
689     /* UDP is always a single packet */
690     ProcessPacket(fd, &addr, addrlen, buffer, (int)len);
691   }
692 
693 }
694 
fds() const695 std::set<ares_socket_t> MockServer::fds() const {
696   std::set<ares_socket_t> result = connfds_;
697   result.insert(tcpfd_);
698   result.insert(udpfd_);
699   return result;
700 }
701 
ProcessRequest(ares_socket_t fd,struct sockaddr_storage * addr,ares_socklen_t addrlen,const std::vector<byte> & req,const std::string & reqstr,int qid,const char * name,int rrtype)702 void MockServer::ProcessRequest(ares_socket_t fd, struct sockaddr_storage* addr,
703                                 ares_socklen_t addrlen, const std::vector<byte> &req,
704                                 const std::string &reqstr,
705                                 int qid, const char *name, int rrtype) {
706 
707   /* DNS 0x20 will mix case, do case-insensitive matching of name in request */
708   char lower_name[256];
709   int flags = 0;
710 
711   arestest_strtolower(lower_name, name, sizeof(lower_name));
712 
713   // Before processing, let gMock know the request is happening.
714   OnRequest(lower_name, rrtype);
715 
716   // If we are expecting a specific request then check it matches here.
717   if (expected_request_.length() > 0) {
718     ASSERT_EQ(expected_request_, reqstr);
719   }
720 
721   if (reply_ != nullptr) {
722     ares_dns_record_t *dnsrec = NULL;
723     /* We will *attempt* to parse the request string.  It may be malformed that
724      * will lead to a parse failure.  If so, we just ignore it.  We want to
725      * pass this parsed data structure to the reply generator in case it needs
726      * to extract metadata (such as a DNS client cookie) from the original
727      * request.  If we can't parse it, oh well, we'll just pass NULL, most
728      * replies don't need anything from the request other than the name which
729      * is passed separately. */
730     ares_dns_parse(req.data(), req.size(), 0, &dnsrec);
731     exact_reply_ = reply_->data(name, dnsrec);
732     ares_dns_record_destroy(dnsrec);
733   }
734 
735   if (exact_reply_.size() == 0) {
736     return;
737   }
738 
739   // Make a local copy of the current pending reply.
740   std::vector<byte> reply = exact_reply_;
741 
742   if (qid_ >= 0) {
743     // Use the explicitly specified query ID.
744     qid = qid_;
745   }
746   if (reply.size() >=  2) {
747     // Overwrite the query ID if space to do so.
748     reply[0] = (byte)((qid >> 8) & 0xff);
749     reply[1] = (byte)(qid & 0xff);
750   }
751   if (verbose) {
752     std::cerr << "sending reply " << PacketToString(reply)
753               << " on port " << ((fd == udpfd_) ? udpport_ : tcpport_)
754               << ":" << getaddrport(addr) << std::endl;
755   }
756 
757   // Prefix with 2-byte length if TCP.
758   if (fd != udpfd_) {
759     int len = (int)reply.size();
760     std::vector<byte> vlen = {(byte)((len & 0xFF00) >> 8), (byte)(len & 0xFF)};
761     reply.insert(reply.begin(), vlen.begin(), vlen.end());
762     // Also, don't bother with the destination address.
763     addr = nullptr;
764     addrlen = 0;
765   }
766 
767 #ifdef MSG_NOSIGNAL
768   flags |= MSG_NOSIGNAL;
769 #endif
770 
771   ares_ssize_t rc = (ares_ssize_t)sendto(fd, BYTE_CAST reply.data(), (SEND_TYPE_ARG3)reply.size(), flags,
772                                          (struct sockaddr *)addr, addrlen);
773   if (rc < static_cast<ares_ssize_t>(reply.size())) {
774     std::cerr << "Failed to send full reply, rc=" << rc << std::endl;
775   }
776 
777 }
778 
779 // static
BuildServers(int count,int family,unsigned short base_port)780 MockChannelOptsTest::NiceMockServers MockChannelOptsTest::BuildServers(int count, int family, unsigned short base_port) {
781   NiceMockServers servers;
782   assert(count > 0);
783   for (unsigned short ii = 0; ii < count; ii++) {
784     unsigned short port = base_port == dynamic_port ? dynamic_port : base_port + ii;
785     std::unique_ptr<NiceMockServer> server(new NiceMockServer(family, port));
786     servers.push_back(std::move(server));
787   }
788   return servers;
789 }
790 
MockChannelOptsTest(int count,int family,bool force_tcp,bool honor_sysconfig,struct ares_options * givenopts,int optmask)791 MockChannelOptsTest::MockChannelOptsTest(int count,
792                                          int family,
793                                          bool force_tcp,
794                                          bool honor_sysconfig,
795                                          struct ares_options* givenopts,
796                                          int optmask)
797   : servers_(BuildServers(count, family, mock_port)),
798     server_(*servers_[0].get()), channel_(nullptr) {
799   // Set up channel options.
800   const char *domains[3] = {"first.com", "second.org", "third.gov"};
801   struct ares_options opts;
802   if (givenopts) {
803     memcpy(&opts, givenopts, sizeof(opts));
804   } else {
805     memset(&opts, 0, sizeof(opts));
806   }
807 
808   /* Honor items from resolv.conf except the dns server itself */
809   if (!honor_sysconfig) {
810     if (!(optmask & (ARES_OPT_TIMEOUTMS|ARES_OPT_TIMEOUT))) {
811       // Reduce timeouts significantly to shorten test times.
812       opts.timeout = 250;
813       optmask |= ARES_OPT_TIMEOUTMS;
814     }
815     // If not already overridden, set 3 retries.
816     if (!(optmask & ARES_OPT_TRIES)) {
817       opts.tries = 3;
818       optmask |= ARES_OPT_TRIES;
819     }
820 
821     // If not already overridden, set search domains.
822     if (!(optmask & ARES_OPT_DOMAINS)) {
823       opts.ndomains = 3;
824       opts.domains = (char**)domains;
825       optmask |= ARES_OPT_DOMAINS;
826     }
827 
828     /* Tests expect ndots=1 in general, the system config may not default to this
829      * so we don't want to inherit that. */
830     if (!(optmask & ARES_OPT_NDOTS)) {
831       opts.ndots = 1;
832       optmask |= ARES_OPT_NDOTS;
833     }
834   }
835 
836   if (force_tcp) {
837     opts.flags |= ARES_FLAG_USEVC;
838     optmask |= ARES_OPT_FLAGS;
839   }
840 
841   /* Disable the query cache for tests unless explicitly enabled. As of
842    * c-ares 1.31.0, the query cache is enabled by default so we have to set
843    * the option and set the TTL to 0 to effectively disable it. */
844   if (!(optmask & ARES_OPT_QUERY_CACHE)) {
845     opts.qcache_max_ttl = 0;
846     optmask |= ARES_OPT_QUERY_CACHE;
847   }
848 
849   /* Enable DNS0x20 by default. Need to also turn on default flag of EDNS */
850   if (!(optmask & ARES_OPT_FLAGS)) {
851     optmask |= ARES_OPT_FLAGS;
852     opts.flags = ARES_FLAG_DNS0x20|ARES_FLAG_EDNS;
853   }
854 
855   EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel_, &opts, optmask));
856   EXPECT_NE(nullptr, channel_);
857 
858   // Set up servers after construction so we can set individual ports
859   struct ares_addr_port_node* prev = nullptr;
860   struct ares_addr_port_node* first = nullptr;
861   for (const auto& server : servers_) {
862     struct ares_addr_port_node* node = (struct ares_addr_port_node*)malloc(sizeof(*node));
863     if (prev) {
864       prev->next = node;
865     } else {
866       first = node;
867     }
868     node->next = nullptr;
869     node->family = family;
870     node->udp_port = server->udpport();
871     node->tcp_port = server->tcpport();
872     if (family == AF_INET) {
873       node->addr.addr4.s_addr = htonl(0x7F000001);
874     } else {
875       memset(&node->addr.addr6, 0, sizeof(node->addr.addr6));
876       node->addr.addr6._S6_un._S6_u8[15] = 1;
877     }
878     prev = node;
879   }
880   EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, first));
881 
882   while (first) {
883     prev = first;
884     first = first->next;
885     free(prev);
886   }
887   if (verbose) {
888     std::cerr << "Configured library with servers:";
889     std::cerr << GetNameServers(channel_);
890     std::cerr << std::endl;
891   }
892 }
893 
~MockChannelOptsTest()894 MockChannelOptsTest::~MockChannelOptsTest() {
895   if (channel_) {
896     ares_destroy(channel_);
897   }
898   channel_ = nullptr;
899 }
900 
fds() const901 std::set<ares_socket_t> MockChannelOptsTest::fds() const {
902   std::set<ares_socket_t> fds;
903   for (const auto& server : servers_) {
904     std::set<ares_socket_t> serverfds = server->fds();
905     fds.insert(serverfds.begin(), serverfds.end());
906   }
907   return fds;
908 }
909 
ProcessFD(ares_socket_t fd)910 void MockChannelOptsTest::ProcessFD(ares_socket_t fd) {
911   for (auto& server : servers_) {
912     server->ProcessFD(fd);
913   }
914 }
915 
ProcessAltChannel(ares_channel_t * chan,unsigned int cancel_ms)916 void MockChannelOptsTest::ProcessAltChannel(ares_channel_t *chan, unsigned int cancel_ms) {
917   using namespace std::placeholders;
918   ProcessWork(chan,
919               std::bind(&MockChannelOptsTest::fds, this),
920               std::bind(&MockChannelOptsTest::ProcessFD, this, _1),
921               cancel_ms);
922 }
923 
Process(unsigned int cancel_ms)924 void MockChannelOptsTest::Process(unsigned int cancel_ms) {
925   ProcessAltChannel(channel_, cancel_ms);
926 }
927 
Process(unsigned int cancel_ms)928 void MockEventThreadOptsTest::Process(unsigned int cancel_ms) {
929   std::set<ares_socket_t> fds;
930 
931   auto tv_begin = std::chrono::high_resolution_clock::now();
932   auto tv_cancel = tv_begin;
933 
934   if (cancel_ms) {
935     if (verbose) std::cerr << "ares_cancel will be called after " << cancel_ms << "ms" << std::endl;
936     tv_cancel += std::chrono::milliseconds(cancel_ms);
937   }
938 
939   while (ares_queue_active_queries(channel_)) {
940     //if (verbose) std::cerr << "pending queries: " << ares_queue_active_queries(channel_) << std::endl;
941 
942     int nfds = 0;
943     fd_set readers;
944 
945     struct timeval  tv;
946 
947     /* c-ares is using its own event thread, so we only need to monitor the
948      * extrafds passed in */
949     FD_ZERO(&readers);
950     fds = MockEventThreadOptsTest::fds();
951     for (ares_socket_t fd : fds) {
952       FD_SET(fd, &readers);
953       if (fd >= (ares_socket_t)nfds) {
954         nfds = (int)fd + 1;
955       }
956     }
957 
958     /* We just always wait 20ms then recheck if we're done. Not doing any
959      * complex signaling. */
960     tv.tv_sec  = 0;
961     tv.tv_usec = 20000;
962 
963     if (cancel_ms) {
964       auto tv_now       = std::chrono::high_resolution_clock::now();
965       auto remaining_ms = std::chrono::duration_cast<std::chrono::milliseconds>(tv_cancel - tv_now).count();
966 
967       if (remaining_ms <= 0) {
968         if (verbose) std::cerr << "Issuing ares_cancel()" << std::endl;
969         ares_cancel(channel_);
970         cancel_ms = 0; /* Disable issuing cancel again */
971       } else {
972         tv.tv_sec = remaining_ms / 1000;
973         tv.tv_usec = (int)(remaining_ms % 1000);
974       }
975     }
976 
977     if (select(nfds, &readers, nullptr, nullptr, &tv) < 0) {
978       fprintf(stderr, "select() failed, errno %d\n", errno);
979       return;
980     }
981 
982     // Let the provided callback process any activity on the extra FD.
983     for (ares_socket_t fd : fds) {
984       if (FD_ISSET(fd, &readers)) {
985         ProcessFD(fd);
986       }
987     }
988   }
989 
990   //if (verbose) std::cerr << "pending queries at process end: " << ares_queue_active_queries(channel_) << std::endl;
991 }
992 
operator <<(std::ostream & os,const HostResult & result)993 std::ostream& operator<<(std::ostream& os, const HostResult& result) {
994   os << '{';
995   if (result.done_) {
996     os << StatusToString(result.status_);
997     if (result.host_.addrtype_ != -1) {
998       os << " " << result.host_;
999     } else {
1000       os << ", (no hostent)";
1001     }
1002   } else {
1003     os << "(incomplete)";
1004   }
1005   os << '}';
1006   return os;
1007 }
1008 
HostEnt(const struct hostent * hostent)1009 HostEnt::HostEnt(const struct hostent *hostent) : addrtype_(-1) {
1010   if (!hostent)
1011     return;
1012 
1013   if (hostent->h_name) {
1014     // DNS 0x20 may mix case, output as all lower for checks as the mixed case
1015     // is really more of an internal thing
1016     char lowername[256];
1017     arestest_strtolower(lowername, hostent->h_name, sizeof(lowername));
1018     name_ = lowername;
1019   }
1020 
1021   if (hostent->h_aliases) {
1022     char** palias = hostent->h_aliases;
1023     while (*palias != nullptr) {
1024       aliases_.push_back(*palias);
1025       palias++;
1026     }
1027   }
1028 
1029   addrtype_ = hostent->h_addrtype;
1030 
1031   if (hostent->h_addr_list) {
1032     char** paddr = hostent->h_addr_list;
1033     while (*paddr != nullptr) {
1034       std::string addr = AddressToString(*paddr, hostent->h_length);
1035       addrs_.push_back(addr);
1036       paddr++;
1037     }
1038   }
1039 }
1040 
operator <<(std::ostream & os,const HostEnt & host)1041 std::ostream& operator<<(std::ostream& os, const HostEnt& host) {
1042   os << "{'";
1043   if (host.name_.length() > 0) {
1044     os << host.name_;
1045   }
1046   os << "' aliases=[";
1047   for (size_t ii = 0; ii < host.aliases_.size(); ii++) {
1048     if (ii > 0) os << ", ";
1049     os << host.aliases_[ii];
1050   }
1051   os << "] ";
1052   os << "addrs=[";
1053   for (size_t ii = 0; ii < host.addrs_.size(); ii++) {
1054     if (ii > 0) os << ", ";
1055     os << host.addrs_[ii];
1056   }
1057   os << "]";
1058   os << '}';
1059   return os;
1060 }
1061 
HostCallback(void * data,int status,int timeouts,struct hostent * hostent)1062 void HostCallback(void *data, int status, int timeouts,
1063                   struct hostent *hostent) {
1064   EXPECT_NE(nullptr, data);
1065   if (data == nullptr)
1066     return;
1067 
1068   HostResult* result = reinterpret_cast<HostResult*>(data);
1069   result->done_ = true;
1070   result->status_ = status;
1071   result->timeouts_ = timeouts;
1072   if (hostent)
1073     result->host_ = HostEnt(hostent);
1074   if (verbose) std::cerr << "HostCallback(" << *result << ")" << std::endl;
1075 }
1076 
operator <<(std::ostream & os,const AresDnsRecord & dnsrec)1077 std::ostream& operator<<(std::ostream& os, const AresDnsRecord& dnsrec) {
1078   os << "{'";
1079   /* XXX: Todo */
1080   os << '}';
1081   return os;
1082 }
1083 
operator <<(std::ostream & os,const QueryResult & result)1084 std::ostream& operator<<(std::ostream& os, const QueryResult& result) {
1085   os << '{';
1086   if (result.done_) {
1087     os << StatusToString(result.status_);
1088       if (result.dnsrec_.dnsrec_ != nullptr) {
1089         os << " " << result.dnsrec_;
1090       } else {
1091         os << ", (no dnsrec)";
1092       }
1093   } else {
1094     os << "(incomplete)";
1095   }
1096   os << '}';
1097   return os;
1098 }
1099 
QueryCallback(void * data,ares_status_t status,size_t timeouts,const ares_dns_record_t * dnsrec)1100 void QueryCallback(void *data, ares_status_t status, size_t timeouts,
1101                    const ares_dns_record_t *dnsrec) {
1102   EXPECT_NE(nullptr, data);
1103   if (data == nullptr)
1104     return;
1105 
1106   QueryResult* result = reinterpret_cast<QueryResult*>(data);
1107   result->done_ = true;
1108   result->status_ = status;
1109   result->timeouts_ = timeouts;
1110   if (dnsrec)
1111     result->dnsrec_.SetDnsRecord(dnsrec);
1112   if (verbose) std::cerr << "QueryCallback(" << *result << ")" << std::endl;
1113 }
1114 
operator <<(std::ostream & os,const AddrInfoResult & result)1115 std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result) {
1116   os << '{';
1117   if (result.done_ && result.ai_) {
1118     os << StatusToString(result.status_) << " " << result.ai_;
1119   } else {
1120     os << "(incomplete)";
1121   }
1122   os << '}';
1123   return os;
1124 }
1125 
operator <<(std::ostream & os,const AddrInfo & ai)1126 std::ostream& operator<<(std::ostream& os, const AddrInfo& ai) {
1127   os << '{';
1128   if (ai == nullptr) {
1129     os << "nullptr}";
1130     return os;
1131   }
1132 
1133   struct ares_addrinfo_cname *next_cname = ai->cnames;
1134   while(next_cname) {
1135     if(next_cname->alias) {
1136       os << next_cname->alias << "->";
1137     }
1138     if(next_cname->name) {
1139       os << next_cname->name;
1140     }
1141 
1142     next_cname = next_cname->next;
1143 
1144     if (next_cname != NULL)
1145       os << ", ";
1146     else
1147       os << " ";
1148   }
1149 
1150   struct ares_addrinfo_node *next = ai->nodes;
1151   while(next) {
1152     //if(next->ai_canonname) {
1153       //os << "'" << next->ai_canonname << "' ";
1154     //}
1155     unsigned short port = 0;
1156     os << "addr=[";
1157     if(next->ai_family == AF_INET) {
1158       sockaddr_in* sin = (sockaddr_in *)((void *)next->ai_addr);
1159       port = ntohs(sin->sin_port);
1160       os << AddressToString(&sin->sin_addr, 4);
1161     }
1162     else if (next->ai_family == AF_INET6) {
1163       sockaddr_in6* sin = (sockaddr_in6*)((void *)next->ai_addr);
1164       port = ntohs(sin->sin6_port);
1165       os << "[" << AddressToString(&sin->sin6_addr, 16) << "]";
1166     }
1167     else
1168       os << "unknown family";
1169     if(port) {
1170       os << ":" << port;
1171     }
1172     os << "]";
1173     next = next->ai_next;
1174     if (next != NULL)
1175       os << ", ";
1176   }
1177   os << '}';
1178   return os;
1179 }
1180 
AddrInfoCallback(void * data,int status,int timeouts,struct ares_addrinfo * ai)1181 void AddrInfoCallback(void *data, int status, int timeouts,
1182                       struct ares_addrinfo *ai) {
1183   EXPECT_NE(nullptr, data);
1184   AddrInfoResult* result = reinterpret_cast<AddrInfoResult*>(data);
1185   result->done_ = true;
1186   result->status_ = status;
1187   result->timeouts_= timeouts;
1188   if (ai)
1189     result->ai_ = AddrInfo(ai);
1190   if (verbose) std::cerr << "AddrInfoCallback(" << *result << ")" << std::endl;
1191 }
1192 
operator <<(std::ostream & os,const SearchResult & result)1193 std::ostream& operator<<(std::ostream& os, const SearchResult& result) {
1194   os << '{';
1195   if (result.done_) {
1196     os << StatusToString(result.status_) << " " << PacketToString(result.data_);
1197   } else {
1198     os << "(incomplete)";
1199   }
1200   os << '}';
1201   return os;
1202 }
1203 
SearchCallback(void * data,int status,int timeouts,unsigned char * abuf,int alen)1204 void SearchCallback(void *data, int status, int timeouts,
1205                     unsigned char *abuf, int alen) {
1206   EXPECT_NE(nullptr, data);
1207   SearchResult* result = reinterpret_cast<SearchResult*>(data);
1208   result->done_ = true;
1209   result->status_ = status;
1210   result->timeouts_ = timeouts;
1211   result->data_.assign(abuf, abuf + alen);
1212   if (verbose) std::cerr << "SearchCallback(" << *result << ")" << std::endl;
1213 }
1214 
SearchCallbackDnsRec(void * data,ares_status_t status,size_t timeouts,const ares_dns_record_t * dnsrec)1215 void SearchCallbackDnsRec(void *data, ares_status_t status, size_t timeouts,
1216                           const ares_dns_record_t *dnsrec) {
1217   EXPECT_NE(nullptr, data);
1218   SearchResult* result = reinterpret_cast<SearchResult*>(data);
1219   unsigned char *abuf = NULL;
1220   size_t alen = 0;
1221   result->done_ = true;
1222   result->status_ = (int)status;
1223   result->timeouts_ = (int)timeouts;
1224   if (dnsrec != NULL) {
1225     ares_dns_write(dnsrec, &abuf, &alen);
1226   }
1227   result->data_.assign(abuf, abuf + alen);
1228   ares_free_string(abuf);
1229   if (verbose) std::cerr << "SearchCallbackDnsRec(" << *result << ")" << std::endl;
1230 }
1231 
operator <<(std::ostream & os,const NameInfoResult & result)1232 std::ostream& operator<<(std::ostream& os, const NameInfoResult& result) {
1233   os << '{';
1234   if (result.done_) {
1235     os << StatusToString(result.status_) << " " << result.node_ << " " << result.service_;
1236   } else {
1237     os << "(incomplete)";
1238   }
1239   os << '}';
1240   return os;
1241 }
1242 
NameInfoCallback(void * data,int status,int timeouts,char * node,char * service)1243 void NameInfoCallback(void *data, int status, int timeouts,
1244                       char *node, char *service) {
1245   EXPECT_NE(nullptr, data);
1246   NameInfoResult* result = reinterpret_cast<NameInfoResult*>(data);
1247   result->done_ = true;
1248   result->status_ = status;
1249   result->timeouts_ = timeouts;
1250   result->node_ = std::string(node ? node : "");
1251   result->service_ = std::string(service ? service : "");
1252   if (verbose) std::cerr << "NameInfoCallback(" << *result << ")" << std::endl;
1253 }
1254 
GetNameServers(ares_channel_t * channel)1255 std::string GetNameServers(ares_channel_t *channel) {
1256   char *csv = ares_get_servers_csv(channel);
1257   EXPECT_NE((char *)NULL, csv);
1258 
1259   std::string servers(csv);
1260 
1261   ares_free_string(csv);
1262   return servers;
1263 }
1264 
TransientDir(const std::string & dirname)1265 TransientDir::TransientDir(const std::string& dirname) : dirname_(dirname) {
1266   if (mkdir_(dirname_.c_str(), 0755) != 0) {
1267     std::cerr << "Failed to create subdirectory '" << dirname_ << "'" << std::endl;
1268   }
1269 }
1270 
~TransientDir()1271 TransientDir::~TransientDir() {
1272   rmdir(dirname_.c_str());
1273 }
1274 
TransientFile(const std::string & filename,const std::string & contents)1275 TransientFile::TransientFile(const std::string& filename,
1276                              const std::string& contents)
1277     : filename_(filename) {
1278   FILE *f = fopen(filename.c_str(), "w");
1279   if (f == nullptr) {
1280     std::cerr << "Error: failed to create '" << filename << "'" << std::endl;
1281     return;
1282   }
1283   size_t rc = (size_t)fwrite(contents.data(), 1, contents.size(), f);
1284   if (rc != contents.size()) {
1285     std::cerr << "Error: failed to write contents of '" << filename << "'" << std::endl;
1286   }
1287   fclose(f);
1288 }
1289 
~TransientFile()1290 TransientFile::~TransientFile() {
1291   unlink(filename_.c_str());
1292 }
1293 
TempNam(const char * dir,const char * prefix)1294 std::string TempNam(const char *dir, const char *prefix) {
1295   char *p = tempnam(dir, prefix);
1296   std::string result(p);
1297   free(p);
1298   return result;
1299 }
1300 
TempFile(const std::string & contents)1301 TempFile::TempFile(const std::string& contents)
1302   : TransientFile(TempNam(nullptr, "ares"), contents) {
1303 
1304 }
1305 
VirtualizeIO(ares_channel_t * c)1306 VirtualizeIO::VirtualizeIO(ares_channel_t *c)
1307   : channel_(c)
1308 {
1309   ares_set_socket_functions(channel_, &default_functions, 0);
1310 }
1311 
~VirtualizeIO()1312 VirtualizeIO::~VirtualizeIO() {
1313   ares_set_socket_functions(channel_, 0, 0);
1314 }
1315 
1316 }  // namespace test
1317 }  // namespace ares
1318