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