quickjs-tart

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

ares-test-mock-ai.cc (49562B)


      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-ai.h"
     27 #include "dns-proto.h"
     28 
     29 #ifdef HAVE_NETINET_IN_H
     30 #include <netinet/in.h>
     31 #endif
     32 
     33 #include <sstream>
     34 #include <vector>
     35 
     36 using testing::InvokeWithoutArgs;
     37 using testing::DoAll;
     38 
     39 namespace ares {
     40 namespace test {
     41 
     42 MATCHER_P(IncludesNumAddresses, n, "") {
     43   (void)result_listener;
     44   if(!arg)
     45     return false;
     46   int cnt = 0;
     47   for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next)
     48     cnt++;
     49   return n == cnt;
     50 }
     51 
     52 MATCHER_P(IncludesV4Address, address, "") {
     53   (void)result_listener;
     54   if(!arg)
     55     return false;
     56   in_addr addressnum = {};
     57   if (!ares_inet_pton(AF_INET, address, &addressnum))
     58     return false; // wrong number format?
     59   for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
     60     if (ai->ai_family != AF_INET)
     61       continue;
     62     if (ai->ai_addrlen != sizeof(struct sockaddr_in))
     63       continue;
     64     if (reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr.s_addr ==
     65         addressnum.s_addr)
     66       return true; // found
     67   }
     68   return false;
     69 }
     70 
     71 MATCHER_P(IncludesV6Address, address, "") {
     72   (void)result_listener;
     73   if(!arg)
     74     return false;
     75   in6_addr addressnum = {};
     76   if (!ares_inet_pton(AF_INET6, address, &addressnum)) {
     77     return false; // wrong number format?
     78   }
     79   for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) {
     80     if (ai->ai_family != AF_INET6)
     81       continue;
     82     if (ai->ai_addrlen != sizeof(struct sockaddr_in6))
     83       continue;
     84     if (!memcmp(
     85         reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr.s6_addr,
     86         addressnum.s6_addr, sizeof(addressnum.s6_addr)))
     87       return true; // found
     88   }
     89   return false;
     90 }
     91 
     92 // UDP only so mock server doesn't get confused by concatenated requests
     93 TEST_P(MockUDPChannelTestAI, GetAddrInfoParallelLookups) {
     94   DNSPacket rsp1;
     95   rsp1.set_response().set_aa()
     96     .add_question(new DNSQuestion("www.google.com", T_A))
     97     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
     98   ON_CALL(server_, OnRequest("www.google.com", T_A))
     99     .WillByDefault(SetReply(&server_, &rsp1));
    100   DNSPacket rsp2;
    101   rsp2.set_response().set_aa()
    102     .add_question(new DNSQuestion("www.example.com", T_A))
    103     .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
    104   ON_CALL(server_, OnRequest("www.example.com", T_A))
    105     .WillByDefault(SetReply(&server_, &rsp2));
    106 
    107   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    108   hints.ai_family = AF_INET;
    109   hints.ai_flags = ARES_AI_NOSORT;
    110   AddrInfoResult result1;
    111   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result1);
    112   AddrInfoResult result2;
    113   ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result2);
    114   AddrInfoResult result3;
    115   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result3);
    116   Process();
    117 
    118   EXPECT_TRUE(result1.done_);
    119   EXPECT_EQ(result1.status_, ARES_SUCCESS);
    120   EXPECT_THAT(result1.ai_, IncludesNumAddresses(1));
    121   EXPECT_THAT(result1.ai_, IncludesV4Address("2.3.4.5"));
    122 
    123   EXPECT_TRUE(result2.done_);
    124   EXPECT_EQ(result2.status_, ARES_SUCCESS);
    125   EXPECT_THAT(result2.ai_, IncludesNumAddresses(1));
    126   EXPECT_THAT(result2.ai_, IncludesV4Address("1.2.3.4"));
    127 
    128   EXPECT_TRUE(result3.done_);
    129   EXPECT_EQ(result3.status_, ARES_SUCCESS);
    130   EXPECT_THAT(result3.ai_, IncludesNumAddresses(1));
    131   EXPECT_THAT(result3.ai_, IncludesV4Address("2.3.4.5"));
    132 }
    133 
    134 // UDP to TCP specific test
    135 TEST_P(MockUDPChannelTestAI, TruncationRetry) {
    136   DNSPacket rsptruncated;
    137   rsptruncated.set_response().set_aa().set_tc()
    138     .add_question(new DNSQuestion("www.google.com", T_A));
    139   DNSPacket rspok;
    140   rspok.set_response()
    141     .add_question(new DNSQuestion("www.google.com", T_A))
    142     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
    143   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    144     .WillOnce(SetReply(&server_, &rsptruncated))
    145     .WillOnce(SetReply(&server_, &rspok));
    146 
    147   AddrInfoResult result;
    148   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    149   hints.ai_family = AF_INET;
    150   hints.ai_flags = ARES_AI_NOSORT;
    151   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    152   Process();
    153   EXPECT_TRUE(result.done_);
    154   EXPECT_EQ(result.status_, ARES_SUCCESS);
    155   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    156   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
    157 }
    158 
    159 TEST_P(MockTCPChannelTestAI, MalformedResponse) {
    160   std::vector<byte> one = {0x01};
    161   ON_CALL(server_, OnRequest("www.google.com", T_A))
    162     .WillByDefault(SetReplyData(&server_, one));
    163 
    164   AddrInfoResult result;
    165   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    166   hints.ai_family = AF_INET;
    167   hints.ai_flags = ARES_AI_NOSORT;
    168   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    169   Process();
    170   EXPECT_TRUE(result.done_);
    171   EXPECT_EQ(ARES_EBADRESP, result.status_);
    172 }
    173 
    174 TEST_P(MockTCPChannelTestAI, FormErrResponse) {
    175   DNSPacket rsp;
    176   rsp.set_response().set_aa()
    177     .add_question(new DNSQuestion("www.google.com", T_A));
    178   rsp.set_rcode(FORMERR);
    179   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    180     .WillOnce(SetReply(&server_, &rsp));
    181 
    182   AddrInfoResult result;
    183   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    184   hints.ai_family = AF_INET;
    185   hints.ai_flags = ARES_AI_NOSORT;
    186   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    187   Process();
    188   EXPECT_TRUE(result.done_);
    189   EXPECT_EQ(ARES_EFORMERR, result.status_);
    190 }
    191 
    192 TEST_P(MockTCPChannelTestAI, ServFailResponse) {
    193   DNSPacket rsp;
    194   rsp.set_response().set_aa()
    195     .add_question(new DNSQuestion("www.google.com", T_A));
    196   rsp.set_rcode(SERVFAIL);
    197   ON_CALL(server_, OnRequest("www.google.com", T_A))
    198     .WillByDefault(SetReply(&server_, &rsp));
    199 
    200   AddrInfoResult result;
    201   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    202   hints.ai_family = AF_INET;
    203   hints.ai_flags = ARES_AI_NOSORT;
    204   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    205   Process();
    206   EXPECT_TRUE(result.done_);
    207   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
    208 }
    209 
    210 TEST_P(MockTCPChannelTestAI, NotImplResponse) {
    211   DNSPacket rsp;
    212   rsp.set_response().set_aa()
    213     .add_question(new DNSQuestion("www.google.com", T_A));
    214   rsp.set_rcode(NOTIMP);
    215   ON_CALL(server_, OnRequest("www.google.com", T_A))
    216     .WillByDefault(SetReply(&server_, &rsp));
    217 
    218   AddrInfoResult result;
    219   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    220   hints.ai_family = AF_INET;
    221   hints.ai_flags = ARES_AI_NOSORT;
    222   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    223   Process();
    224   EXPECT_TRUE(result.done_);
    225   EXPECT_EQ(ARES_ENOTIMP, result.status_);
    226 }
    227 
    228 TEST_P(MockTCPChannelTestAI, RefusedResponse) {
    229   DNSPacket rsp;
    230   rsp.set_response().set_aa()
    231     .add_question(new DNSQuestion("www.google.com", T_A));
    232   rsp.set_rcode(REFUSED);
    233   ON_CALL(server_, OnRequest("www.google.com", T_A))
    234     .WillByDefault(SetReply(&server_, &rsp));
    235 
    236   AddrInfoResult result;
    237   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    238   hints.ai_family = AF_INET;
    239   hints.ai_flags = ARES_AI_NOSORT;
    240   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    241   Process();
    242   EXPECT_TRUE(result.done_);
    243   EXPECT_EQ(ARES_EREFUSED, result.status_);
    244 }
    245 
    246 TEST_P(MockTCPChannelTestAI, YXDomainResponse) {
    247   DNSPacket rsp;
    248   rsp.set_response().set_aa()
    249     .add_question(new DNSQuestion("www.google.com", T_A));
    250   rsp.set_rcode(YXDOMAIN);
    251   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    252     .WillOnce(SetReply(&server_, &rsp));
    253 
    254   AddrInfoResult result;
    255   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    256   hints.ai_family = AF_INET;
    257   hints.ai_flags = ARES_AI_NOSORT;
    258   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    259   Process();
    260   EXPECT_TRUE(result.done_);
    261   EXPECT_EQ(ARES_ENODATA, result.status_);
    262 }
    263 
    264 class MockExtraOptsTestAI
    265     : public MockChannelOptsTest,
    266       public ::testing::WithParamInterface< std::pair<int, bool> > {
    267  public:
    268   MockExtraOptsTestAI()
    269     : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
    270                           FillOptions(&opts_),
    271                           ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
    272   static struct ares_options* FillOptions(struct ares_options * opts) {
    273     memset(opts, 0, sizeof(struct ares_options));
    274     // Set a few options that affect socket communications
    275     opts->socket_send_buffer_size = 514;
    276     opts->socket_receive_buffer_size = 514;
    277     return opts;
    278   }
    279  private:
    280   struct ares_options opts_;
    281 };
    282 
    283 TEST_P(MockExtraOptsTestAI, SimpleQuery) {
    284   ares_set_local_ip4(channel_, 0x7F000001);
    285   byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    286                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
    287   ares_set_local_ip6(channel_, addr6);
    288   ares_set_local_dev(channel_, "dummy");
    289 
    290   DNSPacket rsp;
    291   rsp.set_response().set_aa()
    292     .add_question(new DNSQuestion("www.google.com", T_A))
    293     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
    294   ON_CALL(server_, OnRequest("www.google.com", T_A))
    295     .WillByDefault(SetReply(&server_, &rsp));
    296 
    297   AddrInfoResult result;
    298   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    299   hints.ai_family = AF_INET;
    300   hints.ai_flags = ARES_AI_NOSORT;
    301   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    302   Process();
    303   EXPECT_TRUE(result.done_);
    304   EXPECT_EQ(ARES_SUCCESS, result.status_);
    305   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    306   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
    307 }
    308 
    309 class MockExtraOptsNDotsTestAI
    310     : public MockChannelOptsTest,
    311       public ::testing::WithParamInterface< std::pair<int, bool> > {
    312  public:
    313   MockExtraOptsNDotsTestAI(int ndots)
    314     : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
    315                           FillOptions(&opts_, ndots),
    316                           ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF|ARES_OPT_NDOTS) {}
    317   static struct ares_options* FillOptions(struct ares_options * opts, int ndots) {
    318     memset(opts, 0, sizeof(struct ares_options));
    319     // Set a few options that affect socket communications
    320     opts->socket_send_buffer_size = 514;
    321     opts->socket_receive_buffer_size = 514;
    322     opts->ndots = ndots;
    323     return opts;
    324   }
    325  private:
    326   struct ares_options opts_;
    327 };
    328 
    329 class MockExtraOptsNDots5TestAI : public MockExtraOptsNDotsTestAI {
    330  public:
    331   MockExtraOptsNDots5TestAI() : MockExtraOptsNDotsTestAI(5) {}
    332 };
    333 
    334 TEST_P(MockExtraOptsNDots5TestAI, SimpleQuery) {
    335   ares_set_local_ip4(channel_, 0x7F000001);
    336   byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    337                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
    338   ares_set_local_ip6(channel_, addr6);
    339   ares_set_local_dev(channel_, "dummy");
    340 
    341   DNSPacket rsp;
    342   rsp.set_response().set_aa()
    343     .add_question(new DNSQuestion("dynamodb.us-east-1.amazonaws.com", T_A))
    344     .add_answer(new DNSARR("dynamodb.us-east-1.amazonaws.com", 100, {123, 45, 67, 8}));
    345   ON_CALL(server_, OnRequest("dynamodb.us-east-1.amazonaws.com", T_A))
    346     .WillByDefault(SetReply(&server_, &rsp));
    347 
    348   AddrInfoResult result;
    349   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    350   hints.ai_family = AF_INET;
    351   hints.ai_flags = ARES_AI_NOSORT;
    352   ares_getaddrinfo(channel_, "dynamodb.us-east-1.amazonaws.com.", NULL, &hints, AddrInfoCallback, &result);
    353   Process();
    354   EXPECT_TRUE(result.done_);
    355   EXPECT_EQ(ARES_SUCCESS, result.status_);
    356   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    357   EXPECT_THAT(result.ai_, IncludesV4Address("123.45.67.8"));
    358 }
    359 
    360 class MockExtraOptsNDots0TestAI : public MockExtraOptsNDotsTestAI {
    361  public:
    362   MockExtraOptsNDots0TestAI() : MockExtraOptsNDotsTestAI(0) {}
    363 };
    364 
    365 TEST_P(MockExtraOptsNDots0TestAI, SimpleQuery) {
    366   DNSPacket rsp_ndots0;
    367   rsp_ndots0.set_response().set_aa()
    368     .add_question(new DNSQuestion("ndots0", T_A))
    369     .add_answer(new DNSARR("ndots0", 100, {1, 2, 3, 4}));
    370   ON_CALL(server_, OnRequest("ndots0", T_A))
    371     .WillByDefault(SetReply(&server_, &rsp_ndots0));
    372 
    373   DNSPacket rsp_ndots0_first;
    374   rsp_ndots0_first.set_response().set_aa()
    375     .add_question(new DNSQuestion("ndots0.first.com", T_A))
    376     .add_answer(new DNSARR("ndots0.first.com", 100, {99, 99, 99, 99}));
    377   ON_CALL(server_, OnRequest("ndots0.first.com", T_A))
    378     .WillByDefault(SetReply(&server_, &rsp_ndots0_first));
    379 
    380   DNSPacket rsp_ndots0_second;
    381   rsp_ndots0_second.set_response().set_aa()
    382     .add_question(new DNSQuestion("ndots0.second.org", T_A))
    383     .add_answer(new DNSARR("ndots0.second.org", 100, {98, 98, 98, 98}));
    384   ON_CALL(server_, OnRequest("ndots0.second.org", T_A))
    385     .WillByDefault(SetReply(&server_, &rsp_ndots0_second));
    386 
    387   DNSPacket rsp_ndots0_third;
    388   rsp_ndots0_third.set_response().set_aa()
    389     .add_question(new DNSQuestion("ndots0.third.gov", T_A))
    390     .add_answer(new DNSARR("ndots0.third.gov", 100, {97, 97, 97, 97}));
    391   ON_CALL(server_, OnRequest("ndots0.third.gov", T_A))
    392     .WillByDefault(SetReply(&server_, &rsp_ndots0_third));
    393 
    394   AddrInfoResult result;
    395   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    396   hints.ai_family = AF_INET;
    397   hints.ai_flags = ARES_AI_NOSORT;
    398   ares_getaddrinfo(channel_, "ndots0", NULL, &hints, AddrInfoCallback, &result);
    399   Process();
    400   EXPECT_TRUE(result.done_);
    401   EXPECT_EQ(ARES_SUCCESS, result.status_);
    402   std::stringstream ss;
    403   ss << result.ai_;
    404   EXPECT_EQ("{addr=[1.2.3.4]}", ss.str());
    405 }
    406 
    407 
    408 // Issue #852, systemd-resolved returns SERVFAIL (and possibly REFUSED) on
    409 // single label domains.  We need to work around this by continuing to go
    410 // to the next in the search list. See also
    411 // https://github.com/systemd/systemd/issues/34101
    412 TEST_P(MockExtraOptsNDots0TestAI, SystemdServFail) {
    413   DNSPacket rsp_ndots0;
    414   rsp_ndots0.set_response().set_rcode(SERVFAIL)
    415     .add_question(new DNSQuestion("ndots0", T_A));
    416   EXPECT_CALL(server_, OnRequest("ndots0", T_A))
    417     // Will call until it hits max retries
    418     .WillRepeatedly(SetReply(&server_, &rsp_ndots0));
    419 
    420   DNSPacket rsp_ndots0_first;
    421   rsp_ndots0_first.set_response().set_aa()
    422     .add_question(new DNSQuestion("ndots0.first.com", T_A))
    423     .add_answer(new DNSARR("ndots0.first.com", 100, {1, 2, 3, 4}));
    424   EXPECT_CALL(server_, OnRequest("ndots0.first.com", T_A))
    425     .WillOnce(SetReply(&server_, &rsp_ndots0_first));
    426 
    427   AddrInfoResult result;
    428   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    429   hints.ai_family = AF_INET;
    430   hints.ai_flags = ARES_AI_NOSORT;
    431   ares_getaddrinfo(channel_, "ndots0", NULL, &hints, AddrInfoCallback, &result);
    432   Process();
    433   EXPECT_TRUE(result.done_);
    434   EXPECT_EQ(ARES_SUCCESS, result.status_);
    435   std::stringstream ss;
    436   ss << result.ai_;
    437   EXPECT_EQ("{addr=[1.2.3.4]}", ss.str());
    438 }
    439 TEST_P(MockExtraOptsNDots0TestAI, SystemdServFailSearch) {
    440   DNSPacket rsp_ndots0;
    441   rsp_ndots0.set_response().set_rcode(SERVFAIL)
    442     .add_question(new DNSQuestion("ndots0", T_A));
    443   EXPECT_CALL(server_, OnRequest("ndots0", T_A))
    444     // Will call until it hits max retries
    445     .WillRepeatedly(SetReply(&server_, &rsp_ndots0));
    446 
    447   DNSPacket rsp_ndots0_first;
    448   rsp_ndots0_first.set_response().set_aa()
    449     .add_question(new DNSQuestion("ndots0.first.com", T_A))
    450     .add_answer(new DNSARR("ndots0.first.com", 100, {1, 2, 3, 4}));
    451   EXPECT_CALL(server_, OnRequest("ndots0.first.com", T_A))
    452     .WillOnce(SetReply(&server_, &rsp_ndots0_first));
    453 
    454   QueryResult result;
    455   ares_dns_record_t *dnsrec = NULL;
    456   ares_dns_record_create(&dnsrec, 0, ARES_FLAG_RD, ARES_OPCODE_QUERY, ARES_RCODE_NOERROR);
    457   ares_dns_record_query_add(dnsrec, "ndots0", ARES_REC_TYPE_A, ARES_CLASS_IN);
    458   ares_search_dnsrec(channel_, dnsrec, QueryCallback, &result);
    459   ares_dns_record_destroy(dnsrec);
    460   Process();
    461   EXPECT_TRUE(result.done_);
    462   EXPECT_EQ(ARES_SUCCESS, result.status_);
    463 
    464   // QueryResult doesn't provide an easy way to retrieve the address, just ignore,
    465   // success is probably good enough
    466 }
    467 TEST_P(MockExtraOptsNDots0TestAI, SystemdRefused) {
    468   DNSPacket rsp_ndots0;
    469   rsp_ndots0.set_response().set_rcode(REFUSED)
    470     .add_question(new DNSQuestion("ndots0", T_A));
    471   EXPECT_CALL(server_, OnRequest("ndots0", T_A))
    472     // Will call until it hits max retries
    473     .WillRepeatedly(SetReply(&server_, &rsp_ndots0));
    474 
    475   DNSPacket rsp_ndots0_first;
    476   rsp_ndots0_first.set_response().set_aa()
    477     .add_question(new DNSQuestion("ndots0.first.com", T_A))
    478     .add_answer(new DNSARR("ndots0.first.com", 100, {1, 2, 3, 4}));
    479   EXPECT_CALL(server_, OnRequest("ndots0.first.com", T_A))
    480     .WillOnce(SetReply(&server_, &rsp_ndots0_first));
    481 
    482   AddrInfoResult result;
    483   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    484   hints.ai_family = AF_INET;
    485   hints.ai_flags = ARES_AI_NOSORT;
    486   ares_getaddrinfo(channel_, "ndots0", NULL, &hints, AddrInfoCallback, &result);
    487   Process();
    488   EXPECT_TRUE(result.done_);
    489   EXPECT_EQ(ARES_SUCCESS, result.status_);
    490   std::stringstream ss;
    491   ss << result.ai_;
    492   EXPECT_EQ("{addr=[1.2.3.4]}", ss.str());
    493 }
    494 TEST_P(MockExtraOptsNDots0TestAI, SystemdRefusedSearch) {
    495   DNSPacket rsp_ndots0;
    496   rsp_ndots0.set_response().set_rcode(REFUSED)
    497     .add_question(new DNSQuestion("ndots0", T_A));
    498   EXPECT_CALL(server_, OnRequest("ndots0", T_A))
    499     // Will call until it hits max retries
    500     .WillRepeatedly(SetReply(&server_, &rsp_ndots0));
    501 
    502   DNSPacket rsp_ndots0_first;
    503   rsp_ndots0_first.set_response().set_aa()
    504     .add_question(new DNSQuestion("ndots0.first.com", T_A))
    505     .add_answer(new DNSARR("ndots0.first.com", 100, {1, 2, 3, 4}));
    506   EXPECT_CALL(server_, OnRequest("ndots0.first.com", T_A))
    507     .WillOnce(SetReply(&server_, &rsp_ndots0_first));
    508 
    509   QueryResult result;
    510   ares_dns_record_t *dnsrec = NULL;
    511   ares_dns_record_create(&dnsrec, 0, ARES_FLAG_RD, ARES_OPCODE_QUERY, ARES_RCODE_NOERROR);
    512   ares_dns_record_query_add(dnsrec, "ndots0", ARES_REC_TYPE_A, ARES_CLASS_IN);
    513   ares_search_dnsrec(channel_, dnsrec, QueryCallback, &result);
    514   ares_dns_record_destroy(dnsrec);
    515   Process();
    516   EXPECT_TRUE(result.done_);
    517   EXPECT_EQ(ARES_SUCCESS, result.status_);
    518 
    519   // QueryResult doesn't provide an easy way to retrieve the address, just ignore,
    520   // success is probably good enough
    521 }
    522 
    523 
    524 class MockFlagsChannelOptsTestAI
    525     : public MockChannelOptsTest,
    526       public ::testing::WithParamInterface< std::pair<int, bool> > {
    527  public:
    528   MockFlagsChannelOptsTestAI(int flags)
    529     : MockChannelOptsTest(1, GetParam().first, GetParam().second, false,
    530                           FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
    531   static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
    532     memset(opts, 0, sizeof(struct ares_options));
    533     opts->flags = flags;
    534     return opts;
    535   }
    536  private:
    537   struct ares_options opts_;
    538 };
    539 
    540 class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI {
    541  public:
    542   MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {}
    543 };
    544 
    545 TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) {
    546   DNSPacket rsp;
    547   rsp.set_response().set_aa()
    548     .add_question(new DNSQuestion("www.google.com", T_A));
    549   rsp.set_rcode(SERVFAIL);
    550   ON_CALL(server_, OnRequest("www.google.com", T_A))
    551     .WillByDefault(SetReply(&server_, &rsp));
    552 
    553   AddrInfoResult result;
    554   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    555   hints.ai_family = AF_INET;
    556   hints.ai_flags = ARES_AI_NOSORT;
    557   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    558   Process();
    559   EXPECT_TRUE(result.done_);
    560   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
    561 }
    562 
    563 TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) {
    564   DNSPacket rsp;
    565   rsp.set_response().set_aa()
    566     .add_question(new DNSQuestion("www.google.com", T_A));
    567   rsp.set_rcode(NOTIMP);
    568   ON_CALL(server_, OnRequest("www.google.com", T_A))
    569     .WillByDefault(SetReply(&server_, &rsp));
    570 
    571   AddrInfoResult result;
    572   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    573   hints.ai_family = AF_INET;
    574   hints.ai_flags = ARES_AI_NOSORT;
    575   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    576   Process();
    577   EXPECT_TRUE(result.done_);
    578   EXPECT_EQ(ARES_ENOTIMP, result.status_);
    579 }
    580 
    581 TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) {
    582   DNSPacket rsp;
    583   rsp.set_response().set_aa()
    584     .add_question(new DNSQuestion("www.google.com", T_A));
    585   rsp.set_rcode(REFUSED);
    586   ON_CALL(server_, OnRequest("www.google.com", T_A))
    587     .WillByDefault(SetReply(&server_, &rsp));
    588 
    589   AddrInfoResult result;
    590   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    591   hints.ai_family = AF_INET;
    592   hints.ai_flags = ARES_AI_NOSORT;
    593   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    594   Process();
    595   EXPECT_TRUE(result.done_);
    596   EXPECT_EQ(ARES_EREFUSED, result.status_);
    597 }
    598 
    599 TEST_P(MockChannelTestAI, FamilyV6) {
    600   DNSPacket rsp6;
    601   rsp6.set_response().set_aa()
    602     .add_question(new DNSQuestion("example.com", T_AAAA))
    603     .add_answer(new DNSAaaaRR("example.com", 100,
    604                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    605                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
    606   ON_CALL(server_, OnRequest("example.com", T_AAAA))
    607     .WillByDefault(SetReply(&server_, &rsp6));
    608   AddrInfoResult result;
    609   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    610   hints.ai_family = AF_INET6;
    611   hints.ai_flags = ARES_AI_NOSORT;
    612   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
    613                    AddrInfoCallback, &result);
    614   Process();
    615   EXPECT_TRUE(result.done_);
    616   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    617   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
    618 }
    619 
    620 // Test case for Issue #662
    621 TEST_P(MockChannelTestAI, PartialQueryCancel) {
    622   std::vector<byte> nothing;
    623   DNSPacket reply;
    624   reply.set_response().set_aa()
    625     .add_question(new DNSQuestion("example.com", T_A))
    626     .add_answer(new DNSARR("example.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
    627 
    628   ON_CALL(server_, OnRequest("example.com", T_A))
    629     .WillByDefault(SetReply(&server_, &reply));
    630 
    631   ON_CALL(server_, OnRequest("example.com", T_AAAA))
    632     .WillByDefault(SetReplyData(&server_, nothing));
    633 
    634 
    635   AddrInfoResult result;
    636   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    637   hints.ai_family = AF_UNSPEC;
    638   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
    639                    AddrInfoCallback, &result);
    640 
    641   // After 100ms, issues ares_cancel(), this should be enough time for the A
    642   // record reply, but before the timeout on the AAAA record.
    643   Process(100);
    644   EXPECT_TRUE(result.done_);
    645   EXPECT_EQ(ARES_ECANCELLED, result.status_);
    646 }
    647 
    648 TEST_P(MockChannelTestAI, FamilyV4) {
    649   DNSPacket rsp4;
    650   rsp4.set_response().set_aa()
    651     .add_question(new DNSQuestion("example.com", T_A))
    652     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
    653   ON_CALL(server_, OnRequest("example.com", T_A))
    654     .WillByDefault(SetReply(&server_, &rsp4));
    655   AddrInfoResult result = {};
    656   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    657   hints.ai_family = AF_INET;
    658   hints.ai_flags = ARES_AI_NOSORT;
    659   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
    660                    AddrInfoCallback, &result);
    661   Process();
    662   EXPECT_TRUE(result.done_);
    663   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    664   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
    665 }
    666 
    667 TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) {
    668   DNSPacket rsp4;
    669   rsp4.set_response().set_aa()
    670     .add_question(new DNSQuestion("example.com", T_A))
    671     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}))
    672     .add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0}));
    673   ON_CALL(server_, OnRequest("example.com", T_A))
    674     .WillByDefault(SetReply(&server_, &rsp4));
    675   AddrInfoResult result = {};
    676   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    677   hints.ai_family = AF_INET;
    678   hints.ai_flags = ARES_AI_NOSORT;
    679   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
    680                    AddrInfoCallback, &result);
    681   Process();
    682   EXPECT_TRUE(result.done_);
    683   std::stringstream ss;
    684   ss << result.ai_;
    685   EXPECT_EQ("{addr=[2.3.4.5], addr=[7.8.9.0]}", ss.str());
    686 }
    687 
    688 TEST_P(MockChannelTestAI, FamilyUnspecified) {
    689   DNSPacket rsp6;
    690   rsp6.set_response().set_aa()
    691     .add_question(new DNSQuestion("example.com", T_AAAA))
    692     .add_answer(new DNSAaaaRR("example.com", 100,
    693                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    694                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
    695   ON_CALL(server_, OnRequest("example.com", T_AAAA))
    696     .WillByDefault(SetReply(&server_, &rsp6));
    697   DNSPacket rsp4;
    698   rsp4.set_response().set_aa()
    699     .add_question(new DNSQuestion("example.com", T_A))
    700     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
    701   ON_CALL(server_, OnRequest("example.com", T_A))
    702     .WillByDefault(SetReply(&server_, &rsp4));
    703   AddrInfoResult result;
    704   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    705   hints.ai_family = AF_UNSPEC;
    706   hints.ai_flags = ARES_AI_NOSORT;
    707   ares_getaddrinfo(channel_, "example.com.", NULL, &hints,
    708                    AddrInfoCallback, &result);
    709   Process();
    710   EXPECT_TRUE(result.done_);
    711   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
    712   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
    713   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
    714 }
    715 
    716 
    717 TEST_P(MockChannelTestAI, TriggerResendThenConnFailSERVFAIL) {
    718   // Set up the server response. The server always returns SERVFAIL.
    719   DNSPacket badrsp4;
    720   badrsp4.set_response().set_aa().set_rcode(SERVFAIL)
    721     .add_question(new DNSQuestion("www.google.com", T_A));
    722   DNSPacket goodrsp4;
    723   goodrsp4.set_response().set_aa()
    724     .add_question(new DNSQuestion("www.google.com", T_A))
    725     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
    726 
    727   DNSPacket goodrsp6;
    728   goodrsp6.set_response().set_aa()
    729     .add_question(new DNSQuestion("www.google.com", T_AAAA))
    730     .add_answer(new DNSAaaaRR("www.google.com", 100,
    731                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    732                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
    733 
    734   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    735     .WillOnce(SetReplyAndFailSend(&server_, &badrsp4))
    736     .WillOnce(SetReply(&server_, &goodrsp4));
    737 
    738   EXPECT_CALL(server_, OnRequest("www.google.com", T_AAAA))
    739     .WillRepeatedly(SetReply(&server_, &goodrsp6));
    740 
    741   ares_socket_functions sock_funcs;
    742   memset(&sock_funcs, 0, sizeof(sock_funcs));
    743 
    744   sock_funcs.asendv = ares_sendv_fail;
    745 
    746   ares_set_socket_functions(channel_, &sock_funcs, NULL);
    747 
    748   AddrInfoResult result;
    749   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    750   hints.ai_family = AF_UNSPEC;
    751   hints.ai_flags = ARES_AI_NOSORT;
    752   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints,
    753                    AddrInfoCallback, &result);
    754 
    755   Process();
    756   EXPECT_TRUE(result.done_);
    757   EXPECT_TRUE(result.done_);
    758   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
    759   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
    760   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
    761 }
    762 
    763 TEST_P(MockUDPChannelTestAI, TriggerResendThenConnFailEDNS) {
    764   // Set up the server response to simulate an EDNS failure
    765  DNSPacket badrsp4;
    766   badrsp4.set_response().set_aa().set_rcode(FORMERR)
    767     .add_question(new DNSQuestion("www.google.com", T_A));
    768   DNSPacket goodrsp4;
    769   goodrsp4.set_response().set_aa()
    770     .add_question(new DNSQuestion("www.google.com", T_A))
    771     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
    772   DNSPacket goodrsp6;
    773   goodrsp6.set_response().set_aa()
    774     .add_question(new DNSQuestion("www.google.com", T_AAAA))
    775     .add_answer(new DNSAaaaRR("www.google.com", 100,
    776                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    777                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
    778 
    779   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    780     .WillOnce(SetReplyAndFailSend(&server_, &badrsp4))
    781     .WillOnce(SetReply(&server_, &goodrsp4));
    782 
    783   EXPECT_CALL(server_, OnRequest("www.google.com", T_AAAA))
    784     .WillRepeatedly(SetReply(&server_, &goodrsp6));
    785 
    786   ares_socket_functions sock_funcs;
    787   memset(&sock_funcs, 0, sizeof(sock_funcs));
    788 
    789   sock_funcs.asendv = ares_sendv_fail;
    790 
    791   ares_set_socket_functions(channel_, &sock_funcs, NULL);
    792 
    793   AddrInfoResult result;
    794   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    795   hints.ai_family = AF_UNSPEC;
    796   hints.ai_flags = ARES_AI_NOSORT;
    797   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints,
    798                    AddrInfoCallback, &result);
    799 
    800   Process();
    801   EXPECT_TRUE(result.done_);
    802   EXPECT_TRUE(result.done_);
    803   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
    804   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
    805   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
    806 }
    807 
    808 
    809 
    810 class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI {
    811  public:
    812   MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {}
    813 };
    814 
    815 TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) {
    816   DNSPacket rspfail;
    817   rspfail.set_response().set_aa().set_rcode(FORMERR)
    818     .add_question(new DNSQuestion("www.google.com", T_A));
    819   DNSPacket rspok;
    820   rspok.set_response()
    821     .add_question(new DNSQuestion("www.google.com", T_A))
    822     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
    823   EXPECT_CALL(server_, OnRequest("www.google.com", T_A))
    824     .WillOnce(SetReply(&server_, &rspfail))
    825     .WillOnce(SetReply(&server_, &rspok));
    826 
    827   AddrInfoResult result;
    828   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    829   hints.ai_family = AF_INET;
    830   hints.ai_flags = ARES_AI_NOSORT;
    831   ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result);
    832   Process();
    833   EXPECT_TRUE(result.done_);
    834   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    835   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
    836 }
    837 
    838 TEST_P(MockChannelTestAI, SearchDomains) {
    839   DNSPacket nofirst;
    840   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
    841     .add_question(new DNSQuestion("www.first.com", T_A));
    842   ON_CALL(server_, OnRequest("www.first.com", T_A))
    843     .WillByDefault(SetReply(&server_, &nofirst));
    844   DNSPacket nosecond;
    845   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
    846     .add_question(new DNSQuestion("www.second.org", T_A));
    847   ON_CALL(server_, OnRequest("www.second.org", T_A))
    848     .WillByDefault(SetReply(&server_, &nosecond));
    849   DNSPacket yesthird;
    850   yesthird.set_response().set_aa()
    851     .add_question(new DNSQuestion("www.third.gov", T_A))
    852     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
    853   ON_CALL(server_, OnRequest("www.third.gov", T_A))
    854     .WillByDefault(SetReply(&server_, &yesthird));
    855 
    856   AddrInfoResult result;
    857   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    858   hints.ai_family = AF_INET;
    859   hints.ai_flags = ARES_AI_NOSORT;
    860   ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
    861   Process();
    862   EXPECT_TRUE(result.done_);
    863   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    864   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
    865 }
    866 
    867 TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) {
    868   DNSPacket nofirst;
    869   nofirst.set_response().set_aa().set_rcode(NXDOMAIN)
    870     .add_question(new DNSQuestion("www.first.com", T_AAAA));
    871   ON_CALL(server_, OnRequest("www.first.com", T_AAAA))
    872     .WillByDefault(SetReply(&server_, &nofirst));
    873   DNSPacket nofirst4;
    874   nofirst4.set_response().set_aa().set_rcode(NXDOMAIN)
    875     .add_question(new DNSQuestion("www.first.com", T_A));
    876   ON_CALL(server_, OnRequest("www.first.com", T_A))
    877     .WillByDefault(SetReply(&server_, &nofirst4));
    878 
    879   DNSPacket nosecond;
    880   nosecond.set_response().set_aa().set_rcode(NXDOMAIN)
    881     .add_question(new DNSQuestion("www.second.org", T_AAAA));
    882   ON_CALL(server_, OnRequest("www.second.org", T_AAAA))
    883     .WillByDefault(SetReply(&server_, &nosecond));
    884   DNSPacket yessecond4;
    885   yessecond4.set_response().set_aa()
    886     .add_question(new DNSQuestion("www.second.org", T_A))
    887     .add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5}));
    888   ON_CALL(server_, OnRequest("www.second.org", T_A))
    889     .WillByDefault(SetReply(&server_, &yessecond4));
    890 
    891   DNSPacket failthird;
    892   failthird.set_response().set_aa().set_rcode(SERVFAIL)
    893     .add_question(new DNSQuestion("www.third.gov", T_AAAA));
    894   ON_CALL(server_, OnRequest("www.third.gov", T_AAAA))
    895     .WillByDefault(SetReply(&server_, &failthird));
    896   DNSPacket failthird4;
    897   failthird4.set_response().set_aa().set_rcode(SERVFAIL)
    898     .add_question(new DNSQuestion("www.third.gov", T_A));
    899   ON_CALL(server_, OnRequest("www.third.gov", T_A))
    900     .WillByDefault(SetReply(&server_, &failthird4));
    901 
    902   AddrInfoResult result;
    903   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    904   hints.ai_family = AF_UNSPEC;
    905   hints.ai_flags = ARES_AI_NOSORT;
    906   ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result);
    907   Process();
    908   EXPECT_TRUE(result.done_);
    909   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    910   EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
    911 }
    912 
    913 class MockMultiServerChannelTestAI
    914   : public MockChannelOptsTest,
    915     public ::testing::WithParamInterface< std::pair<int, bool> > {
    916  public:
    917   MockMultiServerChannelTestAI(ares_options *opts, int optmask)
    918     : MockChannelOptsTest(3, GetParam().first, GetParam().second, false, opts, optmask) {}
    919   void CheckExample() {
    920     AddrInfoResult result;
    921     struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    922     hints.ai_family = AF_INET;
    923     hints.ai_flags = ARES_AI_NOSORT;
    924     ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
    925     Process();
    926     EXPECT_TRUE(result.done_);
    927     EXPECT_EQ(result.status_, ARES_SUCCESS);
    928     EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    929     EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5"));
    930   }
    931 };
    932 
    933 class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI {
    934  public:
    935   NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(nullptr, ARES_OPT_NOROTATE) {}
    936 };
    937 
    938 /* We want to terminate retries of other address classes on getaddrinfo if one
    939  * address class is returned already to return replies faster.
    940  * UPDATE: actually we want to do this only if the address class we received
    941  *         was ipv4.  We've seen issues if ipv6 was returned but the host was
    942  *         really only capable of ipv4.
    943  */
    944 TEST_P(NoRotateMultiMockTestAI, v4Worksv6Timesout) {
    945   std::vector<byte> nothing;
    946 
    947   DNSPacket rsp4;
    948   rsp4.set_response().set_aa()
    949     .add_question(new DNSQuestion("www.example.com", T_A))
    950     .add_answer(new DNSARR("www.example.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
    951 
    952   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
    953     .WillOnce(SetReply(servers_[0].get(), &rsp4));
    954   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_AAAA))
    955     .WillOnce(SetReplyData(servers_[0].get(), nothing));
    956 
    957   AddrInfoResult result;
    958   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    959   hints.ai_family = AF_UNSPEC;
    960   hints.ai_flags = ARES_AI_NOSORT;
    961   ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
    962   Process();
    963   EXPECT_TRUE(result.done_);
    964   EXPECT_EQ(result.status_, ARES_SUCCESS);
    965   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
    966   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
    967 }
    968 
    969 TEST_P(NoRotateMultiMockTestAI, v6Worksv4TimesoutFirst) {
    970   std::vector<byte> nothing;
    971 
    972   DNSPacket rsp4;
    973   rsp4.set_response().set_aa()
    974     .add_question(new DNSQuestion("www.example.com", T_A))
    975     .add_answer(new DNSARR("www.example.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
    976 
    977   DNSPacket rsp6;
    978   rsp6.set_response().set_aa()
    979     .add_question(new DNSQuestion("www.example.com", T_AAAA))
    980     .add_answer(new DNSAaaaRR("www.example.com", 100,
    981                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    982                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
    983 
    984   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
    985     .WillOnce(SetReplyData(servers_[0].get(), nothing));
    986   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_AAAA))
    987     .WillOnce(SetReply(servers_[0].get(), &rsp6));
    988   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
    989     .WillOnce(SetReply(servers_[1].get(), &rsp4));
    990 
    991   AddrInfoResult result;
    992   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
    993   hints.ai_family = AF_UNSPEC;
    994   hints.ai_flags = ARES_AI_NOSORT;
    995   ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result);
    996   Process();
    997   EXPECT_TRUE(result.done_);
    998   EXPECT_EQ(result.status_, ARES_SUCCESS);
    999   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
   1000   EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4"));
   1001   EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303"));
   1002 
   1003 }
   1004 
   1005 TEST_P(NoRotateMultiMockTestAI, ThirdServer) {
   1006   struct ares_options opts;
   1007   int optmask = 0;
   1008   memset(&opts, 0, sizeof(opts));
   1009   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
   1010   EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
   1011   ares_destroy_options(&opts);
   1012 
   1013   DNSPacket servfailrsp;
   1014   servfailrsp.set_response().set_aa().set_rcode(SERVFAIL)
   1015     .add_question(new DNSQuestion("www.example.com", T_A));
   1016   DNSPacket notimplrsp;
   1017   notimplrsp.set_response().set_aa().set_rcode(NOTIMP)
   1018     .add_question(new DNSQuestion("www.example.com", T_A));
   1019   DNSPacket okrsp;
   1020   okrsp.set_response().set_aa()
   1021     .add_question(new DNSQuestion("www.example.com", T_A))
   1022     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
   1023 
   1024    EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1025     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
   1026   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1027     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
   1028   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1029     .WillOnce(SetReply(servers_[2].get(), &okrsp));
   1030   CheckExample();
   1031 
   1032   // Second time around, still starts from server [2], as [0] and [1] both
   1033   // recorded failures
   1034   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1035     .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
   1036   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1037     .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
   1038   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1039     .WillOnce(SetReply(servers_[1].get(), &okrsp));
   1040   CheckExample();
   1041 
   1042   // Third time around, server order is [1] (f0), [2] (f1), [0] (f2), which
   1043   // means [1] will get called twice in a row as after the first call
   1044   // order will be  [1] (f1), [2] (f1), [0] (f2) since sort order is
   1045   // (failure count, index)
   1046   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", T_A))
   1047     .WillOnce(SetReply(servers_[1].get(), &servfailrsp))
   1048     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
   1049   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A))
   1050     .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
   1051   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", T_A))
   1052     .WillOnce(SetReply(servers_[0].get(), &okrsp));
   1053   CheckExample();
   1054 }
   1055 
   1056 TEST_P(MockChannelTestAI, FamilyV4ServiceName) {
   1057   DNSPacket rsp4;
   1058   rsp4.set_response().set_aa()
   1059     .add_question(new DNSQuestion("example.com", T_A))
   1060     .add_answer(new DNSARR("example.com", 100, {1, 1, 1, 1}))
   1061     .add_answer(new DNSARR("example.com", 100, {2, 2, 2, 2}));
   1062   ON_CALL(server_, OnRequest("example.com", T_A))
   1063     .WillByDefault(SetReply(&server_, &rsp4));
   1064   AddrInfoResult result = {};
   1065   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1066   hints.ai_family = AF_INET;
   1067   hints.ai_flags = ARES_AI_NOSORT;
   1068   ares_getaddrinfo(channel_, "example.com", "http", &hints, AddrInfoCallback, &result);
   1069   Process();
   1070   EXPECT_TRUE(result.done_);
   1071   std::stringstream ss;
   1072   ss << result.ai_;
   1073   EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str());
   1074 }
   1075 
   1076 #ifdef HAVE_CONTAINER
   1077 
   1078 class ContainedMockChannelAISysConfig
   1079     : public MockChannelOptsTest,
   1080       public ::testing::WithParamInterface<std::pair<int, bool>> {
   1081  public:
   1082   ContainedMockChannelAISysConfig()
   1083     : MockChannelOptsTest(1, GetParam().first, GetParam().second, true, nullptr, 0) {}
   1084 };
   1085 
   1086 static NameContentList files_no_ndots = {
   1087   {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
   1088                        "search example.com example.org\n"
   1089                        "options edns0 trust-ad\n"}, // ndots:1 is default
   1090   {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
   1091   {"/etc/nsswitch.conf", "hosts: files dns\n"}};
   1092 
   1093 /* These tests should still work even with /etc/hosts not having any localhost
   1094  * entries */
   1095 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, NoHostsLocalHostv4,
   1096                  "myhostname", "mydomainname.org", files_no_ndots) {
   1097   AddrInfoResult result = {};
   1098   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1099   hints.ai_family = AF_INET;
   1100   hints.ai_flags = ARES_AI_NOSORT;
   1101   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1102   Process();
   1103   EXPECT_TRUE(result.done_);
   1104   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1105   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
   1106   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
   1107   return HasFailure();
   1108 }
   1109 
   1110 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, NoHostsLocalHostv6,
   1111                  "myhostname", "mydomainname.org", files_no_ndots) {
   1112   AddrInfoResult result = {};
   1113   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1114   hints.ai_family = AF_INET6;
   1115   hints.ai_flags = ARES_AI_NOSORT;
   1116   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1117   Process();
   1118   EXPECT_TRUE(result.done_);
   1119   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1120   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
   1121   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
   1122   return HasFailure();
   1123 }
   1124 
   1125 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, NoHostsLocalHostUnspec,
   1126                  "myhostname", "mydomainname.org", files_no_ndots) {
   1127   AddrInfoResult result = {};
   1128   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1129   hints.ai_family = AF_UNSPEC;
   1130   hints.ai_flags = ARES_AI_NOSORT;
   1131   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1132   Process();
   1133   EXPECT_TRUE(result.done_);
   1134   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1135   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
   1136   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
   1137   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
   1138   return HasFailure();
   1139 }
   1140 
   1141 
   1142 /* Issue #946 says if a v4 localhost entry exists, but not a v6 entry, v6
   1143  * isn't output correctly. */
   1144 static NameContentList files_localhost_v4localhostonly = {
   1145   {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
   1146                        "search example.com example.org\n"
   1147                        "options edns0 trust-ad\n"}, // ndots:1 is default
   1148   {"/etc/hosts", "127.0.0.1 localhost\n"},
   1149   {"/etc/nsswitch.conf", "hosts: files dns\n"}};
   1150 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v4OnlyLocalHostv4,
   1151                  "myhostname", "mydomainname.org", files_localhost_v4localhostonly) {
   1152   AddrInfoResult result = {};
   1153   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1154   hints.ai_family = AF_INET;
   1155   hints.ai_flags = ARES_AI_NOSORT;
   1156   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1157   Process();
   1158   EXPECT_TRUE(result.done_);
   1159   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1160   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
   1161   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
   1162   return HasFailure();
   1163 }
   1164 
   1165 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v4OnlyLocalHostv6,
   1166                  "myhostname", "mydomainname.org", files_localhost_v4localhostonly) {
   1167   AddrInfoResult result = {};
   1168   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1169   hints.ai_family = AF_INET6;
   1170   hints.ai_flags = ARES_AI_NOSORT;
   1171   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1172   Process();
   1173   EXPECT_TRUE(result.done_);
   1174   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1175   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
   1176   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
   1177   return HasFailure();
   1178 }
   1179 
   1180 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v4OnlyLocalHostUnspec,
   1181                  "myhostname", "mydomainname.org", files_localhost_v4localhostonly) {
   1182   AddrInfoResult result = {};
   1183   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1184   hints.ai_family = AF_UNSPEC;
   1185   hints.ai_flags = ARES_AI_NOSORT;
   1186   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1187   Process();
   1188   EXPECT_TRUE(result.done_);
   1189   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1190   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
   1191   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
   1192   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
   1193   return HasFailure();
   1194 }
   1195 
   1196 
   1197 static NameContentList files_localhost_v6localhostonly = {
   1198   {"/etc/resolv.conf", "nameserver 1.2.3.4\n" // Will be replaced
   1199                        "search example.com example.org\n"
   1200                        "options edns0 trust-ad\n"}, // ndots:1 is default
   1201   {"/etc/hosts", "::1 localhost\n"},
   1202   {"/etc/nsswitch.conf", "hosts: files dns\n"}};
   1203 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v6OnlyLocalHostv4,
   1204                  "myhostname", "mydomainname.org", files_localhost_v6localhostonly) {
   1205   AddrInfoResult result = {};
   1206   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1207   hints.ai_family = AF_INET;
   1208   hints.ai_flags = ARES_AI_NOSORT;
   1209   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1210   Process();
   1211   EXPECT_TRUE(result.done_);
   1212   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1213   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
   1214   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
   1215   return HasFailure();
   1216 }
   1217 
   1218 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v6OnlyLocalHostv6,
   1219                  "myhostname", "mydomainname.org", files_localhost_v6localhostonly) {
   1220   AddrInfoResult result = {};
   1221   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1222   hints.ai_family = AF_INET6;
   1223   hints.ai_flags = ARES_AI_NOSORT;
   1224   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1225   Process();
   1226   EXPECT_TRUE(result.done_);
   1227   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1228   EXPECT_THAT(result.ai_, IncludesNumAddresses(1));
   1229   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
   1230   return HasFailure();
   1231 }
   1232 
   1233 CONTAINED_TEST_P(ContainedMockChannelAISysConfig, v6OnlyLocalHostUnspec,
   1234                  "myhostname", "mydomainname.org", files_localhost_v6localhostonly) {
   1235   AddrInfoResult result = {};
   1236   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
   1237   hints.ai_family = AF_UNSPEC;
   1238   hints.ai_flags = ARES_AI_NOSORT;
   1239   ares_getaddrinfo(channel_, "localhost", NULL, &hints, AddrInfoCallback, &result);
   1240   Process();
   1241   EXPECT_TRUE(result.done_);
   1242   EXPECT_EQ(result.status_, ARES_SUCCESS);
   1243   EXPECT_THAT(result.ai_, IncludesNumAddresses(2));
   1244   EXPECT_THAT(result.ai_, IncludesV4Address("127.0.0.1"));
   1245   EXPECT_THAT(result.ai_, IncludesV6Address("0000:0000:0000:0000:0000:0000:0000:0001"));
   1246   return HasFailure();
   1247 }
   1248 
   1249 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, ContainedMockChannelAISysConfig, ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
   1250 #endif
   1251 
   1252 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockChannelTestAI,
   1253                        ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
   1254 
   1255 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockUDPChannelTestAI,
   1256                         ::testing::ValuesIn(ares::test::families), PrintFamily);
   1257 
   1258 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockTCPChannelTestAI,
   1259                         ::testing::ValuesIn(ares::test::families), PrintFamily);
   1260 
   1261 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockExtraOptsTestAI,
   1262 			::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
   1263 
   1264 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockExtraOptsNDots5TestAI,
   1265       ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
   1266 
   1267 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockExtraOptsNDots0TestAI,
   1268       ::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
   1269 
   1270 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI,
   1271 			::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
   1272 
   1273 INSTANTIATE_TEST_SUITE_P(AddressFamiliesAI, MockEDNSChannelTestAI,
   1274 			::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
   1275 
   1276 INSTANTIATE_TEST_SUITE_P(TransportModesAI, NoRotateMultiMockTestAI,
   1277 			::testing::ValuesIn(ares::test::families_modes), PrintFamilyMode);
   1278 
   1279 }  // namespace test
   1280 }  // namespace ares