quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares-test.cc (41080B)


      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 
    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 
    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 
    344 void LibraryTest::SetFailSend() {
    345   failsend_ = true;
    346 }
    347 
    348 // static
    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 
    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
    376 void LibraryTest::SetAllocSizeFail(size_t size) {
    377   lock_.lock();
    378   size_fails_[size]++;
    379   lock_.unlock();
    380 }
    381 
    382 // static
    383 void LibraryTest::ClearFails() {
    384   lock_.lock();
    385   fails_ = 0;
    386   size_fails_.clear();
    387   lock_.unlock();
    388 }
    389 
    390 
    391 // static
    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
    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
    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
    425 void LibraryTest::afree(void *ptr) {
    426   free(ptr);
    427 }
    428 
    429 std::set<ares_socket_t> NoExtraFDs() {
    430   return std::set<ares_socket_t>();
    431 }
    432 
    433 void DefaultChannelTest::Process(unsigned int cancel_ms) {
    434   ProcessWork(channel_, NoExtraFDs, nullptr, cancel_ms);
    435 }
    436 
    437 void FileChannelTest::Process(unsigned int cancel_ms) {
    438   ProcessWork(channel_, NoExtraFDs, nullptr, cancel_ms);
    439 }
    440 
    441 void DefaultChannelModeTest::Process(unsigned int cancel_ms) {
    442   ProcessWork(channel_, NoExtraFDs, nullptr, cancel_ms);
    443 }
    444 
    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 
    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 
    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 
    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 
    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 
    695 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 
    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
    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 
    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 
    894 MockChannelOptsTest::~MockChannelOptsTest() {
    895   if (channel_) {
    896     ares_destroy(channel_);
    897   }
    898   channel_ = nullptr;
    899 }
    900 
    901 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 
    910 void MockChannelOptsTest::ProcessFD(ares_socket_t fd) {
    911   for (auto& server : servers_) {
    912     server->ProcessFD(fd);
    913   }
    914 }
    915 
    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 
    924 void MockChannelOptsTest::Process(unsigned int cancel_ms) {
    925   ProcessAltChannel(channel_, cancel_ms);
    926 }
    927 
    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 
    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 
   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 
   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 
   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 
   1077 std::ostream& operator<<(std::ostream& os, const AresDnsRecord& dnsrec) {
   1078   os << "{'";
   1079   /* XXX: Todo */
   1080   os << '}';
   1081   return os;
   1082 }
   1083 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1271 TransientDir::~TransientDir() {
   1272   rmdir(dirname_.c_str());
   1273 }
   1274 
   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 
   1290 TransientFile::~TransientFile() {
   1291   unlink(filename_.c_str());
   1292 }
   1293 
   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 
   1301 TempFile::TempFile(const std::string& contents)
   1302   : TransientFile(TempNam(nullptr, "ares"), contents) {
   1303 
   1304 }
   1305 
   1306 VirtualizeIO::VirtualizeIO(ares_channel_t *c)
   1307   : channel_(c)
   1308 {
   1309   ares_set_socket_functions(channel_, &default_functions, 0);
   1310 }
   1311 
   1312 VirtualizeIO::~VirtualizeIO() {
   1313   ares_set_socket_functions(channel_, 0, 0);
   1314 }
   1315 
   1316 }  // namespace test
   1317 }  // namespace ares