quickjs-tart

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

ares-test-mock-et.cc (66031B)


      1 /* MIT License
      2  *
      3  * Copyright (c) The c-ares project and its contributors
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a copy
      6  * of this software and associated documentation files (the "Software"), to deal
      7  * in the Software without restriction, including without limitation the rights
      8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9  * copies of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  * SPDX-License-Identifier: MIT
     25  */
     26 #include "ares-test.h"
     27 #include "dns-proto.h"
     28 
     29 #ifdef CARES_THREADS
     30 
     31 #ifndef WIN32
     32 #include <sys/types.h>
     33 #include <sys/stat.h>
     34 #endif
     35 
     36 #include <sstream>
     37 #include <vector>
     38 
     39 using testing::InvokeWithoutArgs;
     40 using testing::DoAll;
     41 
     42 namespace ares {
     43 namespace test {
     44 
     45 // UDP only so mock server doesn't get confused by concatenated requests
     46 TEST_P(MockUDPEventThreadTest, GetHostByNameParallelLookups) {
     47   DNSPacket rsp1;
     48   rsp1.set_response().set_aa()
     49     .add_question(new DNSQuestion("www.google.com", T_A))
     50     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
     51   ON_CALL(server_, OnRequest("www.google.com", T_A))
     52     .WillByDefault(SetReply(&server_, &rsp1));
     53   DNSPacket rsp2;
     54   rsp2.set_response().set_aa()
     55     .add_question(new DNSQuestion("www.example.com", T_A))
     56     .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
     57   ON_CALL(server_, OnRequest("www.example.com", T_A))
     58     .WillByDefault(SetReply(&server_, &rsp2));
     59 
     60   HostResult result1;
     61   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
     62   HostResult result2;
     63   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result2);
     64   HostResult result3;
     65   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result3);
     66   Process();
     67   EXPECT_TRUE(result1.done_);
     68   EXPECT_TRUE(result2.done_);
     69   EXPECT_TRUE(result3.done_);
     70   std::stringstream ss1;
     71   ss1 << result1.host_;
     72   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
     73   std::stringstream ss2;
     74   ss2 << result2.host_;
     75   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[1.2.3.4]}", ss2.str());
     76   std::stringstream ss3;
     77   ss3 << result3.host_;
     78   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
     79 }
     80 
     81 // c-ares issue #819
     82 TEST_P(MockUDPEventThreadTest, BadLoopbackServerNoTimeouts) {
     83   ares_set_servers_csv(channel_, "127.0.0.1:12345");
     84 #define BADLOOPBACK_TESTCNT 5
     85   HostResult result[BADLOOPBACK_TESTCNT];
     86   for (size_t i=0; i<BADLOOPBACK_TESTCNT; i++) {
     87     ares_gethostbyname(channel_, "www.google.com.", AF_UNSPEC, HostCallback, &result[i]);
     88   }
     89   Process();
     90   for (size_t i=0; i<BADLOOPBACK_TESTCNT; i++) {
     91     EXPECT_TRUE(result[i].done_);
     92 
     93     /* This test relies on the ICMP unreachable packet coming back on UDP connections
     94      * when there is no listener on the other end.  Most OS's handle this properly,
     95      * but not all.  For instance, Solaris 11 seems to not be compliant (it
     96      * does however honor it sometimes, just not always) so while we still run
     97      * the test, we don't do a strict validation of the result.
     98      *
     99      * Windows also appears to have intermittent issues, AppVeyor fails but GitHub Actions
    100      * succeeds, which seems strange.  This test goes to loopback so the network
    101      * it resides on shouldn't matter.
    102      *
    103      * This test is really just testing an optimization, UDP is connectionless so you
    104      * should expect most connections to rely on timeouts and not ICMP unreachable.
    105      */
    106 # if defined(__sun) || defined(_WIN32) || defined(__NetBSD__)
    107     EXPECT_TRUE(result[i].status_ == ARES_ECONNREFUSED || result[i].status_ == ARES_ETIMEOUT || result[i].status_ == ARES_ESERVFAIL);
    108 # else
    109     EXPECT_EQ(ARES_ECONNREFUSED, result[i].status_);
    110     EXPECT_EQ(0, result[i].timeouts_);
    111 #endif
    112   }
    113 }
    114 
    115 // UDP to TCP specific test
    116 TEST_P(MockUDPEventThreadTest, TruncationRetry) {
    117   DNSPacket rsptruncated;
    118   rsptruncated.set_response().set_aa().set_tc()
    119     .add_question(new DNSQuestion("www.google.com", T_A));
    120   DNSPacket rspok;
    121   rspok.set_response()
    122     .add_question(new DNSQuestion("www.google.com", T_A))
    123     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
    124   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    125     .WillOnce(SetReply(&server_, &rsptruncated))
    126     .WillOnce(SetReply(&server_, &rspok));
    127   HostResult result;
    128   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    129   Process();
    130   EXPECT_TRUE(result.done_);
    131   std::stringstream ss;
    132   ss << result.host_;
    133   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
    134 }
    135 
    136 static int sock_cb_count = 0;
    137 static int SocketConnectCallback(ares_socket_t fd, int type, void *data) {
    138   int rc = *(int*)data;
    139   (void)type;
    140   sock_cb_count++;
    141   if (verbose) std::cerr << "SocketConnectCallback(fd: " << fd << ", cnt: " << sock_cb_count << ") invoked" << std::endl;
    142   return rc;
    143 }
    144 
    145 TEST_P(MockEventThreadTest, SockCallback) {
    146   DNSPacket rsp;
    147   rsp.set_response().set_aa()
    148     .add_question(new DNSQuestion("www.google.com", T_A))
    149     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
    150   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    151     .WillOnce(SetReply(&server_, &rsp));
    152 
    153   // Get notified of new sockets
    154   int rc = ARES_SUCCESS;
    155   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
    156 
    157   HostResult result;
    158   sock_cb_count = 0;
    159   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    160   Process();
    161   EXPECT_EQ(1, sock_cb_count);
    162   EXPECT_TRUE(result.done_);
    163   std::stringstream ss;
    164   ss << result.host_;
    165   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
    166 }
    167 
    168 TEST_P(MockEventThreadTest, SockFailCallback) {
    169   // Notification of new sockets gives an error.
    170   int rc = -1;
    171   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
    172 
    173   HostResult result;
    174   sock_cb_count = 0;
    175   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    176   Process();
    177   EXPECT_LT(1, sock_cb_count);
    178   EXPECT_TRUE(result.done_);
    179   EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
    180 }
    181 
    182 
    183 TEST_P(MockEventThreadTest, ReInit) {
    184   DNSPacket rsp;
    185   rsp.set_response().set_aa()
    186     .add_question(new DNSQuestion("www.google.com", T_A))
    187     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
    188   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    189     .WillOnce(SetReply(&server_, &rsp));
    190 
    191   HostResult result;
    192   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    193   EXPECT_EQ(ARES_SUCCESS, ares_reinit(channel_));
    194   Process();
    195   EXPECT_TRUE(result.done_);
    196   std::stringstream ss;
    197   ss << result.host_;
    198   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
    199 }
    200 
    201 #define MAXUDPQUERIES_TOTAL 32
    202 #define MAXUDPQUERIES_LIMIT 8
    203 
    204 class MockUDPEventThreadMaxQueriesTest
    205     : public MockEventThreadOptsTest,
    206       public ::testing::WithParamInterface<std::tuple<ares_evsys_t,int>> {
    207  public:
    208   MockUDPEventThreadMaxQueriesTest()
    209     : MockEventThreadOptsTest(1, std::get<0>(GetParam()), std::get<1>(GetParam()), false,
    210                           FillOptions(&opts_),
    211                           ARES_OPT_UDP_MAX_QUERIES|ARES_OPT_FLAGS) {}
    212   static struct ares_options* FillOptions(struct ares_options * opts) {
    213     memset(opts, 0, sizeof(struct ares_options));
    214     opts->flags = ARES_FLAG_STAYOPEN|ARES_FLAG_EDNS;
    215     opts->udp_max_queries = MAXUDPQUERIES_LIMIT;
    216     return opts;
    217   }
    218  private:
    219   struct ares_options opts_;
    220 };
    221 
    222 TEST_P(MockUDPEventThreadMaxQueriesTest, GetHostByNameParallelLookups) {
    223   DNSPacket rsp;
    224   rsp.set_response().set_aa()
    225     .add_question(new DNSQuestion("www.google.com", T_A))
    226     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
    227   ON_CALL(server_, OnRequest("www.google.com", T_A))
    228     .WillByDefault(SetReply(&server_, &rsp));
    229 
    230   // Get notified of new sockets so we can validate how many are created
    231   int rc = ARES_SUCCESS;
    232   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
    233   sock_cb_count = 0;
    234 
    235   HostResult result[MAXUDPQUERIES_TOTAL];
    236   for (size_t i=0; i<MAXUDPQUERIES_TOTAL; i++) {
    237     ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result[i]);
    238   }
    239 
    240   Process();
    241 
    242   EXPECT_EQ(MAXUDPQUERIES_TOTAL / MAXUDPQUERIES_LIMIT, sock_cb_count);
    243 
    244   for (size_t i=0; i<MAXUDPQUERIES_TOTAL; i++) {
    245     std::stringstream ss;
    246     EXPECT_TRUE(result[i].done_);
    247     ss << result[i].host_;
    248     EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
    249   }
    250 }
    251 
    252 /* This test case is likely to fail in heavily loaded environments, it was
    253  * there to stress the windows event system.  Not needed to be on normally */
    254 #if 0
    255 class MockUDPEventThreadSingleQueryPerConnTest
    256     : public MockEventThreadOptsTest,
    257       public ::testing::WithParamInterface<std::tuple<ares_evsys_t,int>> {
    258  public:
    259   MockUDPEventThreadSingleQueryPerConnTest()
    260     : MockEventThreadOptsTest(1, std::get<0>(GetParam()), std::get<1>(GetParam()), false,
    261                           FillOptions(&opts_),
    262                           ARES_OPT_UDP_MAX_QUERIES) {}
    263   static struct ares_options* FillOptions(struct ares_options * opts) {
    264     memset(opts, 0, sizeof(struct ares_options));
    265     opts->udp_max_queries = 1;
    266     return opts;
    267   }
    268  private:
    269   struct ares_options opts_;
    270 };
    271 
    272 #define LOTSOFCONNECTIONS_CNT 64
    273 TEST_P(MockUDPEventThreadSingleQueryPerConnTest, LotsOfConnections) {
    274   DNSPacket rsp;
    275   rsp.set_response().set_aa()
    276     .add_question(new DNSQuestion("www.google.com", T_A))
    277     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
    278   ON_CALL(server_, OnRequest("www.google.com", T_A))
    279     .WillByDefault(SetReply(&server_, &rsp));
    280 
    281   // Get notified of new sockets so we can validate how many are created
    282   int rc = ARES_SUCCESS;
    283   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
    284   sock_cb_count = 0;
    285 
    286   HostResult result[LOTSOFCONNECTIONS_CNT];
    287   for (size_t i=0; i<LOTSOFCONNECTIONS_CNT; i++) {
    288     ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result[i]);
    289   }
    290 
    291   Process();
    292 
    293   EXPECT_EQ(LOTSOFCONNECTIONS_CNT, sock_cb_count);
    294 
    295   for (size_t i=0; i<LOTSOFCONNECTIONS_CNT; i++) {
    296     std::stringstream ss;
    297     EXPECT_TRUE(result[i].done_);
    298     ss << result[i].host_;
    299     EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
    300   }
    301 }
    302 #endif
    303 
    304 class CacheQueriesEventThreadTest
    305     : public MockEventThreadOptsTest,
    306       public ::testing::WithParamInterface<std::tuple<ares_evsys_t,int>> {
    307  public:
    308   CacheQueriesEventThreadTest()
    309     : MockEventThreadOptsTest(1, std::get<0>(GetParam()), std::get<1>(GetParam()), false,
    310                           FillOptions(&opts_),
    311                           ARES_OPT_QUERY_CACHE) {}
    312   static struct ares_options* FillOptions(struct ares_options * opts) {
    313     memset(opts, 0, sizeof(struct ares_options));
    314     opts->qcache_max_ttl = 3600;
    315     return opts;
    316   }
    317  private:
    318   struct ares_options opts_;
    319 };
    320 
    321 TEST_P(CacheQueriesEventThreadTest, GetHostByNameCache) {
    322   DNSPacket rsp;
    323   rsp.set_response().set_aa()
    324     .add_question(new DNSQuestion("www.google.com", T_A))
    325     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
    326   ON_CALL(server_, OnRequest("www.google.com", T_A))
    327     .WillByDefault(SetReply(&server_, &rsp));
    328 
    329   // Get notified of new sockets so we can validate how many are created
    330   int rc = ARES_SUCCESS;
    331   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
    332   sock_cb_count = 0;
    333 
    334   HostResult result1;
    335   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
    336   Process();
    337 
    338   std::stringstream ss1;
    339   EXPECT_TRUE(result1.done_);
    340   ss1 << result1.host_;
    341   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
    342 
    343   /* Run again, should return cached result */
    344   HostResult result2;
    345   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result2);
    346   Process();
    347 
    348   std::stringstream ss2;
    349   EXPECT_TRUE(result2.done_);
    350   ss2 << result2.host_;
    351   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss2.str());
    352 
    353   EXPECT_EQ(1, sock_cb_count);
    354 }
    355 
    356 #define TCPPARALLELLOOKUPS 32
    357 
    358 class MockTCPEventThreadStayOpenTest
    359     : public MockEventThreadOptsTest,
    360       public ::testing::WithParamInterface<std::tuple<ares_evsys_t,int>> {
    361  public:
    362   MockTCPEventThreadStayOpenTest()
    363     : MockEventThreadOptsTest(1, std::get<0>(GetParam()), std::get<1>(GetParam()), true /* tcp */,
    364                           FillOptions(&opts_),
    365                           ARES_OPT_FLAGS) {}
    366   static struct ares_options* FillOptions(struct ares_options * opts) {
    367     memset(opts, 0, sizeof(struct ares_options));
    368     opts->flags = ARES_FLAG_STAYOPEN|ARES_FLAG_EDNS;
    369     return opts;
    370   }
    371  private:
    372   struct ares_options opts_;
    373 };
    374 
    375 TEST_P(MockTCPEventThreadStayOpenTest, GetHostByNameParallelLookups) {
    376   DNSPacket rsp;
    377   rsp.set_response().set_aa()
    378     .add_question(new DNSQuestion("www.google.com", T_A))
    379     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
    380   ON_CALL(server_, OnRequest("www.google.com", T_A))
    381     .WillByDefault(SetReply(&server_, &rsp));
    382 
    383   // Get notified of new sockets so we can validate how many are created
    384   int rc = ARES_SUCCESS;
    385   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
    386   sock_cb_count = 0;
    387 
    388   HostResult result[TCPPARALLELLOOKUPS];
    389   for (size_t i=0; i<TCPPARALLELLOOKUPS; i++) {
    390     ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result[i]);
    391   }
    392 
    393   Process();
    394 
    395   EXPECT_EQ(1, sock_cb_count);
    396 
    397   for (size_t i=0; i<TCPPARALLELLOOKUPS; i++) {
    398     std::stringstream ss;
    399     EXPECT_TRUE(result[i].done_);
    400     ss << result[i].host_;
    401     EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
    402   }
    403 }
    404 
    405 TEST_P(MockTCPEventThreadTest, MalformedResponse) {
    406   std::vector<byte> one = {0x00};
    407   ON_CALL(server_, OnRequest("www.google.com", T_A))
    408     .WillByDefault(SetReplyData(&server_, one));
    409 
    410   HostResult result;
    411   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    412   Process();
    413   EXPECT_TRUE(result.done_);
    414   EXPECT_EQ(ARES_EBADRESP, result.status_);
    415 }
    416 
    417 TEST_P(MockTCPEventThreadTest, FormErrResponse) {
    418   DNSPacket rsp;
    419   rsp.set_response().set_aa()
    420     .add_question(new DNSQuestion("www.google.com", T_A));
    421   rsp.set_rcode(FORMERR);
    422   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    423     .WillOnce(SetReply(&server_, &rsp));
    424   HostResult result;
    425   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    426   Process();
    427   EXPECT_TRUE(result.done_);
    428   EXPECT_EQ(ARES_EFORMERR, result.status_);
    429 }
    430 
    431 TEST_P(MockTCPEventThreadTest, ServFailResponse) {
    432   DNSPacket rsp;
    433   rsp.set_response().set_aa()
    434     .add_question(new DNSQuestion("www.google.com", T_A));
    435   rsp.set_rcode(SERVFAIL);
    436   ON_CALL(server_, OnRequest("www.google.com", T_A))
    437     .WillByDefault(SetReply(&server_, &rsp));
    438   HostResult result;
    439   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    440   Process();
    441   EXPECT_TRUE(result.done_);
    442   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
    443 }
    444 
    445 TEST_P(MockTCPEventThreadTest, NotImplResponse) {
    446   DNSPacket rsp;
    447   rsp.set_response().set_aa()
    448     .add_question(new DNSQuestion("www.google.com", T_A));
    449   rsp.set_rcode(NOTIMP);
    450   ON_CALL(server_, OnRequest("www.google.com", T_A))
    451     .WillByDefault(SetReply(&server_, &rsp));
    452   HostResult result;
    453   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    454   Process();
    455   EXPECT_TRUE(result.done_);
    456   EXPECT_EQ(ARES_ENOTIMP, result.status_);
    457 }
    458 
    459 TEST_P(MockTCPEventThreadTest, RefusedResponse) {
    460   DNSPacket rsp;
    461   rsp.set_response().set_aa()
    462     .add_question(new DNSQuestion("www.google.com", T_A));
    463   rsp.set_rcode(REFUSED);
    464   ON_CALL(server_, OnRequest("www.google.com", T_A))
    465     .WillByDefault(SetReply(&server_, &rsp));
    466   HostResult result;
    467   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    468   Process();
    469   EXPECT_TRUE(result.done_);
    470   EXPECT_EQ(ARES_EREFUSED, result.status_);
    471 }
    472 
    473 TEST_P(MockTCPEventThreadTest, YXDomainResponse) {
    474   DNSPacket rsp;
    475   rsp.set_response().set_aa()
    476     .add_question(new DNSQuestion("www.google.com", T_A));
    477   rsp.set_rcode(YXDOMAIN);
    478   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    479     .WillOnce(SetReply(&server_, &rsp));
    480   HostResult result;
    481   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    482   Process();
    483   EXPECT_TRUE(result.done_);
    484   EXPECT_EQ(ARES_ENODATA, result.status_);
    485 }
    486 
    487 class MockExtraOptsEventThreadTest
    488     : public MockEventThreadOptsTest,
    489       public ::testing::WithParamInterface<std::tuple<ares_evsys_t, int, bool> > {
    490  public:
    491   MockExtraOptsEventThreadTest()
    492     : MockEventThreadOptsTest(1, std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()),
    493                           FillOptions(&opts_),
    494                           ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
    495   static struct ares_options* FillOptions(struct ares_options * opts) {
    496     memset(opts, 0, sizeof(struct ares_options));
    497     // Set a few options that affect socket communications
    498     opts->socket_send_buffer_size = 514;
    499     opts->socket_receive_buffer_size = 514;
    500     return opts;
    501   }
    502  private:
    503   struct ares_options opts_;
    504 };
    505 
    506 TEST_P(MockExtraOptsEventThreadTest, SimpleQuery) {
    507   ares_set_local_ip4(channel_, 0x7F000001);
    508   byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    509                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
    510   ares_set_local_ip6(channel_, addr6);
    511   ares_set_local_dev(channel_, "dummy");
    512 
    513   DNSPacket rsp;
    514   rsp.set_response().set_aa()
    515     .add_question(new DNSQuestion("www.google.com", T_A))
    516     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
    517   ON_CALL(server_, OnRequest("www.google.com", T_A))
    518     .WillByDefault(SetReply(&server_, &rsp));
    519 
    520   HostResult result;
    521   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    522   Process();
    523   EXPECT_TRUE(result.done_);
    524   std::stringstream ss;
    525   ss << result.host_;
    526   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
    527 }
    528 
    529 class MockFlagsEventThreadOptsTest
    530     : public MockEventThreadOptsTest,
    531       public ::testing::WithParamInterface< std::tuple<ares_evsys_t, int, bool> > {
    532  public:
    533   MockFlagsEventThreadOptsTest(int flags)
    534     : MockEventThreadOptsTest(1, std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()),
    535                           FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
    536   static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
    537     memset(opts, 0, sizeof(struct ares_options));
    538     opts->flags = flags;
    539     return opts;
    540   }
    541  private:
    542   struct ares_options opts_;
    543 };
    544 
    545 class MockNoCheckRespEventThreadTest : public MockFlagsEventThreadOptsTest {
    546  public:
    547   MockNoCheckRespEventThreadTest() : MockFlagsEventThreadOptsTest(ARES_FLAG_NOCHECKRESP) {}
    548 };
    549 
    550 TEST_P(MockNoCheckRespEventThreadTest, ServFailResponse) {
    551   DNSPacket rsp;
    552   rsp.set_response().set_aa()
    553     .add_question(new DNSQuestion("www.google.com", T_A));
    554   rsp.set_rcode(SERVFAIL);
    555   ON_CALL(server_, OnRequest("www.google.com", T_A))
    556     .WillByDefault(SetReply(&server_, &rsp));
    557   HostResult result;
    558   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    559   Process();
    560   EXPECT_TRUE(result.done_);
    561   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
    562 }
    563 
    564 TEST_P(MockNoCheckRespEventThreadTest, NotImplResponse) {
    565   DNSPacket rsp;
    566   rsp.set_response().set_aa()
    567     .add_question(new DNSQuestion("www.google.com", T_A));
    568   rsp.set_rcode(NOTIMP);
    569   ON_CALL(server_, OnRequest("www.google.com", T_A))
    570     .WillByDefault(SetReply(&server_, &rsp));
    571   HostResult result;
    572   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    573   Process();
    574   EXPECT_TRUE(result.done_);
    575   EXPECT_EQ(ARES_ENOTIMP, result.status_);
    576 }
    577 
    578 TEST_P(MockNoCheckRespEventThreadTest, RefusedResponse) {
    579   DNSPacket rsp;
    580   rsp.set_response().set_aa()
    581     .add_question(new DNSQuestion("www.google.com", T_A));
    582   rsp.set_rcode(REFUSED);
    583   ON_CALL(server_, OnRequest("www.google.com", T_A))
    584     .WillByDefault(SetReply(&server_, &rsp));
    585   HostResult result;
    586   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    587   Process();
    588   EXPECT_TRUE(result.done_);
    589   EXPECT_EQ(ARES_EREFUSED, result.status_);
    590 }
    591 
    592 class MockEDNSEventThreadTest : public MockFlagsEventThreadOptsTest {
    593  public:
    594   MockEDNSEventThreadTest() : MockFlagsEventThreadOptsTest(ARES_FLAG_EDNS) {}
    595 };
    596 
    597 TEST_P(MockEDNSEventThreadTest, RetryWithoutEDNS) {
    598   DNSPacket rspfail;
    599   rspfail.set_response().set_aa().set_rcode(FORMERR)
    600     .add_question(new DNSQuestion("www.google.com", T_A));
    601   DNSPacket rspok;
    602   rspok.set_response()
    603     .add_question(new DNSQuestion("www.google.com", T_A))
    604     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
    605   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    606     .WillOnce(SetReply(&server_, &rspfail))
    607     .WillOnce(SetReply(&server_, &rspok));
    608   HostResult result;
    609   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    610   Process();
    611   EXPECT_TRUE(result.done_);
    612   std::stringstream ss;
    613   ss << result.host_;
    614   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
    615 }
    616 
    617 TEST_P(MockEventThreadTest, SearchDomains) {
    618   DNSPacket nofirst;
    619   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
    620     .add_question(new DNSQuestion("www.first.com", T_A));
    621   ON_CALL(server_, OnRequest("www.first.com", T_A))
    622     .WillByDefault(SetReply(&server_, &nofirst));
    623   DNSPacket nosecond;
    624   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
    625     .add_question(new DNSQuestion("www.second.org", T_A));
    626   ON_CALL(server_, OnRequest("www.second.org", T_A))
    627     .WillByDefault(SetReply(&server_, &nosecond));
    628   DNSPacket yesthird;
    629   yesthird.set_response().set_aa()
    630     .add_question(new DNSQuestion("www.third.gov", T_A))
    631     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
    632   ON_CALL(server_, OnRequest("www.third.gov", T_A))
    633     .WillByDefault(SetReply(&server_, &yesthird));
    634 
    635   HostResult result;
    636   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
    637   Process();
    638   EXPECT_TRUE(result.done_);
    639   std::stringstream ss;
    640   ss << result.host_;
    641   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
    642 }
    643 
    644 // Relies on retries so is UDP-only
    645 TEST_P(MockUDPEventThreadTest, SearchDomainsWithResentReply) {
    646   DNSPacket nofirst;
    647   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
    648     .add_question(new DNSQuestion("www.first.com", T_A));
    649   EXPECT_CALL(server_, OnRequest("www.first.com", T_A))
    650     .WillOnce(SetReply(&server_, &nofirst));
    651   DNSPacket nosecond;
    652   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
    653     .add_question(new DNSQuestion("www.second.org", T_A));
    654   EXPECT_CALL(server_, OnRequest("www.second.org", T_A))
    655     .WillOnce(SetReply(&server_, &nosecond));
    656   DNSPacket yesthird;
    657   yesthird.set_response().set_aa()
    658     .add_question(new DNSQuestion("www.third.gov", T_A))
    659     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
    660   // Before sending the real answer, resend an earlier reply
    661   EXPECT_CALL(server_, OnRequest("www.third.gov", T_A))
    662     .WillOnce(DoAll(SetReply(&server_, &nofirst),
    663                     SetReplyQID(&server_, 123)))
    664     .WillOnce(DoAll(SetReply(&server_, &yesthird),
    665                     SetReplyQID(&server_, -1)));
    666 
    667   HostResult result;
    668   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
    669   Process();
    670   EXPECT_TRUE(result.done_);
    671   std::stringstream ss;
    672   ss << result.host_;
    673   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
    674 }
    675 
    676 TEST_P(MockEventThreadTest, SearchDomainsBare) {
    677   DNSPacket nofirst;
    678   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
    679     .add_question(new DNSQuestion("www.first.com", T_A));
    680   ON_CALL(server_, OnRequest("www.first.com", T_A))
    681     .WillByDefault(SetReply(&server_, &nofirst));
    682   DNSPacket nosecond;
    683   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
    684     .add_question(new DNSQuestion("www.second.org", T_A));
    685   ON_CALL(server_, OnRequest("www.second.org", T_A))
    686     .WillByDefault(SetReply(&server_, &nosecond));
    687   DNSPacket nothird;
    688   nothird.set_response().set_aa().set_rcode(NXDOMAIN)
    689     .add_question(new DNSQuestion("www.third.gov", T_A));
    690   ON_CALL(server_, OnRequest("www.third.gov", T_A))
    691     .WillByDefault(SetReply(&server_, &nothird));
    692   DNSPacket yesbare;
    693   yesbare.set_response().set_aa()
    694     .add_question(new DNSQuestion("www", T_A))
    695     .add_answer(new DNSARR("www", 0x0200, {2, 3, 4, 5}));
    696   ON_CALL(server_, OnRequest("www", T_A))
    697     .WillByDefault(SetReply(&server_, &yesbare));
    698 
    699   HostResult result;
    700   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
    701   Process();
    702   EXPECT_TRUE(result.done_);
    703   std::stringstream ss;
    704   ss << result.host_;
    705   EXPECT_EQ("{'www' aliases=[] addrs=[2.3.4.5]}", ss.str());
    706 }
    707 
    708 TEST_P(MockEventThreadTest, SearchNoDataThenSuccess) {
    709   // First two search domains recognize the name but have no A records.
    710   DNSPacket nofirst;
    711   nofirst.set_response().set_aa()
    712     .add_question(new DNSQuestion("www.first.com", T_A));
    713   ON_CALL(server_, OnRequest("www.first.com", T_A))
    714     .WillByDefault(SetReply(&server_, &nofirst));
    715   DNSPacket nosecond;
    716   nosecond.set_response().set_aa()
    717     .add_question(new DNSQuestion("www.second.org", T_A));
    718   ON_CALL(server_, OnRequest("www.second.org", T_A))
    719     .WillByDefault(SetReply(&server_, &nosecond));
    720   DNSPacket yesthird;
    721   yesthird.set_response().set_aa()
    722     .add_question(new DNSQuestion("www.third.gov", T_A))
    723     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
    724   ON_CALL(server_, OnRequest("www.third.gov", T_A))
    725     .WillByDefault(SetReply(&server_, &yesthird));
    726 
    727   HostResult result;
    728   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
    729   Process();
    730   EXPECT_TRUE(result.done_);
    731   std::stringstream ss;
    732   ss << result.host_;
    733   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
    734 }
    735 
    736 TEST_P(MockEventThreadTest, SearchNoDataThenNoDataBare) {
    737   // First two search domains recognize the name but have no A records.
    738   DNSPacket nofirst;
    739   nofirst.set_response().set_aa()
    740     .add_question(new DNSQuestion("www.first.com", T_A));
    741   ON_CALL(server_, OnRequest("www.first.com", T_A))
    742     .WillByDefault(SetReply(&server_, &nofirst));
    743   DNSPacket nosecond;
    744   nosecond.set_response().set_aa()
    745     .add_question(new DNSQuestion("www.second.org", T_A));
    746   ON_CALL(server_, OnRequest("www.second.org", T_A))
    747     .WillByDefault(SetReply(&server_, &nosecond));
    748   DNSPacket nothird;
    749   nothird.set_response().set_aa()
    750     .add_question(new DNSQuestion("www.third.gov", T_A));
    751   ON_CALL(server_, OnRequest("www.third.gov", T_A))
    752     .WillByDefault(SetReply(&server_, &nothird));
    753   DNSPacket nobare;
    754   nobare.set_response().set_aa()
    755     .add_question(new DNSQuestion("www", T_A));
    756   ON_CALL(server_, OnRequest("www", T_A))
    757     .WillByDefault(SetReply(&server_, &nobare));
    758 
    759   HostResult result;
    760   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
    761   Process();
    762   EXPECT_TRUE(result.done_);
    763   EXPECT_EQ(ARES_ENODATA, result.status_);
    764 }
    765 
    766 TEST_P(MockEventThreadTest, SearchNoDataThenFail) {
    767   // First two search domains recognize the name but have no A records.
    768   DNSPacket nofirst;
    769   nofirst.set_response().set_aa()
    770     .add_question(new DNSQuestion("www.first.com", T_A));
    771   ON_CALL(server_, OnRequest("www.first.com", T_A))
    772     .WillByDefault(SetReply(&server_, &nofirst));
    773   DNSPacket nosecond;
    774   nosecond.set_response().set_aa()
    775     .add_question(new DNSQuestion("www.second.org", T_A));
    776   ON_CALL(server_, OnRequest("www.second.org", T_A))
    777     .WillByDefault(SetReply(&server_, &nosecond));
    778   DNSPacket nothird;
    779   nothird.set_response().set_aa()
    780     .add_question(new DNSQuestion("www.third.gov", T_A));
    781   ON_CALL(server_, OnRequest("www.third.gov", T_A))
    782     .WillByDefault(SetReply(&server_, &nothird));
    783   DNSPacket nobare;
    784   nobare.set_response().set_aa().set_rcode(NXDOMAIN)
    785     .add_question(new DNSQuestion("www", T_A));
    786   ON_CALL(server_, OnRequest("www", T_A))
    787     .WillByDefault(SetReply(&server_, &nobare));
    788 
    789   HostResult result;
    790   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
    791   Process();
    792   EXPECT_TRUE(result.done_);
    793   EXPECT_EQ(ARES_ENODATA, result.status_);
    794 }
    795 
    796 TEST_P(MockEventThreadTest, SearchHighNdots) {
    797   DNSPacket nobare;
    798   nobare.set_response().set_aa().set_rcode(NXDOMAIN)
    799     .add_question(new DNSQuestion("a.b.c.w.w.w", T_A));
    800   ON_CALL(server_, OnRequest("a.b.c.w.w.w", T_A))
    801     .WillByDefault(SetReply(&server_, &nobare));
    802   DNSPacket yesfirst;
    803   yesfirst.set_response().set_aa()
    804     .add_question(new DNSQuestion("a.b.c.w.w.w.first.com", T_A))
    805     .add_answer(new DNSARR("a.b.c.w.w.w.first.com", 0x0200, {2, 3, 4, 5}));
    806   ON_CALL(server_, OnRequest("a.b.c.w.w.w.first.com", T_A))
    807     .WillByDefault(SetReply(&server_, &yesfirst));
    808 
    809   SearchResult result;
    810   ares_search(channel_, "a.b.c.w.w.w", C_IN, T_A, SearchCallback, &result);
    811   Process();
    812   EXPECT_TRUE(result.done_);
    813   EXPECT_EQ(ARES_SUCCESS, result.status_);
    814   std::stringstream ss;
    815   ss << PacketToString(result.data_);
    816   EXPECT_EQ("RSP QRY AA NOERROR Q:{'a.b.c.w.w.w.first.com' IN A} "
    817             "A:{'a.b.c.w.w.w.first.com' IN A TTL=512 2.3.4.5}",
    818             ss.str());
    819 }
    820 
    821 TEST_P(MockEventThreadTest, V4WorksV6Timeout) {
    822   std::vector<byte> nothing;
    823   DNSPacket reply;
    824   reply.set_response().set_aa()
    825     .add_question(new DNSQuestion("www.google.com", T_A))
    826     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
    827 
    828   ON_CALL(server_, OnRequest("www.google.com", T_A))
    829     .WillByDefault(SetReply(&server_, &reply));
    830 
    831   ON_CALL(server_, OnRequest("www.google.com", T_AAAA))
    832     .WillByDefault(SetReplyData(&server_, nothing));
    833 
    834   HostResult result;
    835   ares_gethostbyname(channel_, "www.google.com.", AF_UNSPEC, HostCallback, &result);
    836   Process();
    837   EXPECT_TRUE(result.done_);
    838   EXPECT_EQ(1, result.timeouts_);
    839   std::stringstream ss;
    840   ss << result.host_;
    841   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
    842 }
    843 
    844 TEST_P(MockEventThreadTest, DestroyQuick) {
    845   /* We are not looking for any particular result as its possible (but unlikely)
    846    * it finished before the destroy completed. We really just want to make sure
    847    * cleanup works in this case properly. */
    848   HostResult result;
    849   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
    850   ares_destroy(channel_);
    851   channel_ = nullptr;
    852   EXPECT_TRUE(result.done_);
    853 }
    854 
    855 // Test case for Issue #662
    856 TEST_P(MockEventThreadTest, PartialQueryCancel) {
    857   std::vector<byte> nothing;
    858   DNSPacket reply;
    859   reply.set_response().set_aa()
    860     .add_question(new DNSQuestion("www.google.com", T_A))
    861     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
    862 
    863   ON_CALL(server_, OnRequest("www.google.com", T_A))
    864     .WillByDefault(SetReply(&server_, &reply));
    865 
    866   ON_CALL(server_, OnRequest("www.google.com", T_AAAA))
    867     .WillByDefault(SetReplyData(&server_, nothing));
    868 
    869   HostResult result;
    870   ares_gethostbyname(channel_, "www.google.com.", AF_UNSPEC, HostCallback, &result);
    871   // After 100ms, issues ares_cancel(), this should be enough time for the A
    872   // record reply, but before the timeout on the AAAA record.
    873   Process(100);
    874   EXPECT_TRUE(result.done_);
    875   EXPECT_EQ(ARES_ECANCELLED, result.status_);
    876 }
    877 
    878 // Test case for Issue #798, we're really looking for a crash, the results
    879 // don't matter.  Should either be successful or canceled.
    880 TEST_P(MockEventThreadTest, BulkCancel) {
    881   std::vector<byte> nothing;
    882   DNSPacket reply;
    883   reply.set_response().set_aa()
    884     .add_question(new DNSQuestion("www.google.com", T_A))
    885     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
    886 
    887   ON_CALL(server_, OnRequest("www.google.com", T_A))
    888     .WillByDefault(SetReply(&server_, &reply));
    889 
    890 #define BULKCANCEL_LOOP 5
    891 #define BULKCANCEL_CNT 50
    892   for (size_t l = 0; l<BULKCANCEL_LOOP; l++) {
    893     HostResult result[BULKCANCEL_CNT];
    894     for (size_t i = 0; i<BULKCANCEL_CNT; i++) {
    895       ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result[i]);
    896     }
    897     // After 1ms, issues ares_cancel(), there should be queries outstanding that
    898     // are cancelled.
    899     Process(1);
    900 
    901     size_t success_cnt = 0;
    902     size_t cancel_cnt = 0;
    903     for (size_t i = 0; i<BULKCANCEL_CNT; i++) {
    904       EXPECT_TRUE(result[i].done_);
    905       EXPECT_TRUE(result[i].status_ == ARES_ECANCELLED || result[i].status_ == ARES_SUCCESS);
    906       if (result[i].done_ && result[i].status_ == ARES_SUCCESS)
    907         success_cnt++;
    908       if (result[i].done_ && result[i].status_ == ARES_ECANCELLED)
    909         cancel_cnt++;
    910     }
    911     if (verbose) std::cerr << "success: " << success_cnt << ", cancel: " << cancel_cnt << std::endl;
    912   }
    913 }
    914 
    915 TEST_P(MockEventThreadTest, UnspecifiedFamilyV6) {
    916   DNSPacket rsp6;
    917   rsp6.set_response().set_aa()
    918     .add_question(new DNSQuestion("example.com", T_AAAA))
    919     .add_answer(new DNSAaaaRR("example.com", 100,
    920                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    921                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
    922   ON_CALL(server_, OnRequest("example.com", T_AAAA))
    923     .WillByDefault(SetReply(&server_, &rsp6));
    924 
    925   DNSPacket rsp4;
    926   rsp4.set_response().set_aa()
    927     .add_question(new DNSQuestion("example.com", T_A));
    928   ON_CALL(server_, OnRequest("example.com", T_A))
    929     .WillByDefault(SetReply(&server_, &rsp4));
    930 
    931   HostResult result;
    932   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
    933   Process();
    934   EXPECT_TRUE(result.done_);
    935   std::stringstream ss;
    936   ss << result.host_;
    937   // Default to IPv6 when both are available.
    938   EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
    939 }
    940 
    941 TEST_P(MockEventThreadTest, UnspecifiedFamilyV4) {
    942   DNSPacket rsp6;
    943   rsp6.set_response().set_aa()
    944     .add_question(new DNSQuestion("example.com", T_AAAA));
    945   ON_CALL(server_, OnRequest("example.com", T_AAAA))
    946     .WillByDefault(SetReply(&server_, &rsp6));
    947   DNSPacket rsp4;
    948   rsp4.set_response().set_aa()
    949     .add_question(new DNSQuestion("example.com", T_A))
    950     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
    951   ON_CALL(server_, OnRequest("example.com", T_A))
    952     .WillByDefault(SetReply(&server_, &rsp4));
    953 
    954   HostResult result;
    955   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
    956   Process();
    957   EXPECT_TRUE(result.done_);
    958   std::stringstream ss;
    959   ss << result.host_;
    960   EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
    961 }
    962 
    963 TEST_P(MockEventThreadTest, UnspecifiedFamilyNoData) {
    964   DNSPacket rsp6;
    965   rsp6.set_response().set_aa()
    966     .add_question(new DNSQuestion("example.com", T_AAAA))
    967     .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
    968   ON_CALL(server_, OnRequest("example.com", T_AAAA))
    969     .WillByDefault(SetReply(&server_, &rsp6));
    970   DNSPacket rsp4;
    971   rsp4.set_response().set_aa()
    972     .add_question(new DNSQuestion("example.com", T_A));
    973   ON_CALL(server_, OnRequest("example.com", T_A))
    974     .WillByDefault(SetReply(&server_, &rsp4));
    975 
    976   HostResult result;
    977   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
    978   Process();
    979   EXPECT_TRUE(result.done_);
    980   std::stringstream ss;
    981   ss << result.host_;
    982   EXPECT_EQ("{'' aliases=[] addrs=[]}", ss.str());
    983 }
    984 
    985 TEST_P(MockEventThreadTest, UnspecifiedFamilyCname6A4) {
    986   DNSPacket rsp6;
    987   rsp6.set_response().set_aa()
    988     .add_question(new DNSQuestion("example.com", T_AAAA))
    989     .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
    990   ON_CALL(server_, OnRequest("example.com", T_AAAA))
    991     .WillByDefault(SetReply(&server_, &rsp6));
    992   DNSPacket rsp4;
    993   rsp4.set_response().set_aa()
    994     .add_question(new DNSQuestion("example.com", T_A))
    995     .add_answer(new DNSARR("example.com", 100, {1, 2, 3, 4}));
    996   ON_CALL(server_, OnRequest("example.com", T_A))
    997     .WillByDefault(SetReply(&server_, &rsp4));
    998 
    999   HostResult result;
   1000   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
   1001   Process();
   1002   EXPECT_TRUE(result.done_);
   1003   std::stringstream ss;
   1004   ss << result.host_;
   1005   EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
   1006 }
   1007 
   1008 TEST_P(MockEventThreadTest, ExplicitIP) {
   1009   HostResult result;
   1010   ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
   1011   EXPECT_TRUE(result.done_);  // Immediate return
   1012   EXPECT_EQ(ARES_SUCCESS, result.status_);
   1013   std::stringstream ss;
   1014   ss << result.host_;
   1015   EXPECT_EQ("{'1.2.3.4' aliases=[] addrs=[1.2.3.4]}", ss.str());
   1016 }
   1017 
   1018 TEST_P(MockEventThreadTest, SortListV4) {
   1019   DNSPacket rsp;
   1020   rsp.set_response().set_aa()
   1021     .add_question(new DNSQuestion("example.com", T_A))
   1022     .add_answer(new DNSARR("example.com", 100, {22, 23, 24, 25}))
   1023     .add_answer(new DNSARR("example.com", 100, {12, 13, 14, 15}))
   1024     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
   1025   ON_CALL(server_, OnRequest("example.com", T_A))
   1026     .WillByDefault(SetReply(&server_, &rsp));
   1027 
   1028   {
   1029     EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "12.13.0.0/255.255.0.0 1234::5678"));
   1030     HostResult result;
   1031     ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
   1032     Process();
   1033     EXPECT_TRUE(result.done_);
   1034     std::stringstream ss;
   1035     ss << result.host_;
   1036     EXPECT_EQ("{'example.com' aliases=[] addrs=[12.13.14.15, 22.23.24.25, 2.3.4.5]}", ss.str());
   1037   }
   1038   {
   1039     EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "2.3.0.0/16 130.140.150.160/26"));
   1040     HostResult result;
   1041     ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
   1042     Process();
   1043     EXPECT_TRUE(result.done_);
   1044     std::stringstream ss;
   1045     ss << result.host_;
   1046     EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5, 22.23.24.25, 12.13.14.15]}", ss.str());
   1047   }
   1048   struct ares_options options;
   1049   memset(&options, 0, sizeof(options));
   1050   int optmask = 0;
   1051   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &options, &optmask));
   1052   EXPECT_TRUE((optmask & ARES_OPT_SORTLIST) == ARES_OPT_SORTLIST);
   1053   ares_destroy_options(&options);
   1054 }
   1055 
   1056 TEST_P(MockEventThreadTest, SortListV6) {
   1057   DNSPacket rsp;
   1058   rsp.set_response().set_aa()
   1059     .add_question(new DNSQuestion("example.com", T_AAAA))
   1060     .add_answer(new DNSAaaaRR("example.com", 100,
   1061                               {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   1062                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02}))
   1063     .add_answer(new DNSAaaaRR("example.com", 100,
   1064                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   1065                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
   1066   ON_CALL(server_, OnRequest("example.com", T_AAAA))
   1067     .WillByDefault(SetReply(&server_, &rsp));
   1068 
   1069   {
   1070     ares_set_sortlist(channel_, "1111::/16 2.3.0.0/255.255.0.0");
   1071     HostResult result;
   1072     ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
   1073     Process();
   1074     EXPECT_TRUE(result.done_);
   1075     std::stringstream ss;
   1076     ss << result.host_;
   1077     EXPECT_EQ("{'example.com' aliases=[] addrs=[1111:0000:0000:0000:0000:0000:0000:0202, "
   1078               "2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
   1079   }
   1080   {
   1081     ares_set_sortlist(channel_, "2121::/8");
   1082     HostResult result;
   1083     ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
   1084     Process();
   1085     EXPECT_TRUE(result.done_);
   1086     std::stringstream ss;
   1087     ss << result.host_;
   1088     EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303, "
   1089               "1111:0000:0000:0000:0000:0000:0000:0202]}", ss.str());
   1090   }
   1091 }
   1092 
   1093 // Relies on retries so is UDP-only
   1094 TEST_P(MockUDPEventThreadTest, Resend) {
   1095   std::vector<byte> nothing;
   1096   DNSPacket reply;
   1097   reply.set_response().set_aa()
   1098     .add_question(new DNSQuestion("www.google.com", T_A))
   1099     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
   1100 
   1101   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
   1102     .WillOnce(SetReplyData(&server_, nothing))
   1103     .WillOnce(SetReplyData(&server_, nothing))
   1104     .WillOnce(SetReply(&server_, &reply));
   1105 
   1106   HostResult result;
   1107   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
   1108   Process();
   1109   EXPECT_TRUE(result.done_);
   1110   EXPECT_EQ(2, result.timeouts_);
   1111   std::stringstream ss;
   1112   ss << result.host_;
   1113   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
   1114 }
   1115 
   1116 TEST_P(MockEventThreadTest, CancelImmediate) {
   1117   HostResult result;
   1118   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
   1119   ares_cancel(channel_);
   1120   EXPECT_TRUE(result.done_);
   1121   EXPECT_EQ(ARES_ECANCELLED, result.status_);
   1122   EXPECT_EQ(0, result.timeouts_);
   1123 }
   1124 
   1125 TEST_P(MockEventThreadTest, CancelImmediateGetHostByAddr) {
   1126   HostResult result;
   1127   struct in_addr addr;
   1128   addr.s_addr = htonl(0x08080808);
   1129 
   1130   ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
   1131   ares_cancel(channel_);
   1132   EXPECT_TRUE(result.done_);
   1133   EXPECT_EQ(ARES_ECANCELLED, result.status_);
   1134   EXPECT_EQ(0, result.timeouts_);
   1135 }
   1136 
   1137 // Relies on retries so is UDP-only
   1138 TEST_P(MockUDPEventThreadTest, CancelLater) {
   1139   std::vector<byte> nothing;
   1140 
   1141   // On second request, cancel the channel.
   1142   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
   1143     .WillOnce(SetReplyData(&server_, nothing))
   1144     .WillOnce(CancelChannel(&server_, channel_));
   1145 
   1146   HostResult result;
   1147   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
   1148   Process();
   1149   EXPECT_TRUE(result.done_);
   1150   EXPECT_EQ(ARES_ECANCELLED, result.status_);
   1151   EXPECT_EQ(0, result.timeouts_);
   1152 }
   1153 
   1154 TEST_P(MockEventThreadTest, DisconnectFirstAttempt) {
   1155   DNSPacket reply;
   1156   reply.set_response().set_aa()
   1157     .add_question(new DNSQuestion("www.google.com", T_A))
   1158     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
   1159 
   1160   // On second request, cancel the channel.
   1161   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
   1162     .WillOnce(Disconnect(&server_))
   1163     .WillOnce(SetReply(&server_, &reply));
   1164 
   1165   HostResult result;
   1166   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
   1167   Process();
   1168   EXPECT_TRUE(result.done_);
   1169   if (result.done_) {
   1170     std::stringstream ss;
   1171     ss << result.host_;
   1172     EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
   1173   }
   1174 }
   1175 
   1176 TEST_P(MockEventThreadTest, GetHostByNameCNAMENoData) {
   1177   DNSPacket response;
   1178   response.set_response().set_aa()
   1179     .add_question(new DNSQuestion("cname.first.com", T_A))
   1180     .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com"));
   1181   ON_CALL(server_, OnRequest("cname.first.com", T_A))
   1182     .WillByDefault(SetReply(&server_, &response));
   1183 
   1184   HostResult result;
   1185   ares_gethostbyname(channel_, "cname.first.com.", AF_INET, HostCallback, &result);
   1186   Process();
   1187   EXPECT_TRUE(result.done_);
   1188   EXPECT_EQ(ARES_ENODATA, result.status_);
   1189 }
   1190 
   1191 #ifndef WIN32
   1192 TEST_P(MockEventThreadTest, HostAlias) {
   1193   DNSPacket reply;
   1194   reply.set_response().set_aa()
   1195     .add_question(new DNSQuestion("www.google.com", T_A))
   1196     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
   1197   ON_CALL(server_, OnRequest("www.google.com", T_A))
   1198     .WillByDefault(SetReply(&server_, &reply));
   1199 
   1200   TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
   1201   EnvValue with_env("HOSTALIASES", aliases.filename());
   1202 
   1203   HostResult result;
   1204   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
   1205   Process();
   1206   EXPECT_TRUE(result.done_);
   1207   std::stringstream ss;
   1208   ss << result.host_;
   1209   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
   1210 }
   1211 
   1212 TEST_P(MockEventThreadTest, HostAliasMissing) {
   1213   DNSPacket yesfirst;
   1214   yesfirst.set_response().set_aa()
   1215     .add_question(new DNSQuestion("www.first.com", T_A))
   1216     .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
   1217   ON_CALL(server_, OnRequest("www.first.com", T_A))
   1218     .WillByDefault(SetReply(&server_, &yesfirst));
   1219 
   1220   TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
   1221   EnvValue with_env("HOSTALIASES", aliases.filename());
   1222   HostResult result;
   1223   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
   1224   Process();
   1225   EXPECT_TRUE(result.done_);
   1226   std::stringstream ss;
   1227   ss << result.host_;
   1228   EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
   1229 }
   1230 
   1231 TEST_P(MockEventThreadTest, HostAliasMissingFile) {
   1232   DNSPacket yesfirst;
   1233   yesfirst.set_response().set_aa()
   1234     .add_question(new DNSQuestion("www.first.com", T_A))
   1235     .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
   1236   ON_CALL(server_, OnRequest("www.first.com", T_A))
   1237     .WillByDefault(SetReply(&server_, &yesfirst));
   1238 
   1239   EnvValue with_env("HOSTALIASES", "bogus.mcfile");
   1240   HostResult result;
   1241   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
   1242   Process();
   1243   EXPECT_TRUE(result.done_);
   1244   std::stringstream ss;
   1245   ss << result.host_;
   1246   EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
   1247 }
   1248 
   1249 TEST_P(MockEventThreadTest, HostAliasUnreadable) {
   1250   TempFile aliases("www www.google.com\n");
   1251   EXPECT_EQ(chmod(aliases.filename(), 0), 0);
   1252 
   1253   /* Perform OS sanity checks.  We are observing on Debian after the chmod(fn, 0)
   1254    * that we are still able to fopen() the file which is unexpected.  Skip the
   1255    * test if we observe this behavior */
   1256   struct stat st;
   1257   EXPECT_EQ(stat(aliases.filename(), &st), 0);
   1258   EXPECT_EQ(st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO), 0);
   1259   FILE *fp = fopen(aliases.filename(), "r");
   1260   if (fp != NULL) {
   1261     if (verbose) std::cerr << "Skipping Test due to OS incompatibility (open file caching)" << std::endl;
   1262     fclose(fp);
   1263     return;
   1264   }
   1265 
   1266   EnvValue with_env("HOSTALIASES", aliases.filename());
   1267 
   1268   HostResult result;
   1269   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
   1270   Process();
   1271   EXPECT_TRUE(result.done_);
   1272   EXPECT_EQ(ARES_EFILE, result.status_);
   1273   chmod(aliases.filename(), 0777);
   1274 }
   1275 #endif
   1276 
   1277 
   1278 class MockMultiServerEventThreadTest
   1279   : public MockEventThreadOptsTest,
   1280     public ::testing::WithParamInterface< std::tuple<ares_evsys_t, int, bool> > {
   1281  public:
   1282   MockMultiServerEventThreadTest(ares_options *opts, int optmask)
   1283     : MockEventThreadOptsTest(3, std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()), opts, optmask) {}
   1284   void CheckExample() {
   1285     HostResult result;
   1286     ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
   1287     Process();
   1288     EXPECT_TRUE(result.done_);
   1289     std::stringstream ss;
   1290     ss << result.host_;
   1291     EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
   1292   }
   1293 };
   1294 
   1295 class NoRotateMultiMockEventThreadTest : public MockMultiServerEventThreadTest {
   1296  public:
   1297   NoRotateMultiMockEventThreadTest() : MockMultiServerEventThreadTest(nullptr, ARES_OPT_NOROTATE) {}
   1298 };
   1299 
   1300 
   1301 TEST_P(NoRotateMultiMockEventThreadTest, ThirdServer) {
   1302   struct ares_options opts;
   1303   int optmask = 0;
   1304   memset(&opts, 0, sizeof(opts));
   1305   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
   1306   EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
   1307   ares_destroy_options(&opts);
   1308 
   1309   DNSPacket servfailrsp;
   1310   servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
   1311     .add_question(new DNSQuestion("www.example.com", T_A));
   1312   DNSPacket notimplrsp;
   1313   notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
   1314     .add_question(new DNSQuestion("www.example.com", T_A));
   1315   DNSPacket okrsp;
   1316   okrsp.set_response().set_aa()
   1317     .add_question(new DNSQuestion("www.example.com", T_A))
   1318     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
   1319 
   1320   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1321     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
   1322   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1323     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
   1324   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1325     .WillOnce(SetReply(servers_[2].get(), &okrsp));
   1326   CheckExample();
   1327 
   1328   // Second time around, still starts from server [2], as [0] and [1] both
   1329   // recorded failures
   1330   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1331     .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
   1332   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1333     .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
   1334   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1335     .WillOnce(SetReply(servers_[1].get(), &okrsp));
   1336   CheckExample();
   1337 
   1338   // Third time around, server order is [1] (f0), [2] (f1), [0] (f2), which
   1339   // means [1] will get called twice in a row as after the first call
   1340   // order will be  [1] (f1), [2] (f1), [0] (f2) since sort order is
   1341   // (failure count, index)
   1342   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1343     .WillOnce(SetReply(servers_[1].get(), &servfailrsp))
   1344     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
   1345   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1346     .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
   1347   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1348     .WillOnce(SetReply(servers_[0].get(), &okrsp));
   1349   CheckExample();
   1350 }
   1351 
   1352 TEST_P(NoRotateMultiMockEventThreadTest, ServerNoResponseFailover) {
   1353   std::vector<byte> nothing;
   1354   DNSPacket okrsp;
   1355   okrsp.set_response().set_aa()
   1356     .add_question(new DNSQuestion("www.example.com", T_A))
   1357     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
   1358 
   1359   /* Server #1 works fine on first attempt, then acts like its offline on
   1360    * second, then backonline on the third. */
   1361   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1362     .WillOnce(SetReply(servers_[0].get(), &okrsp))
   1363     .WillOnce(SetReplyData(servers_[0].get(), nothing))
   1364     .WillOnce(SetReply(servers_[0].get(), &okrsp));
   1365 
   1366   /* Server #2 always acts like its offline */
   1367   ON_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1368     .WillByDefault(SetReplyData(servers_[1].get(), nothing));
   1369 
   1370   /* Server #3 works fine on first and second request, then no reply on 3rd */
   1371   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1372     .WillOnce(SetReply(servers_[2].get(), &okrsp))
   1373     .WillOnce(SetReply(servers_[2].get(), &okrsp))
   1374     .WillOnce(SetReplyData(servers_[2].get(), nothing));
   1375 
   1376   HostResult result;
   1377 
   1378   /* 1. First server returns a response on the first request immediately, normal
   1379    *    operation on channel. */
   1380   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
   1381   Process();
   1382   EXPECT_TRUE(result.done_);
   1383   EXPECT_EQ(0, result.timeouts_);
   1384   std::stringstream ss1;
   1385   ss1 << result.host_;
   1386   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
   1387 
   1388   /* 2. On the second request, simulate the first and second servers not
   1389    *    returning a response at all, but the 3rd server works, so should have
   1390    *    2 timeouts. */
   1391   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
   1392   Process();
   1393   EXPECT_TRUE(result.done_);
   1394   EXPECT_EQ(2, result.timeouts_);
   1395   std::stringstream ss2;
   1396   ss2 << result.host_;
   1397   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss2.str());
   1398 
   1399   /* 3. On the third request, the active server should be #3, so should respond
   1400    *    immediately with no timeouts */
   1401   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
   1402   Process();
   1403   EXPECT_TRUE(result.done_);
   1404   EXPECT_EQ(0, result.timeouts_);
   1405   std::stringstream ss3;
   1406   ss3 << result.host_;
   1407   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
   1408 
   1409   /* 4. On the fourth request, the active server should be #3, but will timeout,
   1410    *    and the first server should then respond */
   1411   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
   1412   Process();
   1413   EXPECT_TRUE(result.done_);
   1414   EXPECT_EQ(1, result.timeouts_);
   1415   std::stringstream ss4;
   1416   ss4 << result.host_;
   1417   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss4.str());
   1418 }
   1419 
   1420 #if defined(_WIN32)
   1421 #  define SERVER_FAILOVER_RETRY_DELAY 500
   1422 #else
   1423 #  define SERVER_FAILOVER_RETRY_DELAY 330
   1424 #endif
   1425 
   1426 
   1427 class ServerFailoverOptsMockEventThreadTest
   1428   : public MockEventThreadOptsTest,
   1429     public ::testing::WithParamInterface<std::tuple<ares_evsys_t, int, bool> > {
   1430  public:
   1431   ServerFailoverOptsMockEventThreadTest()
   1432     : MockEventThreadOptsTest(4, std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()),
   1433                           FillOptions(&opts_),
   1434                           ARES_OPT_SERVER_FAILOVER | ARES_OPT_NOROTATE) {}
   1435   void CheckExample() {
   1436     HostResult result;
   1437     ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
   1438     Process();
   1439     EXPECT_TRUE(result.done_);
   1440     std::stringstream ss;
   1441     ss << result.host_;
   1442     EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
   1443   }
   1444 
   1445   static struct ares_options* FillOptions(struct ares_options *opts) {
   1446     memset(opts, 0, sizeof(struct ares_options));
   1447     opts->server_failover_opts.retry_chance = 1;
   1448     opts->server_failover_opts.retry_delay = SERVER_FAILOVER_RETRY_DELAY;
   1449     return opts;
   1450   }
   1451  private:
   1452   struct ares_options opts_;
   1453 };
   1454 
   1455 // Test case to trigger server failover behavior. We use a retry chance of
   1456 // 100% and a retry delay so that we can test behavior reliably.
   1457 TEST_P(ServerFailoverOptsMockEventThreadTest, ServerFailoverOpts) {
   1458   DNSPacket servfailrsp;
   1459   servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
   1460     .add_question(new DNSQuestion("www.example.com", T_A));
   1461   DNSPacket okrsp;
   1462   okrsp.set_response().set_aa()
   1463     .add_question(new DNSQuestion("www.example.com", T_A))
   1464     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
   1465 
   1466   auto tv_begin = std::chrono::high_resolution_clock::now();
   1467   auto tv_now   = std::chrono::high_resolution_clock::now();
   1468   unsigned int delay_ms;
   1469 
   1470   // At start all servers are healthy, first server should be selected
   1471   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: First server should be selected" << std::endl;
   1472   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1473     .WillOnce(SetReply(servers_[0].get(), &okrsp));
   1474   CheckExample();
   1475 
   1476   // Fail server #0 but leave server #1 as healthy.  This results in server
   1477   // order:
   1478   //  #1 (failures: 0), #2 (failures: 0), #3 (failures: 0), #0 (failures: 1)
   1479   tv_now = std::chrono::high_resolution_clock::now();
   1480   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Server0 will fail but leave Server1 as healthy" << std::endl;
   1481   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1482     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
   1483   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1484     .WillOnce(SetReply(servers_[1].get(), &okrsp));
   1485   CheckExample();
   1486 
   1487   // Sleep for the retry delay (actually a little more than the retry delay to account
   1488   // for unreliable timing, e.g. NTP slew) and send in another query. The real
   1489   // query will be sent to Server #1 (which will succeed) and Server #0 will
   1490   // be probed and return a successful result.  This leaves the server order
   1491   // of:
   1492   //   #0 (failures: 0), #1 (failures: 0), #2 (failures: 0), #3 (failures: 0)
   1493   tv_now = std::chrono::high_resolution_clock::now();
   1494   delay_ms = SERVER_FAILOVER_RETRY_DELAY + (SERVER_FAILOVER_RETRY_DELAY / 10);
   1495   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
   1496   ares_sleep_time(delay_ms);
   1497   tv_now = std::chrono::high_resolution_clock::now();
   1498   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Server0 should be past retry delay and should be probed (successful), server 1 will respond successful for real query" << std::endl;
   1499   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1500     .WillOnce(SetReply(servers_[0].get(), &okrsp));
   1501   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1502     .WillOnce(SetReply(servers_[1].get(), &okrsp));
   1503   CheckExample();
   1504 
   1505 
   1506   // Fail all servers for the first round of tries. On the second round, #0
   1507   // responds successfully. This should leave server order of:
   1508   //   #1 (failures: 0), #2 (failures: 1), #3 (failures: 1), #0 (failures: 2)
   1509   // NOTE: A single query being retried won't spawn probes to downed servers,
   1510   //       only an initial query attempt is eligible to spawn probes.  So
   1511   //       no probes are sent for this test.
   1512   tv_now = std::chrono::high_resolution_clock::now();
   1513   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: All 4 servers will fail on the first attempt, server 0 will fail on second. Server 1 will succeed on second." << std::endl;
   1514   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1515     .WillOnce(SetReply(servers_[0].get(), &servfailrsp))
   1516     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
   1517   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1518     .WillOnce(SetReply(servers_[1].get(), &servfailrsp))
   1519     .WillOnce(SetReply(servers_[1].get(), &okrsp));
   1520   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1521     .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
   1522   EXPECT_CALL(*servers_[3], OnRequest("www.example.com", T_A))
   1523     .WillOnce(SetReply(servers_[3].get(), &servfailrsp));
   1524   CheckExample();
   1525 
   1526 
   1527   // Sleep for the retry delay and send in another query. Server #1 is the
   1528   // highest priority server and will respond with success, however a probe
   1529   // will be sent for Server #2 which will succeed:
   1530   //  #1 (failures: 0), #2 (failures: 0), #3 (failures: 1 - expired), #0 (failures: 2 - expired)
   1531   tv_now = std::chrono::high_resolution_clock::now();
   1532   delay_ms = SERVER_FAILOVER_RETRY_DELAY + (SERVER_FAILOVER_RETRY_DELAY / 10);
   1533   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
   1534   ares_sleep_time(delay_ms);
   1535   tv_now = std::chrono::high_resolution_clock::now();
   1536   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Past retry delay, will query Server 1 and probe Server 2, both will succeed." << std::endl;
   1537   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1538     .WillOnce(SetReply(servers_[1].get(), &okrsp));
   1539   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1540     .WillOnce(SetReply(servers_[2].get(), &okrsp));
   1541   CheckExample();
   1542 
   1543   // Cause another server to fail so we have at least one non-expired failed
   1544   // server and one expired failed server.  #1 is highest priority, which we
   1545   // will fail, #2 will succeed, and #3 will be probed and succeed:
   1546   //  #2 (failures: 0), #3 (failures: 0), #1 (failures: 1 not expired), #0 (failures: 2 expired)
   1547   tv_now = std::chrono::high_resolution_clock::now();
   1548   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Will query Server 1 and fail, Server 2 will answer successfully. Server 3 will be probed and succeed." << std::endl;
   1549   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1550     .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
   1551   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1552     .WillOnce(SetReply(servers_[2].get(), &okrsp));
   1553   EXPECT_CALL(*servers_[3], OnRequest("www.example.com", T_A))
   1554     .WillOnce(SetReply(servers_[3].get(), &okrsp));
   1555   CheckExample();
   1556 
   1557   // We need to make sure that if there is a failed server that is higher priority
   1558   // but not yet expired that it will probe the next failed server instead.
   1559   // In this case #2 is the server that the query will go to and succeed, and
   1560   // then a probe will be sent for #0 (since #1 is not expired) and succeed.  We
   1561   // will sleep for 1/4 the retry duration before spawning the queries so we can
   1562   // then sleep for the rest for the follow-up test.  This will leave the servers
   1563   // in this state:
   1564   //   #0 (failures: 0), #2 (failures: 0), #3 (failures: 0), #1 (failures: 1 not expired)
   1565   tv_now = std::chrono::high_resolution_clock::now();
   1566 
   1567   // We need to track retry delay time to know what is expired when.
   1568   auto elapse_start = tv_now;
   1569 
   1570   delay_ms = (SERVER_FAILOVER_RETRY_DELAY/4);
   1571   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
   1572   ares_sleep_time(delay_ms);
   1573   tv_now = std::chrono::high_resolution_clock::now();
   1574 
   1575   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Retry delay has not been hit yet. Server2 will be queried and succeed. Server 0 (not server 1 due to non-expired retry delay) will be probed and succeed." << std::endl;
   1576   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1577     .WillOnce(SetReply(servers_[2].get(), &okrsp));
   1578   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1579     .WillOnce(SetReply(servers_[0].get(), &okrsp));
   1580   CheckExample();
   1581 
   1582   // Finally we sleep for the remainder of the retry delay, send another
   1583   // query, which should succeed on Server #0, and also probe Server #1 which
   1584   // will also succeed.
   1585   tv_now = std::chrono::high_resolution_clock::now();
   1586 
   1587   unsigned int elapsed_time = (unsigned int)std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - elapse_start).count();
   1588   delay_ms = (SERVER_FAILOVER_RETRY_DELAY) + (SERVER_FAILOVER_RETRY_DELAY / 10);
   1589   if (elapsed_time > delay_ms) {
   1590     if (verbose) std::cerr << "elapsed duration " << elapsed_time << "ms greater than desired delay of " << delay_ms << "ms, not sleeping" << std::endl;
   1591   } else {
   1592     delay_ms -= elapsed_time; // subtract already elapsed time
   1593     if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: sleep " << delay_ms << "ms" << std::endl;
   1594     ares_sleep_time(delay_ms);
   1595   }
   1596   tv_now = std::chrono::high_resolution_clock::now();
   1597   if (verbose) std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(tv_now - tv_begin).count() << "ms: Retry delay has expired on Server1, Server 0 will be queried and succeed, Server 1 will be probed and succeed." << std::endl;
   1598   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1599     .WillOnce(SetReply(servers_[0].get(), &okrsp));
   1600   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1601     .WillOnce(SetReply(servers_[1].get(), &okrsp));
   1602   CheckExample();
   1603 }
   1604 
   1605 static const char *evsys_tostr(ares_evsys_t evsys)
   1606 {
   1607   switch (evsys) {
   1608     case ARES_EVSYS_WIN32:
   1609       return "WIN32";
   1610     case ARES_EVSYS_EPOLL:
   1611       return "EPOLL";
   1612     case ARES_EVSYS_KQUEUE:
   1613       return "KQUEUE";
   1614     case ARES_EVSYS_POLL:
   1615       return "POLL";
   1616     case ARES_EVSYS_SELECT:
   1617       return "SELECT";
   1618     case ARES_EVSYS_DEFAULT:
   1619       return "DEFAULT";
   1620   }
   1621   return "UNKNOWN";
   1622 }
   1623 
   1624 
   1625 static std::string PrintEvsysFamilyMode(const testing::TestParamInfo<std::tuple<ares_evsys_t, int, bool>> &info)
   1626 {
   1627   std::string name;
   1628 
   1629   name += evsys_tostr(std::get<0>(info.param));
   1630   name += "_";
   1631   name += af_tostr(std::get<1>(info.param));
   1632   name += "_";
   1633   name += mode_tostr(std::get<2>(info.param));
   1634   return name;
   1635 }
   1636 
   1637 static std::string PrintEvsysFamily(const testing::TestParamInfo<std::tuple<ares_evsys_t, int>> &info)
   1638 {
   1639   std::string name;
   1640 
   1641   name += evsys_tostr(std::get<0>(info.param));
   1642   name += "_";
   1643   name += af_tostr(std::get<1>(info.param));
   1644   return name;
   1645 }
   1646 
   1647 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families_modes), ares::test::PrintEvsysFamilyMode);
   1648 
   1649 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families), ares::test::PrintEvsysFamily);
   1650 
   1651 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPEventThreadMaxQueriesTest, ::testing::ValuesIn(ares::test::evsys_families), ares::test::PrintEvsysFamily);
   1652 
   1653 INSTANTIATE_TEST_SUITE_P(AddressFamilies, CacheQueriesEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families), ares::test::PrintEvsysFamily);
   1654 
   1655 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockTCPEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families), ares::test::PrintEvsysFamily);
   1656 
   1657 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockTCPEventThreadStayOpenTest, ::testing::ValuesIn(ares::test::evsys_families), ares::test::PrintEvsysFamily);
   1658 
   1659 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockExtraOptsEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families_modes), ares::test::PrintEvsysFamilyMode);
   1660 
   1661 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockNoCheckRespEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families_modes), ares::test::PrintEvsysFamilyMode);
   1662 
   1663 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockEDNSEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families_modes), ares::test::PrintEvsysFamilyMode);
   1664 
   1665 INSTANTIATE_TEST_SUITE_P(TransportModes, NoRotateMultiMockEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families_modes), ares::test::PrintEvsysFamilyMode);
   1666 
   1667 INSTANTIATE_TEST_SUITE_P(TransportModes, ServerFailoverOptsMockEventThreadTest, ::testing::ValuesIn(ares::test::evsys_families_modes), ares::test::PrintEvsysFamilyMode);
   1668 
   1669 #if 0
   1670 INSTANTIATE_TEST_SUITE_P(AddressFamilies, MockUDPEventThreadSingleQueryPerConnTest, ::testing::ValuesIn(ares::test::evsys_families), ares::test::PrintEvsysFamily);
   1671 #endif
   1672 
   1673 }  // namespace test
   1674 }  // namespace ares
   1675 
   1676 #endif /* CARES_THREADS */