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(), ¬implrsp)); 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(), ¬implrsp)); 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(), ¬implrsp)); 1049 EXPECT_CALL(*servers_[2], OnRequest("www.example.com", T_A)) 1050 .WillOnce(SetReply(servers_[2].get(), ¬implrsp)); 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